//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
+import { RpcError } from '../errors'
export type BlockInfo = {
contents: {
height: string
linked_account: string
local_timestamp: string
- subtype: string
+ subtype: 'change' | 'epoch' | 'open' | 'receive' | 'send'
successor: string
}
&& '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'
successor: body.successor,
}
} else {
- throw new Error('Invalid block_info body')
+ throw new RpcError('Invalid block_info response')
}
}
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<Map<number, Account>>
}
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<string, string> = {}
- 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