/** * The Cardano LCP-metadata adapter — thin I/O, PURE-TS (no chain SDK, no CBOR library). It intentionally * does NOT implement binding-core's `WeldAdapter`: that port is EVM-shaped (`SettlementRef.txHash` is a * `0x`-hex value, `ChainReader` speaks `eth_getLogs`), and Cardano speaks 64-hex tx hashes + transaction * metadata queried by label. Rather than lie through those types, this exposes a Cardano-native surface * (a tx-hash `CardanoSettlementRef`, a `CardanoReader` port over metadata + a label index) alongside the * shared, chain-agnostic `BindingManifest`. Unifying the port shape across EVM and non-EVM rails is future * work; forcing it here would misrepresent the rail. * * `propose` builds the LCP metadatum (JSON value + canonical-CBOR bytes) the buyer attaches under the * dedicated LCP label to their ADA-transfer transaction; `recover` reads the atrHash back from a confirmed * transaction's metadata; `observe` reports the settled transition; `enumerate` uses the metadata-label * index the manifest declares (`forwardIndexable: true`) to list settlements bearing a given atrHash. * * ★ RECOVERY GATES ON PHASE-2 VALIDITY (`CardanoTxView.validContract`). A transaction that fails phase-2 * (Plutus script) validation lands ON-CHAIN — collateral consumed, intended outputs never produced, the * seller paid nothing — while its auxiliary data, being part of the transaction body, keeps the LCP * metadata readable AND keeps it in the label index. Phase-1 failures never enter a block, so the gate is * specifically about phase 2. The documented `propose` path is a script-free ADA transfer, which cannot * reach phase 2; the adapter cannot constrain what transaction a buyer attaches the metadatum to, so it * refuses rather than assumes. */ import type { BindingManifest, Outcome } from "@integraledger/lcp-binding-core"; import { type BlockfrostMetadataEntry, type LcpMetadataValue } from "./metadata.js"; /** A Cardano settlement reference — a 64-hex transaction hash. */ export interface CardanoSettlementRef { txHash: string; } /** The LCP metadatum a buyer attaches to their transaction: the JSON value + its canonical-CBOR bytes. */ export interface ProposedMetadatum { /** The dedicated LCP metadata label to place the value under. */ label: number; /** The Blockfrost-shaped JSON value `{ v, atrHash }`. */ value: LcpMetadataValue; /** The canonical-CBOR bytes of `value` (the on-chain `transaction_metadatum`). */ cbor: Uint8Array; } /** * The minimal view of one confirmed transaction this binding cares about — its metadata plus whether the * transaction's scripts actually validated. */ export interface CardanoTxView { /** The tx-metadata array for a confirmed transaction (`GET /txs/{hash}/metadata`), or [] if none. */ metadata: readonly BlockfrostMetadataEntry[]; /** * Blockfrost's `valid_contract` (`GET /txs/{hash}`). ONLY `true` is a settlement: a transaction that * fails PHASE-2 (Plutus script) validation lands ON-CHAIN with its collateral consumed and its intended * outputs never produced — no funds reach the seller — yet its auxiliary data is part of the transaction * body, so the LCP metadata stays readable and the label index still lists it. Phase-1 failures never * enter a block and so need no gate. Fail-closed: `false` AND absent are both refused, because a reader * that supplied no outcome gave no evidence of success (mirrors binding-solana's `err === null` gate). */ validContract?: boolean; } /** * Reads confirmed transactions and enumerates by the LCP label. An implementation wraps a Cardano indexer * (Blockfrost, db-sync, Koios, …) — integration-only; the protocol adapter takes it as a port so the pure * surface has no chain-SDK dependency. */ export interface CardanoReader { /** One confirmed transaction's view (metadata + `valid_contract`), or `null` if the indexer has none. */ txView(txHash: string): Promise; /** * Tx hashes carrying the given metadata label (`GET /metadata/txs/labels/{label}`) — the forward index. * * ⛔⛔ **`limit` IS REQUIRED, AND THAT IS THIS RAIL'S ANSWER TO THE SCAN QUESTION.** It was optional and * forwarded verbatim, so an absent one handed the depth of the scan to whichever indexer the consumer * bridged — Blockfrost pages this endpoint, db-sync and Koios have their own bounds — and the result * came back as a plain array with nothing saying it had been cut. On this rail that is the sharpest * version of the problem in the tree: the LCP label is DEDICATED and global, so this index accumulates * every LCP settlement on Cardano by every seller, and an unbounded-looking query really returns the * most recent page of all of them. A settlement past it reads as `[]`, which is exactly what "this * atrHash never settled" looks like. * * ⭐ Unlike Hedera, this package cannot state a measured page size, and inventing one would be worse * than the defect: three indexers are named in the docblock above and they do not agree. The caller * names the depth, and a full result is then the bound the caller chose rather than one nobody saw. */ txsWithLabel(label: number, limit: number): Promise; } /** Recover the atrHash from a confirmed tx's metadata, or null if no LCP label carries a valid atrHash. */ export declare function recoverAtrHashFromTx(metadata: readonly BlockfrostMetadataEntry[]): `0x${string}` | null; /** Why a tx view yielded no settled weld — distinguished so `recover`/`observe` report WHY (mirrors * binding-stellar): a transaction the indexer does not have is not a failed one, and a failed one is not * missing metadata. One reading shared by every surface, so they cannot disagree about what a view means. */ export type CardanoSettlementReading = { settled: true; atrHash: `0x${string}`; } | { settled: false; reason: "no-such-transaction" | "unsuccessful-transaction" | "no-atr-metadata"; }; /** * Read a transaction view as a settlement. Pure. Fail-closed: a transaction whose scripts failed phase-2 * consumed its collateral and produced no outputs — its metadata is not a weld — and a view with NO * `validContract` gave no evidence of success at all; both read `unsuccessful-transaction`. */ export declare function readTxView(view: CardanoTxView | null): CardanoSettlementReading; /** Recover the atrHash from a transaction view, or `null` if it is not a phase-2-valid settlement whose * metadata carries one. The null-collapsing convenience over `readTxView` — the reasons live there. */ export declare function recoverAtrHashFromTxView(view: CardanoTxView | null): `0x${string}` | null; /** The Cardano rail's surface. `propose` returns a metadatum for you to attach under label 8847 — it does * not build a transaction. `enumerate` is a NATIVE forward index rather than a scan — an indexer queries * the label directly, which is what the manifest's `forwardIndexable: true` claims and why the label is * dedicated rather than a CIP-20 piggyback. Two other rails declare it, both on a log topic. */ export interface CardanoAdapter { manifest: BindingManifest; /** Build the LCP metadatum (JSON value + canonical-CBOR) to attach under the LCP label. Throws on a malformed atrHash. */ propose(atrHash: string, lcpVersion?: string): ProposedMetadatum; /** Recover the atrHash from a confirmed settlement, or a `verification-failure` Refusal if none binds. */ recover(ref: CardanoSettlementRef, reader: CardanoReader): Promise>; /** Report the settled transition (the tx is confirmed and carries a valid LCP-label atrHash). */ observe(ref: CardanoSettlementRef, reader: CardanoReader): Promise>; /** Metadata-label-index scan for settlements bearing `atrHash` (native forward index — see the manifest). * `limit` is the scan DEPTH and it is REQUIRED — see {@link CardanoReader.txsWithLabel} for why this * package will not choose it, and for what an absent one used to mean on a global label index. */ enumerate(atrHash: string, reader: CardanoReader, limit: number): Promise; } /** Construct the Cardano adapter. **The manifest is injected, not baked in** — pass this package's own * `CARDANO_MANIFEST`; a manifest whose `rail` is not `"cardano"` throws, because an adapter over another * rail's manifest would publish that rail's claims as its own. This is the package's entry point. */ export declare function createCardanoAdapter(manifest: BindingManifest): CardanoAdapter; //# sourceMappingURL=adapter.d.ts.map