}
// Index for child account to derive or sign
- if ((action === 'derive' || action === 'sign') && typeof data.index !== 'number') {
+ if ((action === 'derive' || action === 'sign') && !(data.indexes instanceof ArrayBuffer)) {
throw new TypeError('Index is required to derive an account private key')
}
- const index = typeof data.index === 'number'
- ? data.index
- : undefined
-
- // Number of public keys to derive
- if (action === 'derive' && (typeof data.count !== 'number' || data.count < 1)) {
- throw new TypeError('Count is required to derive a batch of keys')
- }
- const count = typeof data.count === 'number'
- ? data.count
+ const indexes = typeof data.indexes instanceof ArrayBuffer
+ ? new Uint32Array(data.index)
: undefined
// Data to sign
const id = parseId(action, data)
const iv = parseIv(action, data)
const parsed = parseData(action, data)
- const { seed, mnemonicPhrase, mnemonicSalt, index, count, encrypted, message, timeout } = parsed
+ const { seed, mnemonicPhrase, mnemonicSalt, indexes, encrypted, message, timeout } = parsed
passkey(action, keySalt, data)
.then((key: CryptoKey | undefined): Promise<Record<string, boolean | number | ArrayBuffer> | void> => {
switch (action) {
return create(type, id, key, keySalt, mnemonicSalt)
}
case 'derive': {
- return derive(index, count)
+ return derive(indexes)
}
case 'load': {
return load(type, id, key, keySalt, mnemonicPhrase ?? seed, mnemonicSalt)
* wallet seed at a specified index and then returns the public key. The wallet
* must be unlocked prior to derivation.
*/
-function derive (index?: number, count?: number): Promise<Record<string, number | ArrayBuffer>> {
+function derive (indexes?: Uint32Array): Promise<Record<string, number | ArrayBuffer>> {
try {
_timer.pause()
if (_locked) {
if (_type !== 'BIP-44' && _type !== 'BLAKE2b' && _type !== 'Exodus') {
throw new Error('Invalid wallet type')
}
- if (typeof index !== 'number' || index < 0) {
- throw new Error('Invalid wallet account index')
- }
- if (typeof count !== 'number' || count < 1) {
- throw new Error('Invalid wallet account batch size')
- }
- const max = index + count
- if (max > (_type === 'BLAKE2b' ? 0xffffffff : 0x7fffffff)) {
- throw new Error('Wallet account range exceeded ')
+ if (indexes == null) {
+ throw new Error('Invalid wallet account index(es)')
}
const promises = []
- for (let i = index; i < max; i++) {
+ const values = indexes.values()
+ for (const index of values) {
promises.push(_ckd(index).then(result => {
const prv = new Uint8Array(result)
const pub = nano25519_derive(prv)
console.warn('libnemo performance may degrade when deriving many accounts at once')
}
const output = new Map<number, Account>()
- const indexes: number[] = []
+ const missing: number[] = []
for (let i = from; i <= to; i++) {
const account = accounts.get(i)
if (account == null) {
- indexes.push(i)
+ missing.push(i)
} else {
output.set(i, account)
}
}
- if (indexes.length > 0) {
+ if (missing.length > 0) {
if (type === 'Ledger') {
- for (const index of indexes) {
+ for (const index of missing) {
const { status, publicKey } = await Ledger.account(index)
if (status !== 'OK' || publicKey == null) {
throw new Error(`Error getting Ledger account: ${status}`)
accounts.set(index, account)
}
} else {
- // const promises = []
- // for (const index of indexes) {
- // promises.push(vault.request<number | ArrayBuffer>({
- // action: 'derive',
- // index
- // }))
- // }
- // const publicKeys = await Promise.all(promises)
- const min = Math.min(...indexes)
- const count = Math.max(...indexes) - min + 1
+ const indexes = new Uint32Array(missing).buffer
const publicKeys = await vault.request<ArrayBuffer>({
action: 'derive',
- index: min,
- count
+ indexes
})
console.log(publicKeys)
for (const [index, publicKey] of Object.entries(publicKeys)) {