import type { Chain } from 'viem' import type * as Auth from '../../internal/Auth.js' import * as Tidx from '../../internal/Tidx.js' import * as Viem from '../../internal/Viem.js' import * as Scope from '../../Scope.js' /** Returns configured and routable Zones that an API key may read. */ export function readableChainIds(options: readableChainIds.Options): readonly number[] { const { parentChainId, principal, zones } = options const scopes = principal.apiKey.scopes if (!scopes.includes(Scope.wildcard) && !scopes.includes('data:read')) return [] const chainIds = [...zones.values()].flatMap((zone) => { if (zone.sourceId !== parentChainId) return [] const allowed = scopes.includes(Scope.wildcard) || scopes.includes(`zone:${zone.id}:read`) || scopes.includes(`zone:${zone.id}:write`) if (!allowed) return [] if ( principal.environment === 'sandbox' && (zone.sourceId === undefined || Viem.isMainnet(zone.sourceId)) ) return [] const context = { chainId: zone.id, principal, zone } if (Viem.resolveRpc(options.rpc, context).url === undefined) return [] if (Tidx.resolve(options.tidx, context).baseUrl === undefined) return [] return [zone.id] }) return chainIds.sort((a, b) => a - b) } export declare namespace readableChainIds { /** Inputs for resolving the readable inferred-Zone set. */ type Options = { /** Parent Tempo chain whose Zones may be selected. */ parentChainId: Viem.ChainId /** Authenticated API-key principal selecting Zones. */ principal: Extract /** RPC configuration used to exclude unroutable Zones. */ rpc?: Viem.getClient.Rpc | undefined /** TIDX configuration used to exclude unroutable Zones. */ tidx?: Tidx.getClient.Tidx | undefined /** Hosted Zone metadata keyed by chain id. */ zones: ReadonlyMap } } /** Resolves chain receipt probes without treating partial upstream results as complete. */ export function uniqueMatch( probes: readonly uniqueMatch.Probe[], ): uniqueMatch.Result { const failures = probes.flatMap((probe) => ('cause' in probe ? [probe] : [])) if (failures.length > 0) return { failures, kind: 'failed' } const matches = probes.flatMap((probe) => 'value' in probe && probe.value !== null ? [{ chainId: probe.chainId, value: probe.value }] : [], ) if (matches.length === 0) return { kind: 'not_found' } if (matches.length > 1) return { kind: 'ambiguous' } return { ...matches[0]!, kind: 'selected' } } export declare namespace uniqueMatch { /** One completed chain lookup. */ type Probe = | { /** Chain that completed the lookup. */ chainId: number /** Matching value, or null when the chain did not contain the resource. */ value: value | null } | { /** Upstream failure from this chain. */ cause: unknown /** Chain that failed the lookup. */ chainId: number } /** Unique-match decision across every requested chain. */ type Result = | { /** Chain containing the unique match. */ chainId: number /** Unique match result. */ kind: 'selected' /** Value found in the selected Zone. */ value: value } | { /** Every failed Zone lookup. */ failures: readonly Extract, { cause: unknown }>[] /** Partial failure result. */ kind: 'failed' } | { /** Ambiguous match result. */ kind: 'ambiguous' } | { /** No-match result. */ kind: 'not_found' } }