import { Pool } from './pool.js'\r
import { Rpc } from './rpc.js'\r
import { Safe } from './safe.js'\r
-import { ckdBip44 } from './workers.js'\r
+import { ckdBip44, nanoNacl } from './workers.js'\r
import type { Ledger } from './ledger.js'\r
\r
+type KeyPair = {\r
+ publicKey?: string,\r
+ privateKey?: string,\r
+ index?: number\r
+}\r
/**\r
* Represents a wallet containing numerous Nano accounts derived from a single\r
* source, the form of which can vary based on the type of wallet. The Wallet\r
#id: Entropy\r
#locked: boolean = true\r
#mnemonic: Bip39Mnemonic | null\r
+ #pool: Pool\r
#safe: Safe\r
#seed: string | null\r
get id () { return this.#id.hex }\r
return ''\r
}\r
\r
- abstract ckd (index: number | number[]): Promise<Account> | Promise<Account[]>\r
+ abstract ckd (index: number | number[]): Promise<KeyPair> | Promise<KeyPair[]>\r
\r
constructor (seed?: string, mnemonic?: Bip39Mnemonic, id?: string) {\r
if (this.constructor === Wallet) {\r
? new Entropy(id)\r
: new Entropy(16)\r
this.#mnemonic = mnemonic ?? null\r
+ this.#pool = new Pool(nanoNacl)\r
this.#safe = new Safe()\r
this.#seed = seed ?? null\r
}\r
if (indexes.length > 0) {\r
let results = await this.ckd(indexes)\r
if (!Array.isArray(results)) results = [results]\r
- for (const result of results) {\r
- if (result.index == null) {\r
- throw new RangeError('Account key derived but index missing')\r
- } else {\r
- this.#accounts[result.index] = result\r
- }\r
+ const data: any = []\r
+ results.forEach(r => data.push({ privateKey: r.privateKey, index: r.index }))\r
+ let now = performance.now()\r
+ const keypairs: [{ publicKey: string, privateKey: string, index: number }] = await this.#pool.work(data)\r
+ console.log(`accounts: ${-now + (now = performance.now())} ms`)\r
+ for (const keypair of keypairs) {\r
+ if (keypair.publicKey == null) throw new RangeError('Account public key missing')\r
+ if (keypair.privateKey == null) throw new RangeError('Account private key missing')\r
+ if (keypair.index == null) throw new RangeError('Account keys derived but index missing')\r
+ const { publicKey, privateKey, index } = keypair\r
+ this.#accounts[keypair.index] = Account.fromKnownKeys(publicKey, privateKey, index)\r
}\r
+ console.log(`done: ${-now + (now = performance.now())} ms`)\r
}\r
return this.#accounts.slice(from, to + 1)\r
}\r
* @param {number} index - Index of the account\r
* @returns {Promise<Account>}\r
*/\r
- async ckd (index: number | number[]): Promise<Account[]> {\r
+ async ckd (index: number | number[]): Promise<KeyPair[]> {\r
if (!Array.isArray(index)) index = [index]\r
const data: any = []\r
index.forEach(i => data.push({ seed: this.seed, index: i }))\r
let now = performance.now()\r
- const privateKeys: [{ index: number, key: string }] = await this.#pool.work(data)\r
+ const privateKeys: KeyPair[] = await this.#pool.work(data)\r
console.log(`ckd: ${-now + (now = performance.now())} ms`)\r
- const accounts: Account[] = []\r
- for (const pk of privateKeys) {\r
- const { key, index } = pk\r
- if (typeof key !== 'string') {\r
- throw new TypeError('BIP-44 child key derivation returned invalid data')\r
- }\r
- accounts.push(await Account.fromPrivateKey(key, index))\r
- }\r
- console.log(`accounts: ${-now + (now = performance.now())} ms`)\r
- return accounts\r
+ return privateKeys\r
}\r
}\r
\r
* @param {number} index - Index of the account\r
* @returns {Promise<Account>}\r
*/\r
- async ckd (index: number | number[]): Promise<Account[]> {\r
+ async ckd (index: number | number[]): Promise<KeyPair[]> {\r
if (!Array.isArray(index)) index = [index]\r
const data: any = []\r
let now = performance.now()\r
return { key, index }\r
})\r
console.log(`ckd: ${-now + (now = performance.now())} ms`)\r
- const accounts: Account[] = []\r
- for (const result of results) {\r
- const { key, index } = result\r
- if (typeof key !== 'string') {\r
- throw new TypeError('BLAKE2b child key derivation returned invalid data')\r
- }\r
- accounts.push(await Account.fromPrivateKey(key, index))\r
- }\r
- console.log(`accounts: ${-now + (now = performance.now())} ms`)\r
- return accounts\r
+ return results\r
}\r
}\r
\r
* @param {number} index - Index of the account\r
* @returns {Promise<Account>}\r
*/\r
- async ckd (index: number): Promise<Account> {\r
+ async ckd (index: number): Promise<KeyPair> {\r
const { status, publicKey } = await this.ledger.account(index)\r
if (status === 'OK' && publicKey != null) {\r
- return await Account.fromPublicKey(publicKey, index)\r
+ return { publicKey, index }\r
}\r
throw new Error(`Error getting Ledger account: ${status}`)\r
}\r