IntersectMBO / IntersectMBO/cardano-api
gRPC: [Meta] cardano-rpc: Ogmios feature parity
- Dominant language
- Haskell
- Stars
- 40
- Forks
- 30
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 30
Description
## Goal
Track everything cardano-rpc needs before it can stand in for Ogmios.
The work is grouped into small, independently shippable chunks - pick any unchecked box and run with it.
Comparison pinned to Ogmios v7.0.0 (2026-08-19).
## Where we stand (10-second version)
| | |
|---|---|
| ✅ Done | chain sync from genesis, submit, eval, UTxO / params / genesis / tip queries |
| 🟡 Close | era summaries (one wire-up away), mempool RPCs (unimplemented) |
| ❌ Missing | stake / rewards / pools / governance queries, tx-chain evaluation |
Indexers doing chain-sync (Kupo-style, see [#1229](https://github.com/IntersectMBO/cardano-api/issues/1229)) and submit-only tooling can migrate off Ogmios today.
Wallets, dApp backends and SPO tooling can't yet - they need the missing rows above.
---
## Phase 1 - quick win
- https://github.com/IntersectMBO/cardano-api/pull/1325 - `ReadEraSummary` - the `EraHistory` is already computed internally for slot/time conversion; only the RPC wiring is missing
## Phase 2 - mempool monitoring
Replaces Ogmios's local-tx-monitor (`acquireMempool` / `nextTransaction` / `hasTransaction` / `sizeOfMempool` / `releaseMempool`):
- [ ] `ReadMempool` - snapshot of current mempool contents
- [ ] `WaitForTx` (streaming) - wait until given txs reach the mempool/chain; covers the acquire-and-poll `hasTransaction` pattern
- [ ] `WatchMempool` (streaming) - live mempool events
## Phase 3 - ledger-state queries (the big gap)
Ogmios exposes ~21 `queryLedgerState/*` methods; we cover 4 categories (utxo, params, tip, genesis).
Upstream has already designed the extension point: the `ReadState` RPC (`AnyChainStateQuery` envelope) with `GetStakePoolDistribution` as the first Cardano query.
Every query beyond that first one is two pieces of work: a PR to utxorpc/spec adding its protobuf definition, then the implementation here.
- [ ] `ReadState` envelope + `GetStakePoolDistribution` (upstream-specced, mirrors Ouroboros `GetPoolDistr`)
- [ ] stake pools: parameters + performance (Ogmios `stakePools`, `stakePoolsPerformances`)
- [ ] rewards: account summaries, projected rewards, provenance (`rewardAccountSummaries`, `projectedRewards`, `rewardsProvenance`)
- [ ] governance: proposals, constitution, committee, DReps (`governanceProposals`, `constitution`, `constitutionalCommittee`, `delegateRepresentatives`)
- [ ] epoch / era: `epoch`, `eraStart` (partly redundant with `ReadEraSummary`)
- [ ] SPO/consensus: `nonces`, `operationalCertificates`
- [ ] `treasuryAndReserves`
## Phase 4 - open design questions
Two Ogmios capabilities with no direct equivalent in our API shape.
Each needs a design decision before any code.
### `EvalTx` cannot evaluate transaction chains
Ogmios's `evaluateTransaction` accepts an `additionalUtxoSet`: extra UTxOs that are not on-chain yet.
That lets tooling evaluate a tx that spends outputs of another, still-unsubmitted tx.
Our `EvalTx` resolves inputs against the live ledger state only, and `EvalTxRequest` has no field for extra UTxOs.
- [ ] add such a field to `EvalTxRequest` in utxorpc/spec
- [ ] support it in the `EvalTx` handler
### Queries always answer at the current tip
Ogmios clients can pin the ledger state at a recent point (`acquireLedgerState`) and run several queries against that one consistent state, so a block arriving mid-sequence cannot skew combined results.
All our queries answer at whatever the tip is at call time.
- [ ] decide whether this is worth supporting at all, and if so how a gRPC API should express it (per-request point parameter vs an acquire/release session)
## Non-goals
Skipped deliberately, each for a stated reason.
Reopen any of them as its own issue if the premise changes.
### Ogmios wire compatibility
Ogmios speaks its own JSON-RPC 2.0 over WebSocket, with stateful acquire/release sessions baked into the protocol.
Emulating it would mean maintaining a second protocol surface, including its session state machine, forever, and it would add no capability that the gRPC API does not already have.
Migrating clients switch protocols instead; an HTTP/JSON path is available through a standalone web proxy, but it is not wire-compatible either.
### Client SDKs
Protobuf codegen already produces typed clients for every mainstream language, and the upstream UTxORPC project publishes SDKs for Python, Go, Rust, Node.js, .NET and Deno.
A hand-written client library would duplicate those and couple its release cadence to node releases; if one is ever wanted, it belongs in a consumer repo.
### `queryLedgerState/dump` (entire ledger state as CBOR)
The payload is the ledger's internal `NewEpochState` debug encoding: schema-free bytes that change with every ledger release, the opposite of what a versioned protobuf API promises.
Serialising the multi-GB mainnet ledger state is also a heavy CPU and memory hit on a relay that is busy serving peers.
The capability also already exists where it belongs: `cardano-cli query ledger-state`, the node's on-disk ledger snapshots, or db-sync for real analysis.
No UTxORPC equivalent, no known consumer; revisit if a real one shows up.
Full Ogmios → cardano-rpc method mapping (v7.0.0)
| Ogmios method | cardano-rpc equivalent | Status |
|---|---|---|
| `findIntersection` + `nextBlock` | `FollowTip` | ✅ |
| `submitTransaction` | `SubmitTx` | ✅ |
| `evaluateTransaction` | `EvalTx` | 🟡 no `additionalUtxoSet` |
| `acquireMempool` / `nextTransaction` / `hasTransaction` / `sizeOfMempool` / `releaseMempool` | `ReadMempool` / `WaitForTx` / `WatchMempool` | ❌ |
| `queryLedgerState/utxo` | `ReadUtxos`, `SearchUtxos` | ✅ |
| `queryLedgerState/protocolParameters` | `ReadParams`, `GetProtocolParamsJson` | ✅ |
| `queryLedgerState/tip` | `ReadTip` | ✅ |
| `queryLedgerState/eraSummaries`, `eraStart`, `epoch` | `ReadEraSummary` (#1325) | 🟡 |
| `queryLedgerState/liveStakeDistribution` | `ReadState` + `GetStakePoolDistribution` (unvendored) | ❌ |
| `queryLedgerState/stakePools`, `stakePoolsPerformances` | - | ❌ |
| `queryLedgerState/rewardAccountSummaries`, `projectedRewards`, `rewardsProvenance` | - | ❌ |
| `queryLedgerState/governanceProposals`, `constitution`, `constitutionalCommittee`, `delegateRepresentatives` | - | ❌ |
| `queryLedgerState/nonces`, `operationalCertificates` | - | ❌ |
| `queryLedgerState/treasuryAndReserves` | - | ❌ |
| `queryLedgerState/dump` | - | ❌ non-goal |
| `queryNetwork/genesisConfiguration` | `ReadGenesis` | ✅ |
| `queryNetwork/tip`, `blockHeight` | `ReadTip` | ✅ |
| `queryNetwork/startTime` | derivable from `ReadGenesis` | ✅ |
## Related
- [#1229](https://github.com/IntersectMBO/cardano-api/issues/1229) - replace Ogmios as Kupo's chain data source (parent use case; server side done)
- [#1216](https://github.com/IntersectMBO/cardano-api/issues/1216) `FetchBlock` · [#1217](https://github.com/IntersectMBO/cardano-api/issues/1217) `ReadGenesis` · [#1218](https://github.com/IntersectMBO/cardano-api/issues/1218) `ReadTip` · [#1219](https://github.com/IntersectMBO/cardano-api/issues/1219) `FollowTip` - all closed
- upstream spec: https://github.com/utxorpc/spec
- Ogmios API reference: https://ogmios.dev/api/
Contributor guide
Assessment
This issue has not been assessed yet.