From 8bea9106d12cdf80e308fd9471cf35c0ebf78314 Mon Sep 17 00:00:00 2001 From: Chris Duncan Date: Fri, 7 Aug 2026 07:01:06 -0700 Subject: [PATCH] Specify valid subtypes in parsed block_info response and fix remaining refresh function issues. --- src/lib/rpc/block_info.ts | 7 ++++--- src/lib/wallet/refresh.ts | 30 +++++++++++------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/lib/rpc/block_info.ts b/src/lib/rpc/block_info.ts index da3bf7f..b9dbb36 100644 --- a/src/lib/rpc/block_info.ts +++ b/src/lib/rpc/block_info.ts @@ -1,6 +1,7 @@ //! SPDX-FileCopyrightText: 2026 Chris Duncan //! SPDX-License-Identifier: GPL-3.0-or-later +import { RpcError } from '../errors' export type BlockInfo = { contents: { @@ -21,7 +22,7 @@ export type BlockInfo = { height: string linked_account: string local_timestamp: string - subtype: string + subtype: 'change' | 'epoch' | 'open' | 'receive' | 'send' successor: string } @@ -34,7 +35,7 @@ export function block_info (body: unknown): BlockInfo { && 'height' in body && typeof body.height === 'string' && 'linked_account' in body && typeof body.linked_account === 'string' && 'local_timestamp' in body && typeof body.local_timestamp === 'string' - && 'subtype' in body && typeof body.subtype === 'string' + && 'subtype' in body && (body.subtype === 'change' || body.subtype === 'epoch' || body.subtype === 'open' || body.subtype === 'receive' || body.subtype === 'send') && 'successor' in body && typeof body.successor === 'string' && 'contents' in body && body.contents != null && typeof body.contents === 'object' && 'account' in body.contents && typeof body.contents.account === 'string' @@ -70,6 +71,6 @@ export function block_info (body: unknown): BlockInfo { successor: body.successor, } } else { - throw new Error('Invalid block_info body') + throw new RpcError('Invalid block_info response') } } diff --git a/src/lib/wallet/refresh.ts b/src/lib/wallet/refresh.ts index eb699ee..354811e 100644 --- a/src/lib/wallet/refresh.ts +++ b/src/lib/wallet/refresh.ts @@ -3,7 +3,7 @@ import { Account } from '../account' import { Block } from '../block' -import { Rpc, Schema } from '../rpc' +import { Rpc } from '../rpc' import { Wallet } from '../wallet' export async function _refresh (wallet: Wallet, rpc: Rpc | string | URL, from: number, to: number): Promise> @@ -30,30 +30,22 @@ export async function _refresh (wallet: Wallet, rpc: unknown, from: unknown, to: } const { balances } = await rpc.post('accounts_balances', data) const { frontiers } = await rpc.post('accounts_frontiers', data) - const { blocks } = await rpc.post('blocks_info', { json_block: true, include_not_found: true, hashes: Object.values(frontiers) }) as BlockInfo + const { blocks } = await rpc.post('blocks_info', { json_block: true, include_not_found: true, hashes: Object.values(frontiers ?? {}) }) for (const account of accounts.values()) { account.balance = balances?.[account.address]?.balance ?? 0 account.receivable = balances?.[account.address]?.receivable ?? 0 - if (frontiers[account.address] != null) { + if (frontiers?.[account.address] != null) { account.frontier = frontiers[account.address] - const { subtype } = blocks[account.frontier] - if (!['change', 'epoch', 'open', 'receive', 'send'].includes(subtype)) { - throw new RangeError('Invalid subtype for account frontier block', { cause: subtype }) - } - const frontierContents: Record = {} - for (const [k, v] of Object.entries(blocks[account.frontier].contents)) { - if (Schema.block_info.contents.fields.includes(k) && typeof v === 'string') { - frontierContents[k] = v + if (blocks?.[account.frontier] != null) { + const { subtype, contents: { balance, link, previous, representative, signature } } = blocks[account.frontier] + account.representative = representative + const frontierBlock = new Block(account, balance, previous, representative) + if (typeof frontierBlock[subtype] !== 'function') { + throw new TypeError('Unknown frontier block subtype', { cause: subtype }) } + frontierBlock[subtype](link, 0).signature = signature + account.frontier_block = frontierBlock } - const { balance, link, previous, representative, signature } = frontierContents - account.representative = representative - const frontierBlock = new Block(account, balance, previous, representative) - if (typeof frontierBlock[subtype] !== 'function') { - throw new TypeError('Unknown frontier block subtype', { cause: subtype }) - } - frontierBlock[subtype](link, 0).signature = signature - account.frontier_block = frontierBlock } } return accounts -- 2.52.0