]> git.codecow.com Git - libnemo.git/commitdiff
Rename getNextNewAccount and alphabetize wallet methods.
authorChris Duncan <chris@zoso.dev>
Sun, 6 Jul 2025 05:06:15 +0000 (22:06 -0700)
committerChris Duncan <chris@zoso.dev>
Sun, 6 Jul 2025 05:06:15 +0000 (22:06 -0700)
src/lib/wallets/wallet.ts
test/test.refresh-accounts.mjs

index 7bbc335c93eeca6d63de33964361f6013cb29a59..4a685177a96ffb499fd480f377a8726c5d249656 100644 (file)
@@ -53,25 +53,6 @@ export abstract class Wallet {
                Wallet.#poolSafe ??= new Pool(SafeWorker)\r
        }\r
 \r
-       /**\r
-       * Removes encrypted secrets in storage and releases variable references to\r
-       * allow garbage collection.\r
-       */\r
-       async destroy (): Promise<void> {\r
-               let i = 0\r
-               for (const a in this.#accounts) {\r
-                       await this.#accounts[a].destroy()\r
-                       delete this.#accounts[a]\r
-                       i++\r
-               }\r
-               this.#m = null\r
-               this.#s = null\r
-               await Wallet.#poolSafe.assign({\r
-                       method: 'destroy',\r
-                       name: this.id\r
-               })\r
-       }\r
-\r
        /**\r
        * Retrieves an account from a wallet using its child key derivation function.\r
        * Defaults to the first account at index 0.\r
@@ -152,61 +133,22 @@ export abstract class Wallet {
        }\r
 \r
        /**\r
-       * Fetches the lowest-indexed unopened account from a wallet in sequential\r
-       * order. An account is unopened if it has no frontier block.\r
-       *\r
-       * @param {Rpc|string|URL} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks\r
-       * @param {number} batchSize - Number of accounts to fetch and check per RPC callout\r
-       * @param {number} from - Account index from which to start the search\r
-       * @returns {Promise<Account>} The lowest-indexed unopened account belonging to the wallet\r
-       */\r
-       async getNextNewAccount (rpc: Rpc, batchSize: number = ADDRESS_GAP, from: number = 0): Promise<Account> {\r
-               if (!Number.isSafeInteger(batchSize) || batchSize < 1) {\r
-                       throw new RangeError(`Invalid batch size ${batchSize}`)\r
-               }\r
-               const accounts = await this.accounts(from, from + batchSize - 1)\r
-               const addresses = []\r
-               for (const a in accounts) {\r
-                       addresses.push(accounts[a].address)\r
-               }\r
-               const data = {\r
-                       "accounts": addresses\r
-               }\r
-               const { errors } = await rpc.call('accounts_frontiers', data)\r
-               for (const key of Object.keys(errors ?? {})) {\r
-                       const value = errors[key]\r
-                       if (value === 'Account not found') {\r
-                               return Account.fromAddress(key)\r
-                       }\r
-               }\r
-               return await this.getNextNewAccount(rpc, batchSize, from + batchSize)\r
-       }\r
-\r
-       /**\r
-       * Refreshes wallet account balances, frontiers, and representatives from the\r
-       * current state on the network.\r
-       *\r
-       * A successful response will set these properties on each account.\r
-       *\r
-       * @param {Rpc|string|URL} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks\r
-       * @returns {Promise<Account[]>} Accounts with updated balances, frontiers, and representatives\r
+       * Removes encrypted secrets in storage and releases variable references to\r
+       * allow garbage collection.\r
        */\r
-       async refresh (rpc: Rpc | string | URL, from: number = 0, to: number = from): Promise<AccountList> {\r
-               if (typeof rpc === 'string' || rpc.constructor === URL) {\r
-                       rpc = new Rpc(rpc)\r
-               }\r
-               if (rpc.constructor !== Rpc) {\r
-                       throw new TypeError('RPC must be a valid node')\r
-               }\r
-               const accounts = await this.accounts(from, to)\r
-               for (const a in accounts) {\r
-                       try {\r
-                               await accounts[a].refresh(rpc)\r
-                       } catch (err) {\r
-                               delete accounts[a]\r
-                       }\r
+       async destroy (): Promise<void> {\r
+               let i = 0\r
+               for (const a in this.#accounts) {\r
+                       await this.#accounts[a].destroy()\r
+                       delete this.#accounts[a]\r
+                       i++\r
                }\r
-               return accounts\r
+               this.#m = null\r
+               this.#s = null\r
+               await Wallet.#poolSafe.assign({\r
+                       method: 'destroy',\r
+                       name: this.id\r
+               })\r
        }\r
 \r
        /**\r
@@ -260,6 +202,33 @@ export abstract class Wallet {
                return true\r
        }\r
 \r
+       /**\r
+       * Refreshes wallet account balances, frontiers, and representatives from the\r
+       * current state on the network.\r
+       *\r
+       * A successful response will set these properties on each account.\r
+       *\r
+       * @param {Rpc|string|URL} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks\r
+       * @returns {Promise<Account[]>} Accounts with updated balances, frontiers, and representatives\r
+       */\r
+       async refresh (rpc: Rpc | string | URL, from: number = 0, to: number = from): Promise<AccountList> {\r
+               if (typeof rpc === 'string' || rpc.constructor === URL) {\r
+                       rpc = new Rpc(rpc)\r
+               }\r
+               if (rpc.constructor !== Rpc) {\r
+                       throw new TypeError('RPC must be a valid node')\r
+               }\r
+               const accounts = await this.accounts(from, to)\r
+               for (const a in accounts) {\r
+                       try {\r
+                               await accounts[a].refresh(rpc)\r
+                       } catch (err) {\r
+                               delete accounts[a]\r
+                       }\r
+               }\r
+               return accounts\r
+       }\r
+\r
        /**\r
        * Unlocks the wallet using the same password as used prior to lock it.\r
        *\r
@@ -302,4 +271,35 @@ export abstract class Wallet {
                }\r
                return true\r
        }\r
+\r
+       /**\r
+       * Fetches the lowest-indexed unopened account from a wallet in sequential\r
+       * order. An account is unopened if it has no frontier block.\r
+       *\r
+       * @param {Rpc|string|URL} rpc - RPC node information required to refresh accounts, calculate PoW, and process blocks\r
+       * @param {number} batchSize - Number of accounts to fetch and check per RPC callout\r
+       * @param {number} from - Account index from which to start the search\r
+       * @returns {Promise<Account>} The lowest-indexed unopened account belonging to the wallet\r
+       */\r
+       async unopened (rpc: Rpc, batchSize: number = ADDRESS_GAP, from: number = 0): Promise<Account> {\r
+               if (!Number.isSafeInteger(batchSize) || batchSize < 1) {\r
+                       throw new RangeError(`Invalid batch size ${batchSize}`)\r
+               }\r
+               const accounts = await this.accounts(from, from + batchSize - 1)\r
+               const addresses = []\r
+               for (const a in accounts) {\r
+                       addresses.push(accounts[a].address)\r
+               }\r
+               const data = {\r
+                       "accounts": addresses\r
+               }\r
+               const { errors } = await rpc.call('accounts_frontiers', data)\r
+               for (const key of Object.keys(errors ?? {})) {\r
+                       const value = errors[key]\r
+                       if (value === 'Account not found') {\r
+                               return Account.fromAddress(key)\r
+                       }\r
+               }\r
+               return await this.unopened(rpc, batchSize, from + batchSize)\r
+       }\r
 }\r
index c37f34ba639be91202816b1a86987f220e227866..d325f090c04a6a47a9c42e4a000df3d2c104dfe5 100644 (file)
@@ -78,7 +78,7 @@ await suite('Fetch next unopened account', { skip: false }, async () => {
        await test('return correct account from test vector', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
-               const account = await wallet.getNextNewAccount(rpc)
+               const account = await wallet.unopened(rpc)
 
                assert.exists(account)
                assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
@@ -90,7 +90,7 @@ await suite('Fetch next unopened account', { skip: false }, async () => {
        await test('return successfully for small batch size', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
-               const account = await wallet.getNextNewAccount(rpc, 1)
+               const account = await wallet.unopened(rpc, 1)
 
                assert.exists(account)
                assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
@@ -102,7 +102,7 @@ await suite('Fetch next unopened account', { skip: false }, async () => {
        await test('return successfully for large batch size', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
-               const account = await wallet.getNextNewAccount(rpc, 100)
+               const account = await wallet.unopened(rpc, 100)
 
                assert.exists(account)
                assert.equals(account.address, NANO_TEST_VECTORS.ADDRESS_1)
@@ -115,11 +115,11 @@ await suite('Fetch next unopened account', { skip: false }, async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
 
-               await assert.rejects(wallet.getNextNewAccount())
-               await assert.rejects(wallet.getNextNewAccount(null))
-               await assert.rejects(wallet.getNextNewAccount(1))
-               await assert.rejects(wallet.getNextNewAccount(''))
-               await assert.rejects(wallet.getNextNewAccount('foo'))
+               await assert.rejects(wallet.unopened())
+               await assert.rejects(wallet.unopened(null))
+               await assert.rejects(wallet.unopened(1))
+               await assert.rejects(wallet.unopened(''))
+               await assert.rejects(wallet.unopened('foo'))
 
                await wallet.destroy()
        })
@@ -128,11 +128,11 @@ await suite('Fetch next unopened account', { skip: false }, async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
 
-               await assert.rejects(wallet.getNextNewAccount(rpc, null))
-               await assert.rejects(wallet.getNextNewAccount(rpc, -1))
-               await assert.rejects(wallet.getNextNewAccount(rpc, ''))
-               await assert.rejects(wallet.getNextNewAccount(rpc, 'foo'))
-               await assert.rejects(wallet.getNextNewAccount(rpc, { 'foo': 'bar' }))
+               await assert.rejects(wallet.unopened(rpc, null))
+               await assert.rejects(wallet.unopened(rpc, -1))
+               await assert.rejects(wallet.unopened(rpc, ''))
+               await assert.rejects(wallet.unopened(rpc, 'foo'))
+               await assert.rejects(wallet.unopened(rpc, { 'foo': 'bar' }))
 
                await wallet.destroy()
        })