import * as Token from './Token.js' /** Canonical identifier for a funding chain. */ export type Id = `eip155:${number}` | `solana:${string}` | `tron:${string}` /** Chain metadata for a funding token. */ export type Chain = Callable & ( | (Base & { /** Address encoding used by accounts and tokens on the chain. */ addressFormat: 'hex' /** Chain execution family. */ kind: 'evm' }) | (Base & { /** Address encoding used by accounts and tokens on the chain. */ addressFormat: 'base58' /** Chain execution family. */ kind: 'solana' }) | (Base & { /** Address encoding used by accounts and tokens on the chain. */ addressFormat: 'base58check' /** Chain execution family. */ kind: 'tron' }) ) type Callable = (options: Callable.Options) => Selection declare namespace Callable { /** Tokens selected for a funding route on this chain. */ type Options = { /** Token definitions to resolve on the chain. */ tokens: readonly Token.Token[] } } /** Tokens resolved for one funding chain. */ export type Selection = { /** Chain shared by every selected token. */ chain: Chain /** Chain-scoped funding tokens. */ tokens: readonly Token.Resolved[] } type Base = { /** Caller-facing aliases accepted for this chain. */ aliases: readonly string[] /** CAIP-2 chain identifier. */ id: Id /** Human-readable chain name. */ name: string /** Parent chain identifier when this chain is a Zone. */ parentChainId?: Id | undefined /** Public RPC endpoints used for funding-chain evidence. */ rpcUrls: readonly string[] /** Stable chain segment used in quote identifiers. */ slug: string } /** Creates funding chain metadata from a CAIP-2 identifier. */ export function from(options: from.Options): Chain { const { aliases = [], id, name, parentChainId, rpcUrls = [], slug } = options const base = { aliases, id, name, ...(parentChainId ? { parentChainId } : {}), rpcUrls, slug } const metadata = (() => { if (id.startsWith('eip155:')) return { ...base, addressFormat: 'hex', kind: 'evm' } as const if (id.startsWith('solana:')) return { ...base, addressFormat: 'base58', kind: 'solana' } as const if (id.startsWith('tron:')) return { ...base, addressFormat: 'base58check', kind: 'tron' } as const throw new InvalidIdError() })() function select(parameters: Callable.Options): Selection { const chain = select as Chain return { chain, tokens: parameters.tokens.map((token) => Token.resolve(token, chain)), } } return Object.defineProperties( select, Object.fromEntries( Object.entries(metadata).map(([key, value]) => [ key, { configurable: true, enumerable: true, value }, ]), ), ) as Chain } export declare namespace from { /** Funding chain definition. */ type Options = { /** Additional caller-facing aliases accepted for this chain. */ aliases?: readonly string[] | undefined /** CAIP-2 chain identifier. */ id: Id /** Human-readable chain name. */ name: string /** Parent chain identifier when this chain is a Zone. */ parentChainId?: Id | undefined /** Public RPC endpoints used for funding-chain evidence. */ rpcUrls?: readonly string[] | undefined /** Stable chain segment used in quote identifiers. */ slug: string } } /** Returns the numeric portion of an EIP-155 CAIP-2 chain identifier. */ export function eip155Id(chain: Chain): string { const match = /^eip155:(\d+)$/.exec(chain.id) if (!match?.[1]) throw new InvalidIdError() return match[1] } /** Error thrown when a funding chain identifier is invalid for an operation. */ export class InvalidIdError extends Error { override name = 'Funding.Chain.InvalidIdError' }