--- /dev/null
+//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
+//! SPDX-License-Identifier: GPL-3.0-or-later
+
+'use strict'
+
+import { Wallet } from 'libnemo'
+import { assert, suite, test } from './GLOBALS.mjs'
+import { CUSTOM_TEST_VECTORS, NANO_TEST_VECTORS, TEST_PASSWORD } from './VECTORS.mjs'
+
+await Promise.all([
+ suite('Autolock Exodus wallet (slowest derivation time, largest pause window)', async () => {
+
+ await test('lock after 10s timeout and not before', async () => {
+ const wallet = await Wallet.load('Exodus', TEST_PASSWORD, CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_0)
+ await wallet.unlock(TEST_PASSWORD)
+
+ await wallet.config({ timeout: 10 })
+ await new Promise(r => setTimeout(r, 8_000))
+ assert.ok(!wallet.isLocked, 'wallet should be unlocked')
+ await new Promise(r => setTimeout(r, 1_000))
+ assert.ok(wallet.isLocked, 'wallet should be locked')
+
+ await assert.resolves(wallet.destroy())
+ })
+
+ await test('stay unlocked for 5s, derive to reset timer, then lock after additional 10s', async () => {
+ const wallet = await Wallet.load('Exodus', TEST_PASSWORD, CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_0)
+ await wallet.unlock(TEST_PASSWORD)
+ await wallet.config({ timeout: 10 })
+
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(!wallet.isLocked, 'wallet should be unlocked')
+
+ await wallet.accounts(0, 1000)
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(!wallet.isLocked, 'wallet should be unlocked')
+
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(wallet.isLocked, 'wallet should be locked')
+
+ await assert.resolves(wallet.destroy())
+ })
+
+ await test('config for 10s autolock, verify after 5s does not reset timer, still locks after additional 5s', async () => {
+ const wallet = await Wallet.load('Exodus', TEST_PASSWORD, CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_0)
+ await wallet.unlock(TEST_PASSWORD)
+ await wallet.config({ timeout: 10 })
+
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(!wallet.isLocked, 'wallet should be unlocked')
+
+ await wallet.verify(CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_0)
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(wallet.isLocked, 'wallet should be locked')
+
+ await wallet.lock()
+ await wallet.unlock(TEST_PASSWORD)
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(!wallet.isLocked, 'wallet should be unlocked')
+
+ await wallet.verify(CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_1)
+ await new Promise(r => setTimeout(r, 5_000))
+ assert.ok(wallet.isLocked, 'wallet should be locked')
+
+ await assert.resolves(wallet.destroy())
+ })
+
+ await test('after first autolock, subsequent autolocks still work', async () => {
+ const wallet = await Wallet.load('Exodus', TEST_PASSWORD, CUSTOM_TEST_VECTORS.EXODUS.BIP39_SEED_0)
+ await wallet.unlock(TEST_PASSWORD)
+ await wallet.config({ timeout: 10 })
+ assert.ok(!wallet.isLocked)
+
+ await new Promise(r => setTimeout(r, 10_000))
+ assert.ok(wallet.isLocked)
+
+ await wallet.unlock(TEST_PASSWORD)
+ await new Promise(r => setTimeout(r, 10_000))
+ assert.ok(wallet.isLocked)
+
+ await assert.resolves(wallet.destroy())
+ })
+ })
+])