// SPDX-FileCopyrightText: © 2026 LEDGER SAS // SPDX-License-Identifier: Apache-2.0 import type { Context, CurrencyConfig } from '../config' import type { BlockInfo, ListOperationsOptions } from './types' import { optionalApiKeys, requiredApiKeys } from './impl' import { isNotSupportedStub } from './notSupported' import { notSupportedApi } from './notSupportedApi' import { withDefaults } from './withDefaults' type Cfg = CurrencyConfig type Ctx = Context const ctx: Ctx = { config: () => Promise.reject(new Error('stub')), logger: () => undefined } const isMethod = (value: unknown): value is (...args: unknown[]) => unknown => typeof value === 'function' describe('notSupportedApi', () => { it('stubs every capability with the standard error', () => { const api: Record = notSupportedApi() for (const name of [...requiredApiKeys, ...optionalApiKeys]) { if (name === 'getAccountInfo') continue const method = api[name] if (!isMethod(method)) throw new Error(`${name} is missing`) expect(() => method()).toThrow(`${name} is not supported`) } }) it('answers the ADR-045 sentinel for getAccountInfo rather than throwing', async () => { await expect(notSupportedApi().getAccountInfo?.(ctx, 'addr')).resolves.toEqual({ type: 'none', }) }) it('leaves listFeeOptions absent, as withDefaults does', () => { expect(notSupportedApi().listFeeOptions).toBe(undefined) }) it('tags its stubs, so they are distinguishable from implementations', () => { expect(isNotSupportedStub(notSupportedApi().getStakes)).toBe(true) }) // The point of shipping this alongside the authoring type: a module may be written either // way and still report the same capabilities through the resolver. Were the stubs not // tagged, `supports` would call every spread stub an implementation and say the opposite // of the truth. it('reports the truth through withDefaults().supports()', () => { const partialModule = { ...notSupportedApi(), lastBlock: (_ctx: Ctx): Promise => Promise.reject(new Error('stub')), getBalance: (_ctx: Ctx, _addr: string) => Promise.resolve([]), listOperations: (_ctx: Ctx, _addr: string, _opts: ListOperationsOptions) => Promise.resolve({ items: [] }), getStakes: (_ctx: Ctx, _addr: string) => Promise.resolve({ items: [] }), } const api = withDefaults(partialModule) expect(api.supports('getStakes')).toBe(true) expect(api.supports('getValidators')).toBe(false) expect(api.supports('getRewards')).toBe(false) // Overridden methods keep the real implementation, not the stub. expect(() => api.getBalance(ctx, 'addr')).not.toThrow() // Everything left stubbed still raises the same error from the same name. expect(() => api.broadcast(ctx, 'tx')).toThrow('broadcast is not supported') }) })