]> git.codecow.com Git - libnemo.git/commitdiff
Refactor account load to work from single inputs.
authorChris Duncan <chris@zoso.dev>
Thu, 16 Oct 2025 02:26:21 +0000 (19:26 -0700)
committerChris Duncan <chris@zoso.dev>
Thu, 16 Oct 2025 02:26:21 +0000 (19:26 -0700)
src/lib/account/index.ts
src/lib/account/load.ts

index ac15c20e6be35921d69968f4a6ce8a4db07a925a..6b6d88a0684180b1a607dc0de9dbd23525eebbc1 100644 (file)
@@ -2,9 +2,7 @@
 //! SPDX-License-Identifier: GPL-3.0-or-later\r
 \r
 import { Block } from '../block'\r
-import { ACCOUNT_KEY_BYTE_LENGTH, ACCOUNT_KEY_HEX_LENGTH } from '../constants'\r
-import { bytes, hex } from '../convert'\r
-import { NanoNaCl } from '../crypto'\r
+import { bytes } from '../convert'\r
 import { Rpc } from '../rpc'\r
 import { Address } from './address'\r
 import { _load } from './load'\r
@@ -246,7 +244,15 @@ export class Account {
        * @returns {(Account | Account[] | Promise<Account | Account[]>)} Promise for array of new Account objects\r
        */\r
        static load (input: string | Uint8Array<ArrayBuffer> | KeyPair | (string | Uint8Array<ArrayBuffer> | KeyPair)[], type?: 'private'): Account | Account[] | Promise<Account | Account[]> {\r
-               return _load(input, type)\r
+               const isInputArray = Array.isArray(input)\r
+               const inputs = isInputArray ? input : [input]\r
+               this.#isInternal = true\r
+               const accounts = inputs.map((input) => {\r
+                       const { address, publicKey, index } = _load(input, type)\r
+                       return new this(address, publicKey, index)\r
+               })\r
+               this.#isInternal = false\r
+               return isInputArray ? accounts : accounts[0]\r
        }\r
 \r
        /**\r
index b897bc91b7e54cb3dc82186a9135eef098fe77ee..1835f4d644cda7f7d794098348b92162e2f5ffe0 100644 (file)
@@ -2,19 +2,16 @@
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
 import { Account, KeyPair } from '../account'
-import { Address } from './address'
 import { ACCOUNT_KEY_BYTE_LENGTH, ACCOUNT_KEY_HEX_LENGTH } from '../constants'
 import { hex } from '../convert'
 import { NanoNaCl } from '../crypto'
+import { Address } from './address'
 
-export function _load (input: string | Uint8Array<ArrayBuffer> | KeyPair | (string | Uint8Array<ArrayBuffer> | KeyPair)[], type?: 'private'): Account | Account[] | Promise<Account | Account[]> {
-       const isInputArray = Array.isArray(input)
-       const inputs = isInputArray ? input : [input]
-       if (isKeyPairs(inputs) && type === 'private') {
-               return fromPrivate(inputs)
-                       .then(r => isInputArray ? r : r[0])
+export function _load (input: string | Uint8Array<ArrayBuffer> | KeyPair, type?: 'private'): { address: Address, publicKey: Uint8Array<ArrayBuffer>, index?: number } {
+       if (isKeyPair(input) && type === 'private') {
+               return fromPrivate(input)
        } else {
-               return isInputArray ? fromPublic(inputs) : fromPublic(inputs)[0]
+               return fromPublic(input)
        }
 }
 
@@ -25,31 +22,24 @@ export function _load (input: string | Uint8Array<ArrayBuffer> | KeyPair | (stri
 * @param {KeyPair} keypairs - Indexes and keys of the accounts
 * @returns {Promise<Account[]>} Promise for new Account objects
 */
-async function fromPrivate (keypairs: KeyPair[]): Promise<Account[]> {
+function fromPrivate (keypair: KeyPair) {
        try {
-               const accounts: Account[] = []
-               for (let keypair of keypairs) {
-                       let { index, privateKey } = keypair
-                       if (index == null) {
-                               throw new RangeError('Index missing for Account')
-                       }
-                       if (typeof privateKey === 'string' && RegExp(`^[A-F0-9]{${ACCOUNT_KEY_HEX_LENGTH}}$`, 'i').test(privateKey)) {
-                               privateKey = hex.toBytes(privateKey)
-                       }
-                       if (!(privateKey instanceof Uint8Array) || privateKey.every(v => v === 0)) {
-                               throw new TypeError('Invalid private key')
-                       }
-                       if (privateKey.byteLength !== ACCOUNT_KEY_BYTE_LENGTH) {
-                               throw new TypeError(`Private key must be ${ACCOUNT_KEY_BYTE_LENGTH} bytes`)
-                       }
-                       const publicKey = await NanoNaCl.convert(privateKey)
-                       const address = new Address(publicKey)
-                       this.#isInternal = true
-                       const account = new this(address, publicKey, index)
-                       this.#isInternal = false
-                       accounts.push(account)
+               let { index, privateKey } = keypair
+               if (index == null) {
+                       throw new RangeError('Index missing for Account')
+               }
+               if (typeof privateKey === 'string' && RegExp(`^[A-F0-9]{${ACCOUNT_KEY_HEX_LENGTH}}$`, 'i').test(privateKey)) {
+                       privateKey = hex.toBytes(privateKey)
+               }
+               if (!(privateKey instanceof Uint8Array) || privateKey.every(v => v === 0)) {
+                       throw new TypeError('Invalid private key')
+               }
+               if (privateKey.byteLength !== ACCOUNT_KEY_BYTE_LENGTH) {
+                       throw new TypeError(`Private key must be ${ACCOUNT_KEY_BYTE_LENGTH} bytes`)
                }
-               return accounts
+               const publicKey = NanoNaCl.convert(privateKey)
+               const address = new Address(publicKey)
+               return { address, publicKey, index }
        } catch (err) {
                throw new Error('Failed to import Accounts from private keys', { cause: err })
        }
@@ -62,38 +52,29 @@ async function fromPrivate (keypairs: KeyPair[]): Promise<Account[]> {
 * @param {(string | Uint8Array<ArrayBuffer>|KeyPair)[]} input - Public keys or addresses of the accounts
 * @returns {Account[]} The instantiated Account objects
 */
-function fromPublic (input: (string | Uint8Array<ArrayBuffer> | KeyPair)[] | unknown): Account[] {
+function fromPublic (input: string | Uint8Array<ArrayBuffer> | KeyPair | unknown) {
        try {
-               const keypairs = isKeyPairs(input)
+               const keypair = isKeyPair(input)
                        ? input
-                       : isKeys(input)
-                               ? input.map(i => { return { publicKey: i } as KeyPair })
-                               : []
-               if (keypairs.length === 0) {
+                       : isKey(input)
+                               ? { publicKey: input } as KeyPair
+                               : undefined
+               if (keypair == null) {
                        throw new TypeError('Invalid public input for Account')
                }
-
-               const accounts: Account[] = []
-               for (let keypair of keypairs) {
-                       if (keypair.publicKey == null) {
-                               throw new TypeError('Account address or public key is required', { cause: keypair.publicKey })
-                       }
-                       const { index } = keypair
-                       const address = new Address(keypair.publicKey)
-                       const publicKey = address.toPublicKey()
-                       this.#isInternal = true
-                       const account = new this(address, publicKey, index)
-                       this.#isInternal = false
-                       accounts.push(account)
+               if (keypair.publicKey == null) {
+                       throw new TypeError('Account address or public key is required', { cause: keypair.publicKey })
                }
-               return accounts
+               const { index } = keypair
+               const address = new Address(keypair.publicKey)
+               const publicKey = address.toPublicKey()
+               return { address, publicKey, index }
        } catch (err) {
                console.error(err)
                throw new TypeError('Failed to import Account from public data', { cause: { err } })
        }
 }
 
-
 function isKeyPair (input: unknown): input is KeyPair {
        if (typeof input === 'object') {
                const obj = input as { [key: string]: unknown }
@@ -110,30 +91,6 @@ function isKeyPair (input: unknown): input is KeyPair {
        return false
 }
 
-
-function isKeyPairs (input: unknown): input is KeyPair[] {
-       if (Array.isArray(input)) {
-               for (const i of input) {
-                       if (!isKeyPair(i)) {
-                               return false
-                       }
-               }
-       }
-       return true
-}
-
-
 function isKey (input: unknown): input is string | Uint8Array<ArrayBuffer> {
        return typeof input === 'string' || (input instanceof Uint8Array && 'buffer' in input)
 }
-
-function isKeys (input: unknown): input is (string | Uint8Array<ArrayBuffer>)[] {
-       if (Array.isArray(input)) {
-               for (const i of input) {
-                       if (!isKey(i)) {
-                               return false
-                       }
-               }
-       }
-       return true
-}