]> git.codecow.com Git - libnemo.git/commitdiff
Implement vault timer config in wallet.
authorChris Duncan <chris@zoso.dev>
Wed, 10 Sep 2025 06:15:23 +0000 (23:15 -0700)
committerChris Duncan <chris@zoso.dev>
Wed, 10 Sep 2025 06:15:23 +0000 (23:15 -0700)
src/lib/wallet/config.ts [new file with mode: 0644]
src/lib/wallet/index.ts
src/types.d.ts
test/test.lock-unlock.mjs

diff --git a/src/lib/wallet/config.ts b/src/lib/wallet/config.ts
new file mode 100644 (file)
index 0000000..2a5c34e
--- /dev/null
@@ -0,0 +1,26 @@
+//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
+//! SPDX-License-Identifier: GPL-3.0-or-later
+
+import { Vault } from '../vault'
+import { Wallet } from '../wallet'
+
+export async function _config (wallet: Wallet, vault: Vault, settings: { timeout: number }): Promise<void>
+export async function _config (wallet: Wallet, vault: Vault, settings: unknown): Promise<void> {
+       try {
+               if (settings == null || typeof settings !== 'object') {
+                       throw new TypeError('Invalid configuration settings')
+               }
+               const { timeout } = settings as { [key: string]: unknown }
+               if (typeof timeout !== 'number') {
+                       throw new TypeError('Timeout must be number', { cause: timeout })
+               }
+               if (wallet.type === 'BIP-44' || wallet.type === 'BLAKE2b') {
+                       await vault.request({
+                               action: 'config',
+                               timeout
+                       })
+               }
+       } catch (err) {
+               throw new Error('Failed to lock wallet', { cause: err })
+       }
+}
index 751e47d52e85298ff03f9b25d494ac81633ffedd..0b6b45b92dea1f0799b76c9ff0d2c2fb9294a34f 100644 (file)
@@ -10,6 +10,7 @@ import { Rpc } from '../rpc'
 import { Vault } from '../vault'\r
 import { _accounts } from './accounts'\r
 import { _backup } from './backup'\r
+import { _config } from './config'\r
 import { _create } from './create'\r
 import { _destroy } from './destroy'\r
 import { _get } from './get'\r
@@ -245,6 +246,14 @@ export class Wallet {
                return await _accounts(this.type, this.#accounts, this.#vault, from, to)\r
        }\r
 \r
+       /**\r
+       * Configures vault worker settings.\r
+       * @param {number} timeout - Measured in seconds of inactivity before wallet automatically locks\r
+       */\r
+       async config (settings: { timeout: number }): Promise<void> {\r
+               return await _config(this, this.#vault, settings)\r
+       }\r
+\r
        /**\r
        * Removes encrypted secrets in storage, releases variable references to\r
        * allow garbage collection, and terminates vault worker.\r
index 4d2d32103af9264a6e7d2ae24cfc08ff4896f4b5..8c1d490bdddb39d31fd2481b9c533efcec7b3a27 100644 (file)
@@ -741,6 +741,13 @@ export declare class Wallet {
        */
        accounts (from?: number, to?: number): Promise<Map<number, Account>>
        /**
+       * Configures vault worker settings.
+       * @param {number} timeout - Measured in seconds of inactivity before wallet automatically locks
+       */
+       config (settings: {
+               timeout: number
+       }): Promise<void>
+       /**
        * Removes encrypted secrets in storage, releases variable references to
        * allow garbage collection, and terminates vault worker.
        */
index 1618ad9c8fa9c219608e646b5286133273bed80f..31a05e120deec33211e52a39f6730897bd06f9e2 100644 (file)
@@ -182,5 +182,34 @@ await Promise.all([
                                }, 60000)\r
                        })\r
                })\r
+\r
+               await test('configure autolock', { skip: false }, async () => {\r
+                       const wallet = await Wallet.load('BIP-44', NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.MNEMONIC, NANO_TEST_VECTORS.PASSWORD)\r
+                       assert.equal(wallet.isLocked, true)\r
+                       await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)\r
+                       assert.equal(wallet.isLocked, false)\r
+                       await wallet.config({ timeout: 5 })\r
+\r
+                       await new Promise(async (resolve) => {\r
+                               console.log('Waiting 3 seconds...')\r
+                               setTimeout(async () => {\r
+                                       // should still be unlocked\r
+                                       assert.equal(wallet.isLocked, false)\r
+                                       assert.ok(await wallet.verify(NANO_TEST_VECTORS.MNEMONIC))\r
+                                       resolve(null)\r
+                               }, 3000)\r
+                       })\r
+\r
+                       await new Promise(async (resolve) => {\r
+                               console.log('Timer should not be reset by verify, waiting 3 more seconds...')\r
+                               setTimeout(async () => {\r
+                                       // should be locked from account() reset and not reset by verify()\r
+                                       assert.equal(wallet.isLocked, true)\r
+                                       await assert.rejects(wallet.verify(NANO_TEST_VECTORS.MNEMONIC))\r
+                                       await assert.resolves(wallet.destroy())\r
+                                       resolve(null)\r
+                               }, 3000)\r
+                       })\r
+               })\r
        })\r
 ])\r