]> git.codecow.com Git - libnemo.git/commitdiff
Start refactoring RPC method response parsing.
authorChris Duncan <chris@codecow.com>
Fri, 7 Aug 2026 04:20:53 +0000 (21:20 -0700)
committerChris Duncan <chris@codecow.com>
Fri, 7 Aug 2026 04:20:53 +0000 (21:20 -0700)
src/lib/rpc/accounts_balances.ts
src/lib/rpc/index.ts
src/lib/rpc/schema.ts
src/lib/wallet/refresh.ts

index ecf49b115de5ab71c8c518b5a3cad309ec6cfe4b..274ab0bba67f1c597f4355f1282b9dd0eb2c8d68 100644 (file)
@@ -1,16 +1,71 @@
 //! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-export const accounts_balances = Object.freeze({
-       fields: [
-               'balances',
-       ],
-       balances: {
-               address: {
-                       fields: [
-                               'balance',
-                               'receivable',
-                       ],
-               },
+import { Account } from '../account'
+
+type AccountsBalances = {
+       balances?: {
+               [address: string]: {
+                       balance: string,
+                       receivable: string
+               }
        },
-})
+       errors?: {
+               [address: string]: string
+       }
+}
+
+export function accounts_balances (body: unknown): AccountsBalances {
+       const response: AccountsBalances = {}
+       if (body == null || typeof body !== 'object') {
+               return response
+       }
+
+       const balances = 'balances' in body ? body.balances : null
+       const errors = 'errors' in body ? body.errors : null
+       if (balances == null && errors == null) {
+               return response
+       }
+
+       if (balances != null) {
+               if (typeof balances === 'object') {
+                       for (const [address, data] of Object.entries(balances) as [string, unknown][]) {
+                               try {
+                                       Account.validate(address)
+                                       if (data == null || typeof data !== 'object') {
+                                               throw new Error('Invalid account balance data')
+                                       }
+                                       if ('balance' in data && typeof data.balance === 'string') {
+                                               response.balances ??= {}
+                                               response.balances[address].balance = data.balance
+                                       }
+                                       if ('receivable' in data && typeof data.receivable === 'string') {
+                                               response.balances ??= {}
+                                               response.balances[address].receivable = data.receivable
+                                       }
+                               } catch (err: any) {
+                                       response.errors ??= {}
+                                       response.errors[address] = err?.message
+                               }
+                       }
+               }
+       }
+
+       if (errors != null) {
+               if (typeof errors === 'object') {
+                       for (const [address, error] of Object.entries(errors) as [string, unknown][]) {
+                               try {
+                                       Account.validate(address)
+                                       if (typeof error === 'string') {
+                                               throw new Error(error)
+                                       }
+                               } catch (err: any) {
+                                       response.errors ??= {}
+                                       response.errors[address] = err?.message
+                               }
+                       }
+               }
+       }
+
+       return response
+}
index 6bc3700a1f0a96995e6bc9b71454fd42a1e16b46..aed417b778a1c32b5d6f542dd6bd217fd2710906 100644 (file)
@@ -74,7 +74,7 @@ export class Rpc {
         * @param {object} [data] - JSON to send to the node as defined by the action
         * @returns {Promise<any>} JSON-formatted RPC results from the node
         */
-       async post<T extends keyof typeof Schema> (action: T, data?: Record<string, unknown>): Promise<typeof Schema[T]>
+       async post<T extends keyof typeof Schema> (action: T, data?: Record<string, unknown>): Promise<ReturnType<typeof Schema[T]>>
        async post (action: unknown, data: unknown): Promise<unknown> {
                this.#validate(action)
                const aborter = new AbortController()
@@ -97,7 +97,7 @@ export class Rpc {
                        if (error) {
                                throw new Error(`${code}${error}${message}`, { cause: JSON.stringify(body) })
                        }
-                       return body
+                       return Schema[action](body)
                } catch (err) {
                        console.error(err)
                        throw new Error(`RPC ${action} request failed`, { cause: err })
@@ -131,7 +131,7 @@ export class Rpc {
                })
        }
 
-       #validate (action: unknown): asserts action is string {
+       #validate (action: unknown): asserts action is keyof typeof Schema {
                if (!action) {
                        throw new ReferenceError('Action is required for RPCs')
                }
index d4655b7c0651f131fb0db1f3d9a4515a35ee7658..6d4c444d8a2615786634dcbfe7505b6a86f84458 100644 (file)
@@ -10,12 +10,12 @@ import { blocks_info } from './blocks_info'
 import { process } from './process'
 
 export const Schema = Object.freeze({
-       account_info,
-       account_representative,
+       // account_info,
+       // account_representative,
        accounts_balances,
-       accounts_frontiers,
-       accounts_representatives,
-       block_info,
-       blocks_info,
-       process,
+       // accounts_frontiers,
+       // accounts_representatives,
+       // block_info,
+       // blocks_info,
+       // process,
 })
index 53fd2c3ee111548928fc9d207ce41cf2cb39ccf4..4ef3d43efa458aebd6b9de019ff6ae71748cf289 100644 (file)
@@ -40,7 +40,7 @@ export async function _refresh (wallet: Wallet, rpc: unknown, from: unknown, to:
                        json_block: true,
                        accounts: addresses
                }
-               const { balances } = await rpc.post('accounts_balances', data) as { balances?: { [address: string]: { balance: string, receivable: string } } }
+               const { balances } = await rpc.post('accounts_balances', data)
                const { frontiers } = await rpc.post('accounts_frontiers', data) as { frontiers: { [address: string]: string } }
                const { blocks } = await rpc.post('blocks_info', { json_block: true, hashes: Object.values(frontiers) }) as BlockInfo
                for (const account of accounts.values()) {