From 5ef42859b1b08e1a81c6baf5bfc8cbc96cd3ec8d Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Thu, 17 Jul 2025 23:05:03 -0700 Subject: [PATCH] Begin refactoring to allow Accounts to be encrypted en masse while retaining their index for their Wallet. --- src/lib/account.ts | 141 +++++++++++++++++------------- src/lib/bip39-mnemonic.ts | 13 ++- src/lib/block.ts | 2 +- src/lib/tools.ts | 9 +- src/lib/wallets/bip44-wallet.ts | 8 +- src/lib/wallets/blake2b-wallet.ts | 6 +- src/lib/wallets/wallet.ts | 28 +++--- src/lib/workers/nano-nacl.ts | 6 +- src/lib/workers/queue.ts | 7 -- src/lib/workers/safe.ts | 4 +- src/types.d.ts | 28 +++--- 11 files changed, 137 insertions(+), 115 deletions(-) diff --git a/src/lib/account.ts b/src/lib/account.ts index f7cf110..3044ea1 100644 --- a/src/lib/account.ts +++ b/src/lib/account.ts @@ -6,7 +6,7 @@ import { ChangeBlock, ReceiveBlock, SendBlock } from './block' import { ACCOUNT_KEY_BYTE_LENGTH, ACCOUNT_KEY_HEX_LENGTH, ALPHABET, PREFIX, PREFIX_LEGACY } from './constants' import { base32, bytes, hex, utf8 } from './convert' import { Rpc } from './rpc' -import { Data } from '#types' +import { Data, Key, KeyPair } from '#types' import { NanoNaClWorker, SafeWorker } from '#workers' /** @@ -19,6 +19,7 @@ export class Account { static #isInternal: boolean = false #address: string + #index?: number #publicKey: Uint8Array #balance?: bigint @@ -28,6 +29,7 @@ export class Account { #weight?: bigint get address () { return `${PREFIX}${this.#address}` } + get index () { return this.#index } get publicKey () { return bytes.toHex(this.#publicKey) } get balance () { return this.#balance } @@ -50,7 +52,7 @@ export class Account { } set weight (v) { this.#weight = v ? BigInt(v) : undefined } - private constructor (address: string, publicKey: Uint8Array) { + private constructor (address: string, publicKey: Uint8Array, index?: number) { if (!Account.#isInternal) { throw new Error(`Account cannot be instantiated directly. Use factory methods instead.`) } @@ -58,6 +60,7 @@ export class Account { .replace(PREFIX, '') .replace(PREFIX_LEGACY, '') this.#publicKey = publicKey + this.#index = index } /** @@ -128,44 +131,24 @@ export class Account { * and stored in IndexedDB. The corresponding public key will automatically be * derived and saved. * - * @param {string} privateKey - Private key of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private key + * @param {KeyPair} keypair - Index and keys of the account + * @param {Key} password - Used to encrypt the private key * @returns {Account} A new Account object */ - static async import (privateKey: string, password: string | Uint8Array): Promise - /** - * Instantiates an Account object from its private key which is then encrypted - * and stored in IndexedDB. The corresponding public key will automatically be - * derived and saved. - * - * @param {Uint8Array} privateKey - Private key of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private key - * @returns {Account} A new Account object - */ - static async import (privateKey: Uint8Array, password: string | Uint8Array): Promise - /** - * Instantiates Account objects from their private keys which are then - * encrypted and stored in IndexedDB. The corresponding public keys will - * automatically be derived and saved. - * - * @param {string[]} privateKeys - Private keys of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private keys - * @returns {Account[]} The instantiated Account objects - */ - static async import (privateKeys: string[], password: string | Uint8Array): Promise + static async import (keypair: KeyPair, password: Key): Promise /** * Instantiates Account objects from their private keys which are then * encrypted and stored in IndexedDB. The corresponding public keys will * automatically be derived and saved. * - * @param {Uint8Array[]} privateKeys - Private keys of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private keys + * @param {KeyPair[]} keypairs - Indexes and keys of the accounts + * @param {Key} password - Used to encrypt the private keys * @returns {Account[]} The instantiated Account objects */ - static async import (privateKeys: Uint8Array[], password: string | Uint8Array): Promise - static import (input: string | string[] | Uint8Array | Uint8Array[], password?: string | Uint8Array): Account | Account[] | Promise { + static async import (keypairs: KeyPair[], password: Key): Promise + static import (input: Key | Key[] | KeyPair | KeyPair[], password?: Key): Account | Account[] | Promise { if (Array.isArray(input)) { - if (password != null) { + if (this.#isKeyPairs(input) && password != null) { return new Promise((resolve, reject): void => { this.#fromPrivate(input, password) .then(r => resolve(r)) @@ -174,14 +157,15 @@ export class Account { } return this.#fromPublic(input) } else { - if (password != null) { + const inputs = [input] + if (this.#isKeyPairs(inputs) && password != null) { return new Promise((resolve, reject): void => { - this.#fromPrivate([input] as string[], password) + this.#fromPrivate(inputs, password) .then(r => resolve(r[0])) .catch(e => reject(e)) }) } - return this.#fromPublic(input)[0] + return this.#fromPublic(inputs)[0] } } @@ -221,11 +205,11 @@ export class Account { * Signs a block using the private key of the account. The signature is * appended to the signature field of the block before being returned. * - * @param {(string|Uint8Array)} password - Required to decrypt the private key for signing + * @param {Key} password - Required to decrypt the private key for signing * @param {(ChangeBlock|ReceiveBlock|SendBlock)} block - The block data to be hashed and signed * @returns {Promise} Hexadecimal-formatted 64-byte signature */ - async sign (block: ChangeBlock | ReceiveBlock | SendBlock, password: string | Uint8Array): Promise { + async sign (block: ChangeBlock | ReceiveBlock | SendBlock, password: Key): Promise { const privateKey = await this.exportPrivateKey(password) try { const headers = { @@ -249,19 +233,19 @@ export class Account { * Retrieves and decryptes the private key of the Account. The same password * used to lock it must be used to unlock it. * - * @param {(string|Uint8Array)} password Used previously to lock the Account + * @param {Key} password Used previously to lock the Account * @returns Private key bytes as a Uint8Array */ - async exportPrivateKey (password: string | Uint8Array): Promise> + async exportPrivateKey (password: Key): Promise> /** * Retrieves and decryptes the private key of the Account. The same password * used to lock it must be used to unlock it. * - * @param {(string|Uint8Array)} password Used previously to lock the Account + * @param {Key} password Used previously to lock the Account * @returns Private key bytes as a hexadecimal string */ - async exportPrivateKey (password: string | Uint8Array, format: 'hex'): Promise - async exportPrivateKey (password: string | Uint8Array, format?: 'hex'): Promise> { + async exportPrivateKey (password: Key, format: 'hex'): Promise + async exportPrivateKey (password: Key, format?: 'hex'): Promise { if (typeof password === 'string') password = utf8.toBytes(password) if (password == null || !(password instanceof Uint8Array)) { throw new Error('Password must be string or bytes') @@ -270,10 +254,12 @@ export class Account { const headers = { method: 'get', name: this.publicKey, - store: 'Account', + store: 'Account' + } + const data = { password: password.buffer } - const response = await SafeWorker.assign(headers) + const response = await SafeWorker.assign(headers, data) const privateKey = new Uint8Array(response[this.publicKey] as ArrayBuffer) return format === 'hex' ? bytes.toHex(privateKey) @@ -337,43 +323,48 @@ export class Account { * and stored in IndexedDB. The corresponding public key will automatically be * derived and saved. * - * @param {(string|Uint8Array)} privateKeys - Private key of the account + * @param {KeyPair} keypairs - Indexes and keys of the accounts * @param {number} [index] - Account number used when deriving the key * @returns {Account} A new Account object */ - static async #fromPrivate (privateKeys: string[] | Uint8Array[], password: string | Uint8Array): Promise { + static async #fromPrivate (keypairs: KeyPair[], password: Key): Promise { if (typeof password === 'string') password = utf8.toBytes(password) if (password == null || !(password instanceof Uint8Array)) { throw new Error('Invalid password when importing Account') } - const keypairs: Data = {} - for (let privateKey of privateKeys) { + const accounts: Account[] = [] + const data: Data = {} + for (let keypair of keypairs) { + let { index, privateKey } = keypair + if (index == null) { + throw new RangeError('Index missing for Account') + } this.#validateKey(privateKey) if (typeof privateKey === 'string') privateKey = hex.toBytes(privateKey) - let publicKey: string try { const headers = { - method: 'convert' + method: 'convert', + privateKey: privateKey.buffer } - const data = { - privateKey: new Uint8Array(privateKey).buffer - } - publicKey = await NanoNaClWorker.assign(headers, data) - keypairs[publicKey] = privateKey.buffer + const publicKey = await NanoNaClWorker.assign(headers) + data[publicKey] = privateKey.buffer + + const address = this.#keyToAddress(publicKey) + this.#isInternal = true + accounts.push(new this(address, publicKey, index)) } catch (err) { throw new Error(`Failed to derive public key from private key`, { cause: err }) } } - const accounts = await this.import(Object.keys(keypairs)) try { const headers = { method: 'set', - store: 'Account', - password: password.buffer + store: 'Account' } - const isLocked = await SafeWorker.assign(headers, keypairs) + data.password = password.buffer + const isLocked = await SafeWorker.assign(headers, data) if (!isLocked) { throw null } @@ -392,12 +383,14 @@ export class Account { * @param {(string[]|Uint8Array[])} input - Public keys or addresses of the accounts * @returns {Account[]} The instantiated Account objects */ - static #fromPublic (input: string[] | Uint8Array[] | unknown): Account[] { - const inputArray: unknown[] = Array.isArray(input) ? input : [input] + static #fromPublic (input: KeyPair[] | unknown): Account[] { + if (!this.#isKeys(input)) { + throw new TypeError('Invalid public input for Account') + } const accounts: Account[] = [] let address: string let publicKey: Uint8Array - for (let i of inputArray) { + for (let i of input) { let keyError, addressError try { this.#validateKey(i) @@ -422,6 +415,32 @@ export class Account { return accounts } + static #isKeys (input: unknown): input is Key[] { + if (Array.isArray(input)) { + for (const i of input) { + if (typeof i !== 'string' && !(i instanceof Uint8Array && 'buffer' in i)) { + return false + } + } + } + return true + } + + static #isKeyPairs (input: unknown): input is KeyPair[] { + if (Array.isArray(input)) { + for (const i of input) { + if (typeof input !== 'object') { + return false + } + const obj = i as { [key: string]: unknown } + if ('index' in obj || 'privateKey' in obj || 'publicKey' in obj) { + return true + } + } + } + return false + } + /** * Converts a public key to a Nano address. * @@ -441,7 +460,7 @@ export class Account { * @param {unknown} key - Key bytes as Uint8Array or hexadecimal string * @throws If key is invalid */ - static #validateKey (key: unknown): asserts key is (string | Uint8Array) { + static #validateKey (key: unknown): asserts key is (Key) { if (key === undefined) { throw new TypeError(`Key is undefined`) } diff --git a/src/lib/bip39-mnemonic.ts b/src/lib/bip39-mnemonic.ts index e286d76..9476941 100644 --- a/src/lib/bip39-mnemonic.ts +++ b/src/lib/bip39-mnemonic.ts @@ -5,8 +5,7 @@ import { Bip39Words } from './bip39-wordlist' import { BIP39_ITERATIONS } from './constants' import { bin, bytes, dec, utf8 } from './convert' import { Entropy } from './entropy' - -const { subtle } = globalThis.crypto +import { Key } from '#types' /** * Represents a mnemonic phrase that identifies a wallet as defined by BIP-39. @@ -78,7 +77,7 @@ export class Bip39Mnemonic { * @returns {Promise} First N/32 bits of the hash as a hexadecimal string */ static async checksum (entropy: Entropy): Promise { - const hashBuffer = await subtle.digest('SHA-256', entropy.bytes) + const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', entropy.bytes) const hashBytes = new Uint8Array(hashBuffer) const hashBits = bytes.toBin(hashBytes) const checksumLength = entropy.bits.length / 32 @@ -146,7 +145,7 @@ export class Bip39Mnemonic { passphrase = '' } const keyData = utf8.toBytes(this.phrase) - const phraseKey = await subtle.importKey('raw', keyData, 'PBKDF2', false, ['deriveBits', 'deriveKey']) + const phraseKey = await globalThis.crypto.subtle.importKey('raw', keyData, 'PBKDF2', false, ['deriveBits', 'deriveKey']) const derivedKeyType: HmacImportParams = { name: 'HMAC', hash: 'SHA-512', @@ -160,8 +159,8 @@ export class Bip39Mnemonic { salt: utf8.toBytes(passphrase), iterations: BIP39_ITERATIONS } - const seedKey = await subtle.deriveKey(algorithm, phraseKey, derivedKeyType, true, ['sign']) - const seedBuffer = await subtle.exportKey('raw', seedKey) + const seedKey = await globalThis.crypto.subtle.deriveKey(algorithm, phraseKey, derivedKeyType, true, ['sign']) + const seedBuffer = await globalThis.crypto.subtle.exportKey('raw', seedKey) this.#bip44Seed = new Uint8Array(seedBuffer) } return format === 'hex' @@ -176,7 +175,7 @@ export class Bip39Mnemonic { * @returns {string} Hexadecimal seed */ async toBlake2bSeed (format: 'hex'): Promise - async toBlake2bSeed (format?: 'hex'): Promise> { + async toBlake2bSeed (format?: 'hex'): Promise { if (this.#blake2bSeed == null) { const wordArray = this.phrase.split(' ') const bits = wordArray.map((w: string) => { diff --git a/src/lib/block.ts b/src/lib/block.ts index ebd164c..57e032b 100644 --- a/src/lib/block.ts +++ b/src/lib/block.ts @@ -141,7 +141,7 @@ abstract class Block { } else { try { const account = (typeof input === 'string') - ? await Account.import(input, '') + ? await Account.import({ privateKey: input }, '') : this.account this.signature = await account.sign(this, '') } catch (err) { diff --git a/src/lib/tools.ts b/src/lib/tools.ts index 84a5328..a9a4459 100644 --- a/src/lib/tools.ts +++ b/src/lib/tools.ts @@ -8,6 +8,7 @@ import { UNITS } from './constants' import { bytes, hex } from './convert' import { Rpc } from './rpc' import { Bip44Wallet, Blake2bWallet, LedgerWallet } from './wallets' +import { Key } from '#types' import { NanoNaClWorker } from '#workers' type SweepResult = { @@ -83,11 +84,11 @@ export async function convert (amount: bigint | string, inputUnit: string, outpu /** * Signs arbitrary strings with a private key using the Ed25519 signature scheme. * -* @param {(string|Uint8Array)} key - Hexadecimal-formatted private key to use for signing +* @param {Key} key - Hexadecimal-formatted private key to use for signing * @param {...string} input - Data to be signed * @returns {Promise} Hexadecimal-formatted signature */ -export async function sign (key: string | Uint8Array, ...input: string[]): Promise { +export async function sign (key: Key, ...input: string[]): Promise { if (typeof key === 'string') key = hex.toBytes(key) let signature: string try { @@ -170,12 +171,12 @@ export async function sweep ( /** * Verifies the signature of arbitrary strings using a public key. * -* @param {(string|Uint8Array)} key - Hexadecimal-formatted public key to use for verification +* @param {Key} key - Hexadecimal-formatted public key to use for verification * @param {string} signature - Hexadcimal-formatted signature * @param {...string} input - Data to be verified * @returns {Promise} True if the data was signed by the public key's matching private key */ -export async function verify (key: string | Uint8Array, signature: string, ...input: string[]): Promise { +export async function verify (key: Key, signature: string, ...input: string[]): Promise { if (typeof key === 'string') key = hex.toBytes(key) try { const headers = { diff --git a/src/lib/wallets/bip44-wallet.ts b/src/lib/wallets/bip44-wallet.ts index dd01f2d..6cbe424 100644 --- a/src/lib/wallets/bip44-wallet.ts +++ b/src/lib/wallets/bip44-wallet.ts @@ -6,7 +6,7 @@ import { Bip39Mnemonic } from '#src/lib/bip39-mnemonic.js' import { SEED_LENGTH_BIP44 } from '#src/lib/constants.js' import { bytes, hex, utf8 } from '#src/lib/convert.js' import { Entropy } from '#src/lib/entropy.js' -import { KeyPair } from '#types' +import { Key, KeyPair } from '#types' import { Bip44CkdWorker } from '#workers' /** @@ -89,7 +89,7 @@ export class Bip44Wallet extends Wallet { * @returns {Bip44Wallet} A newly instantiated Bip44Wallet */ static async fromEntropy (key: Uint8Array, entropy: string, salt?: string): Promise - static async fromEntropy (passkey: string | Uint8Array, entropy: string, salt: string = ''): Promise { + static async fromEntropy (passkey: Key, entropy: string, salt: string = ''): Promise { if (typeof passkey === 'string') passkey = utf8.toBytes(passkey) let wallet: Bip44Wallet try { @@ -129,7 +129,7 @@ export class Bip44Wallet extends Wallet { * @returns {Bip44Wallet} A newly instantiated Bip44Wallet */ static async fromMnemonic (key: Uint8Array, mnemonic: string, salt?: string): Promise - static async fromMnemonic (passkey: string | Uint8Array, mnemonic: string, salt: string = ''): Promise { + static async fromMnemonic (passkey: Key, mnemonic: string, salt: string = ''): Promise { if (typeof passkey === 'string') passkey = utf8.toBytes(passkey) let wallet: Bip44Wallet try { @@ -170,7 +170,7 @@ export class Bip44Wallet extends Wallet { * @returns {Bip44Wallet} A newly instantiated Bip44Wallet */ static async fromSeed (key: Uint8Array, seed: string): Promise - static async fromSeed (passkey: string | Uint8Array, seed: string): Promise { + static async fromSeed (passkey: Key, seed: string): Promise { if (typeof passkey === 'string') passkey = utf8.toBytes(passkey) if (seed.length !== SEED_LENGTH_BIP44) { throw new Error(`Expected a ${SEED_LENGTH_BIP44}-character seed, but received ${seed.length}-character string.`) diff --git a/src/lib/wallets/blake2b-wallet.ts b/src/lib/wallets/blake2b-wallet.ts index e093069..2b9264f 100644 --- a/src/lib/wallets/blake2b-wallet.ts +++ b/src/lib/wallets/blake2b-wallet.ts @@ -7,7 +7,7 @@ import { Blake2b } from '#src/lib/blake2b.js' import { SEED_LENGTH_BLAKE2B } from '#src/lib/constants.js' import { hex, utf8 } from '#src/lib/convert.js' import { Entropy } from '#src/lib/entropy.js' -import { KeyPair } from '#types' +import { Key, KeyPair } from '#types' /** * BLAKE2b wallet created by deriving a mnemonic phrase from a seed or vice @@ -79,7 +79,7 @@ export class Blake2bWallet extends Wallet { * @returns {Blake2bWallet} A newly instantiated Blake2bWallet */ static async fromSeed (key: Uint8Array, seed: string): Promise - static async fromSeed (passkey: string | Uint8Array, seed: string): Promise { + static async fromSeed (passkey: Key, seed: string): Promise { if (typeof passkey === 'string') passkey = utf8.toBytes(passkey) if (seed.length !== SEED_LENGTH_BLAKE2B) { throw new Error(`Expected a ${SEED_LENGTH_BLAKE2B}-character seed, but received ${seed.length}-character string.`) @@ -118,7 +118,7 @@ export class Blake2bWallet extends Wallet { * @returns {Blake2bWallet} A newly instantiated Blake2bWallet */ static async fromMnemonic (key: Uint8Array, mnemonic: string): Promise - static async fromMnemonic (passkey: string | Uint8Array, mnemonic: string): Promise { + static async fromMnemonic (passkey: Key, mnemonic: string): Promise { if (typeof passkey === 'string') passkey = utf8.toBytes(passkey) let wallet: Blake2bWallet try { diff --git a/src/lib/wallets/wallet.ts b/src/lib/wallets/wallet.ts index 2aa4d73..166ede5 100644 --- a/src/lib/wallets/wallet.ts +++ b/src/lib/wallets/wallet.ts @@ -7,7 +7,7 @@ import { ADDRESS_GAP } from '#src/lib/constants.js' import { bytes, hex, utf8 } from '#src/lib/convert.js' import { Entropy } from '#src/lib/entropy.js' import { Rpc } from '#src/lib/rpc.js' -import { Data, KeyPair } from '#types' +import { Data, Key, KeyPair } from '#types' import { SafeWorker } from '#workers' /** @@ -102,20 +102,28 @@ export abstract class Wallet { } if (indexes.length > 0) { const keypairs = await this.ckd(indexes) + const privateKeys = [] for (const keypair of keypairs) { const { index, privateKey, publicKey } = keypair if (index == null) { throw new RangeError('Account keys derived but index missing') } if (privateKey != null) { - output[index] = await Account.import(privateKey, this.seed) - } else if (publicKey != null) { - output[index] = await Account.import(publicKey) - } else { - throw new RangeError('Account keys missing') + privateKeys.push(keypair) + } else if (typeof publicKey === 'string') { + output[index] = Account.import(publicKey) + } else if (publicKey instanceof Uint8Array) { + output[index] = Account.import(publicKey) } this.#accounts[index] = output[index] } + const privateAccounts = await Account.import(privateKeys, this.seed) + for (const a of privateAccounts) { + if (a.index == null) { + throw new RangeError('Index missing for Account') + } + output[a.index] = this.#accounts[a.index] = a + } } return output } @@ -144,10 +152,10 @@ export abstract class Wallet { * Locks the wallet and all currently derived accounts with a password that * will be needed to unlock it later. * - * @param {(string|Uint8Array)} password Used to lock the wallet + * @param {Key} password Used to lock the wallet * @returns True if successfully locked */ - async lock (password: string | Uint8Array): Promise { + async lock (password: Key): Promise { if (typeof password === 'string') { password = utf8.toBytes(password) } @@ -214,10 +222,10 @@ export abstract class Wallet { /** * Unlocks the wallet using the same password as used prior to lock it. * - * @param {(string|Uint8Array)} password Used previously to lock the wallet + * @param {Key} password Used previously to lock the wallet * @returns True if successfully unlocked */ - async unlock (password: string | Uint8Array): Promise { + async unlock (password: Key): Promise { if (typeof password === 'string') { password = utf8.toBytes(password) } diff --git a/src/lib/workers/nano-nacl.ts b/src/lib/workers/nano-nacl.ts index 2ab4920..f2f9fbc 100644 --- a/src/lib/workers/nano-nacl.ts +++ b/src/lib/workers/nano-nacl.ts @@ -6,7 +6,7 @@ import { WorkerInterface } from './worker-interface' import { Blake2b } from '#src/lib/blake2b.js' import { default as Convert, bytes, hex } from '#src/lib/convert.js' -import { Data, Headers } from '#types' +import { Data, Headers, Key } from '#types' /** * Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. @@ -565,10 +565,10 @@ export class NanoNaCl extends WorkerInterface { /** * Derives a public key from a private key. * - * @param {(string|Uint8Array)} seed - 32-byte private key + * @param {Key} seed - 32-byte private key * @returns 32-byte public key byte array */ - static convert (seed: string | Uint8Array): Uint8Array { + static convert (seed: Key): Uint8Array { if (typeof seed === 'string') seed = hex.toBytes(seed) this.checkArrayTypes(seed) if (seed.length !== this.crypto_sign_SEEDBYTES) { diff --git a/src/lib/workers/queue.ts b/src/lib/workers/queue.ts index 3c40cc3..59f5f42 100644 --- a/src/lib/workers/queue.ts +++ b/src/lib/workers/queue.ts @@ -78,13 +78,6 @@ export class Queue { const { id, headers, data, reject } = this.#job try { const buffers: ArrayBuffer[] = [] - if (headers != null) { - for (let h of Object.keys(headers)) { - if (headers[h] instanceof ArrayBuffer) { - buffers.push(headers[h]) - } - } - } if (data != null) { for (let d of Object.keys(data)) { buffers.push(data[d]) diff --git a/src/lib/workers/safe.ts b/src/lib/workers/safe.ts index bcc8c63..44ea2f4 100644 --- a/src/lib/workers/safe.ts +++ b/src/lib/workers/safe.ts @@ -22,7 +22,9 @@ export class Safe extends WorkerInterface { } static async work (headers: Headers, data: Data): Promise { - const { method, name, store, password } = headers + const { method, name, store } = headers + const { password } = data + delete data.password this.#storage = await this.#open(this.DB_NAME) let result try { diff --git a/src/types.d.ts b/src/types.d.ts index c868e7f..bc24af2 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -78,40 +78,40 @@ export declare class Account { * derived and saved. * * @param {string} privateKey - Private key of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private key + * @param {Key} password - Used to encrypt the private key * @returns {Account} A new Account object */ - static import (privateKey: string, password: string | Uint8Array): Promise + static import (privateKey: string, password: Key): Promise /** * Instantiates an Account object from its private key which is then encrypted * and stored in IndexedDB. The corresponding public key will automatically be * derived and saved. * * @param {Uint8Array} privateKey - Private key of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private key + * @param {Key} password - Used to encrypt the private key * @returns {Account} A new Account object */ - static import (privateKey: Uint8Array, password: string | Uint8Array): Promise + static import (privateKey: Uint8Array, password: Key): Promise /** * Instantiates Account objects from their private keys which are then * encrypted and stored in IndexedDB. The corresponding public keys will * automatically be derived and saved. * * @param {string[]} privateKeys - Private keys of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private keys + * @param {Key} password - Used to encrypt the private keys * @returns {Account[]} The instantiated Account objects */ - static import (privateKeys: string[], password: string | Uint8Array): Promise + static import (privateKeys: string[], password: Key): Promise /** * Instantiates Account objects from their private keys which are then * encrypted and stored in IndexedDB. The corresponding public keys will * automatically be derived and saved. * * @param {Uint8Array[]} privateKeys - Private keys of the account - * @param {(string|Uint8Array)} password - Used to encrypt the private keys + * @param {Key} password - Used to encrypt the private keys * @returns {Account[]} The instantiated Account objects */ - static import (privateKeys: Uint8Array[], password: string | Uint8Array): Promise + static import (privateKeys: Uint8Array[], password: Key): Promise /** * Refreshes the account from its current state on the network. * @@ -125,27 +125,27 @@ export declare class Account { * Signs a block using the private key of the account. The signature is * appended to the signature field of the block before being returned. * - * @param {(string|Uint8Array)} password - Required to decrypt the private key for signing + * @param {Key} password - Required to decrypt the private key for signing * @param {(ChangeBlock|ReceiveBlock|SendBlock)} block - The block data to be hashed and signed * @returns {Promise} Hexadecimal-formatted 64-byte signature */ - sign (block: ChangeBlock | ReceiveBlock | SendBlock, password: string | Uint8Array): Promise + sign (block: ChangeBlock | ReceiveBlock | SendBlock, password: Key): Promise /** * Retrieves and decryptes the private key of the Account. The same password * used to lock it must be used to unlock it. * - * @param {(string|Uint8Array)} password Used previously to lock the Account + * @param {Key} password Used previously to lock the Account * @returns Private key bytes as a Uint8Array */ - exportPrivateKey (password: string | Uint8Array): Promise> + exportPrivateKey (password: Key): Promise> /** * Retrieves and decryptes the private key of the Account. The same password * used to lock it must be used to unlock it. * - * @param {(string|Uint8Array)} password Used previously to lock the Account + * @param {Key} password Used previously to lock the Account * @returns Private key bytes as a hexadecimal string */ - exportPrivateKey (password: string | Uint8Array, format: 'hex'): Promise + exportPrivateKey (password: Key, format: 'hex'): Promise /** * Validates a Nano address with 'nano' and 'xrb' prefixes * Derived from https://github.com/alecrios/nano-address-validator -- 2.47.3