]> git.codecow.com Git - libnemo.git/commitdiff
Abort long-running RPC calls after 10 seconds. Throw if any BIP-44 keys are invalid...
authorChris Duncan <chris@zoso.dev>
Fri, 4 Jul 2025 00:56:09 +0000 (17:56 -0700)
committerChris Duncan <chris@zoso.dev>
Fri, 4 Jul 2025 00:56:09 +0000 (17:56 -0700)
src/lib/rpc.ts
src/lib/wallets/bip44-wallet.ts
test/test.refresh-accounts.mjs

index 555db0e0191c714a766a1126cc3dda60cb5df805..0497a918c4329b07819f5db1cded4fcd58247b23 100644 (file)
@@ -41,17 +41,23 @@ export class Rpc {
                        .replaceAll('>', '\\u003d')
                        .replaceAll('\\', '\\u005c')
 
+               const aborter = new AbortController()
                const req = new Request(this.#u, {
+                       signal: aborter.signal,
                        method: 'POST',
                        headers,
                        body
                })
+               const kill = setTimeout(() => {
+                       aborter.abort()
+               }, 10000)
                try {
                        const res = await fetch(req)
                        return await res.json()
                } catch (err) {
-                       console.error(err)
                        return JSON.stringify(err)
+               } finally {
+                       clearTimeout(kill)
                }
        }
 
index 9df7fc65795fba2aeedb426dac25e24ea565685d..45bd3813d00d81b7a98a8ec512436a7e4743f9fa 100644 (file)
@@ -206,7 +206,7 @@ export class Bip44Wallet extends Wallet {
                const privateKeys: KeyPair[] = await this.#poolBip44Ckd.assign(data)\r
                for (let i = 0; i < privateKeys.length; i++) {\r
                        if (privateKeys[i].privateKey == null) {\r
-                               privateKeys.splice(i, 1)\r
+                               throw new Error('Failed to derive private keys')\r
                        }\r
                }\r
                return privateKeys\r
index 59e76aa251cc8bfde5b7dbeb71ec353caea97d71..ef6958442ad2b61b6e90c25d8d88736358e6407f 100644 (file)
@@ -12,33 +12,28 @@ let rpc
 var process = process || env || null
 rpc = new Rpc(process?.env?.NODE_URL ?? '', process?.env?.API_KEY_NAME)
 
-await suite('refreshing account info', { skip: true }, async () => {
+await suite('refreshing account info', { skip: false }, async () => {
 
        await test('fetch balance, frontier, and representative', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
-               const accounts = await wallet.accounts()
-               const account = accounts[0]
+               const account = await wallet.account()
                await account.refresh(rpc)
 
                assert.equals(typeof account.balance, 'bigint')
-               assert.notEqual(account.balance, undefined)
-               assert.notEqual(account.balance, null)
+               assert.exists(account.balance)
                assert.notEqual(account.balance, '')
                assert.notEqual(account.balance && account.balance < 0, true)
 
+               assert.exists(account.frontier)
                assert.equals(typeof account.frontier, 'string')
-               assert.notEqual(account.frontier, undefined)
-               assert.notEqual(account.frontier, null)
                assert.notEqual(account.frontier, '')
-               assert.match(account.frontier ?? '', /^[0-9A-F]{64}$/i)
+               assert.ok(/^[A-Fa-f0-9]{64}$/.test(account.frontier))
 
                assert.equals(account.representative && account.representative.constructor, Account)
-               assert.notEqual(account.representative, undefined)
-               assert.notEqual(account.representative, null)
+               assert.exists(account.representative)
                assert.notEqual(account.representative, '')
-               assert.notEqual(account.representative?.address, undefined)
-               assert.notEqual(account.representative?.address, null)
+               assert.exists(account.representative?.address)
                assert.notEqual(account.representative?.address, '')
 
                await wallet.destroy()
@@ -47,8 +42,8 @@ await suite('refreshing account info', { skip: true }, async () => {
        await test('throw when refreshing unopened account', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
-               const accounts = await wallet.accounts(0x7fffffff)
-               const account = accounts[0]
+               const account = await wallet.account(0x7fffffff)
+
                await assert.rejects(account.refresh(rpc),
                        { message: 'Account not found' })
 
@@ -58,16 +53,18 @@ await suite('refreshing account info', { skip: true }, async () => {
        await test('throw when referencing invalid account index', 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.accounts(0x80000000),
+               await assert.rejects(wallet.account(0x80000000),
                        { message: 'Invalid child key index 0x80000000' })
+
+               await wallet.destroy()
        })
 
        await test('throw with invalid node', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
                await wallet.unlock(NANO_TEST_VECTORS.PASSWORD)
                const invalidNode = new Rpc('http://invalid.com')
-               const accounts = await wallet.accounts()
-               const account = accounts[0]
+               const account = await wallet.account()
+
                await assert.rejects(account.refresh(invalidNode),
                        { message: 'Account not found' })
 
@@ -75,7 +72,7 @@ await suite('refreshing account info', { skip: true }, async () => {
        })
 })
 
-await suite('Fetch next unopened account', { skip: true }, async () => {
+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)
@@ -140,7 +137,7 @@ await suite('Fetch next unopened account', { skip: true }, async () => {
        })
 })
 
-await suite('Refreshing wallet accounts', { skip: true }, async () => {
+await suite('Refreshing wallet accounts', { skip: false }, async () => {
 
        await test('should get balance, frontier, and representative for one account', async () => {
                const wallet = await Bip44Wallet.fromSeed(NANO_TEST_VECTORS.PASSWORD, NANO_TEST_VECTORS.BIP39_SEED)
@@ -149,8 +146,7 @@ await suite('Refreshing wallet accounts', { skip: true }, async () => {
                const account = accounts[0]
                assert.ok(account instanceof Account)
                assert.equals(typeof account.balance, 'bigint')
-               assert.notEqual(account.frontier, undefined)
-               assert.notEqual(account.frontier, null)
+               assert.exists(account.frontier)
                assert.equals(typeof account.frontier, 'string')
 
                await wallet.destroy()