interface ByteRange { offset: number; size: number; } type FormattedValue = null | string | number | boolean | bigint | FormattedValue[] | { [key: string]: FormattedValue; } | { variant: string; value: FormattedValue | null; }; type FormattedValueWithByteRange = { value: FormattedValue; _byteRange: ByteRange; } | { hex: string; _byteRange: ByteRange; } | { variant: string; value: FormattedValue | null; _byteRange: ByteRange; }; interface FormattedReflection { typeName: string; kind: string | null | undefined; value: FormattedValue; byteRange?: ByteRange; } type JsonValue = unknown; interface WasmConfig { /** * Public URL for the generated wasm-pack JS glue module. * * Browser apps that bundle @thru/sdk can use this to load ABI * reflection from a stable static asset path instead of relying on a * package-relative dynamic import. */ moduleUrl?: string; /** * Public URL for abi_reflect_wasm_bg.wasm. */ wasmUrl: string; } /** * Configure the URL from which to load the WASM file. * Must be called before any reflection functions are used. * * This is useful for environments like Next.js where bundler-based WASM loading * doesn't work. Instead, copy the WASM file to your public directory and call: * * @example * ```ts * import { configureWasm } from "@thru/sdk/abi"; * configureWasm("/wasm/abi_reflect_wasm_bg.wasm"); * ``` * * Browser apps that serve both the generated wasm-pack JS glue and the * `.wasm` binary from public assets should pass both URLs: * * @example * ```ts * configureWasm({ * moduleUrl: "/wasm/abi/web/abi_reflect_wasm.js", * wasmUrl: "/wasm/abi/web/abi_reflect_wasm_bg.wasm", * }); * ``` * * Passing a string preserves the legacy behavior and only configures * the `.wasm` binary URL. * * @param config - WASM URL or full browser asset configuration. */ declare function configureWasm(config: string | WasmConfig): void; type BinaryLike = Uint8Array | ArrayBuffer | ArrayBufferView | number[]; declare function reflect(abiYaml: string, typeName: string, payload: { type: 'binary'; value: BinaryLike; } | { type: 'hex'; value: string; }): Promise; declare function buildLayoutIr(abiYaml: string): Promise; type ReflectRootPayload = { type: 'binary'; value: BinaryLike; } | { type: 'hex'; value: string; }; declare function reflectInstruction(abiYaml: string, payload: ReflectRootPayload): Promise; declare function reflectAccount(abiYaml: string, payload: ReflectRootPayload): Promise; declare function reflectEvent(abiYaml: string, payload: ReflectRootPayload): Promise; declare function ensureWasmLoaded(): Promise; interface FormatOptions { includeByteOffsets?: boolean; } declare function formatReflection(raw: JsonValue, options?: FormatOptions): FormattedReflection; type Manifest = Record; /** * Reflect a binary buffer using a pre-resolved manifest. * * @param manifest - Map of package names to ABI YAML content * @param rootPackage - The package containing the target type * @param typeName - The type name to parse * @param payload - Binary data to reflect */ declare function reflectWithManifest(manifest: Manifest, rootPackage: string, typeName: string, payload: ReflectRootPayload): Promise; /** * Reflect an instruction using a pre-resolved manifest. */ declare function reflectInstructionWithManifest(manifest: Manifest, rootPackage: string, payload: ReflectRootPayload): Promise; /** * Reflect an account using a pre-resolved manifest. */ declare function reflectAccountWithManifest(manifest: Manifest, rootPackage: string, payload: ReflectRootPayload): Promise; /** * Reflect an event using a pre-resolved manifest. */ declare function reflectEventWithManifest(manifest: Manifest, rootPackage: string, payload: ReflectRootPayload): Promise; /** * Build layout IR using a pre-resolved manifest. */ declare function buildLayoutIrWithManifest(manifest: Manifest, rootPackage: string): Promise; /** * Get the list of package names in a manifest. */ declare function getManifestPackages(manifest: Manifest): Promise; interface ManifestPackageInfo { name: string; package: string; version: number; type_count: number; has_root_types: boolean; } /** * Validate a manifest and return information about its contents. */ declare function validateManifest(manifest: Manifest): Promise; declare const MAX_NESTED_INSTRUCTION_DEPTH = 15; interface NestedInstructionDecodeOptions { maxDepth?: number; } type NestedInstructionDecoder = (programAddress: string, data: Uint8Array) => FormattedReflection | null | undefined | Promise; declare function resolveNestedInstructionData(reflection: FormattedReflection, accountAddresses: readonly string[], decoder: NestedInstructionDecoder, options?: NestedInstructionDecodeOptions): Promise; /** * Import Source Types * * These types mirror the Rust ImportSource enum and related types. */ type OnchainTarget = "program" | "abi-meta" | "abi"; type RevisionSpec = { type: "exact"; value: number; } | { type: "minimum"; value: number; } | { type: "latest"; } | { type: "atSlot"; slot: bigint; }; type ImportSource = { type: "path"; path: string; } | { type: "git"; url: string; ref: string; path: string; } | { type: "http"; url: string; } | { type: "onchain"; address: string; target: OnchainTarget; network: string; revision: RevisionSpec; }; interface PackageId { packageName: string; version: string; } interface ResolvedPackage { id: PackageId; source: ImportSource; abiYaml: string; dependencies: PackageId[]; isRemote: boolean; } interface ResolutionResult { root: ResolvedPackage; allPackages: ResolvedPackage[]; manifest: Record; } declare class ResolutionError extends Error { code: "CYCLIC_DEPENDENCY" | "VERSION_CONFLICT" | "FETCH_ERROR" | "PARSE_ERROR" | "NOT_FOUND" | "UNSUPPORTED_IMPORT_TYPE"; details?: unknown | undefined; constructor(code: "CYCLIC_DEPENDENCY" | "VERSION_CONFLICT" | "FETCH_ERROR" | "PARSE_ERROR" | "NOT_FOUND" | "UNSUPPORTED_IMPORT_TYPE", message: string, details?: unknown | undefined); } declare const ABI_ACCOUNT_HEADER_SIZE = 45; declare const ABI_STATE_OPEN = 0; declare const ABI_STATE_FINALIZED = 1; interface AbiAccountData { abiMetaAccount: Uint8Array; revision: bigint; state: number; content: string; } interface RpcEndpoints { [network: string]: string; } declare const DEFAULT_RPC_ENDPOINTS: RpcEndpoints; interface AbiMetadata { package: string; name?: string; "abi-version": number; "package-version": string; description: string; imports?: ImportSourceYaml[]; } type ImportSourceYaml = { type: "path"; path: string; } | { type: "git"; url: string; ref: string; path: string; } | { type: "http"; url: string; } | { type: "onchain"; address: string; target?: OnchainTarget; network: string; revision?: number | string; }; interface AbiFile { abi: AbiMetadata; types: unknown[]; } /** * On-chain ABI Fetcher * * Fetches ABI content from on-chain accounts. */ /** * Minimal interface for a Thru RPC client that can fetch raw accounts. * This is compatible with @thru/sdk client but doesn't require it. */ interface ThruRpcClient { query: { getRawAccount: (request: { address: { value: Uint8Array; }; versionContext: Record; }) => Promise<{ rawData?: Uint8Array; }>; }; } /** * Derive the official ABI account address for a given program. * * This performs the same derivation as OnchainFetcher.fetch() with target="program", * returning the raw 32-byte address of the ABI account. */ declare function deriveOfficialAbiAddress(programAddress: string, abiManagerProgramId?: string): Promise; /** * Parse ABI account data from raw bytes. * * Account header layout (45 bytes): * - abi_meta_account: [u8; 32] * - revision: u64 (little-endian) * - state: u8 (0x00=OPEN, 0x01=FINALIZED) * - content_sz: u32 (little-endian) * - content: [u8; content_sz] */ declare function parseAbiAccountData(data: Uint8Array): AbiAccountData; /** * Check if a revision matches the specification. * * Note: `atSlot` skips this check entirely in `OnchainFetcher.fetch` — the * constraint there is "whatever revision was active at this slot", and the * RPC's version_context handles that selection server-side. */ declare function revisionMatches(revision: bigint, spec: RevisionSpec): boolean; interface OnchainFetcherConfig { rpcEndpoints?: RpcEndpoints; thruClient?: ThruRpcClient; abiManagerProgramId?: string; abiManagerIsEphemeral?: boolean; } interface FetchResult { abiYaml: string; revision: bigint; isFinalized: boolean; } /** * Fetcher for on-chain ABI accounts. * * Supports fetching ABI from: * - Official ABI via program (target: "program") * - ABI via ABI meta account (target: "abi-meta") * - Direct ABI account (target: "abi") */ declare class OnchainFetcher { private rpcEndpoints; private thruClient?; private abiManagerProgramId; private abiManagerIsEphemeral; constructor(config?: OnchainFetcherConfig); /** * Fetch ABI content from an on-chain account. * * The `revision` parameter controls both how the account is selected * server-side (via version_context when `atSlot` is used) and whether the * returned revision is validated against an expected value (`exact` / * `minimum`). For `atSlot`, the returned `FetchResult.revision` reflects * the revision that was active at that slot. */ fetch(address: string, target: OnchainTarget, network: string, revision: RevisionSpec): Promise; /** * Get the RPC endpoint for a network. */ getRpcEndpoint(network: string): string; private parseAddress; private fetchAccountData; private fetchWithThruClient; private fetchWithHttp; } /** * Import Resolver * * Resolves ABI imports and builds a manifest for WASM consumption. */ interface ResolverConfig { onchainFetcher?: OnchainFetcher; rpcEndpoints?: RpcEndpoints; maxDepth?: number; } /** * Resolve all imports for an ABI and return a manifest. * * The resolver only supports on-chain imports for browser environments. * For path imports, use the CLI `bundle` command. */ declare function resolveImports(rootAbiYaml: string, config?: ResolverConfig): Promise; /** * Create a manifest from an ABI and its resolved imports. * * The manifest maps package names to ABI YAML content. */ declare function createManifest(result: ResolutionResult): Record; export { ABI_ACCOUNT_HEADER_SIZE, ABI_STATE_FINALIZED, ABI_STATE_OPEN, type AbiAccountData, type AbiFile, type AbiMetadata, type ByteRange, DEFAULT_RPC_ENDPOINTS, type FetchResult, type FormatOptions, type FormattedReflection, type FormattedValue, type FormattedValueWithByteRange, type ImportSource, type ImportSourceYaml, MAX_NESTED_INSTRUCTION_DEPTH, type Manifest, type ManifestPackageInfo, type NestedInstructionDecodeOptions, type NestedInstructionDecoder, OnchainFetcher, type OnchainFetcherConfig, type OnchainTarget, type PackageId, ResolutionError, type ResolutionResult, type ResolvedPackage, type ResolverConfig, type RevisionSpec, type RpcEndpoints, type ThruRpcClient, type WasmConfig, buildLayoutIr, buildLayoutIrWithManifest, configureWasm, createManifest, deriveOfficialAbiAddress, ensureWasmLoaded, formatReflection, getManifestPackages, parseAbiAccountData, reflect, reflectAccount, reflectAccountWithManifest, reflectEvent, reflectEventWithManifest, reflectInstruction, reflectInstructionWithManifest, reflectWithManifest, resolveImports, resolveNestedInstructionData, revisionMatches, validateManifest };