Skip to content

Latest commit

 

History

2,547 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Cardano IBC Incubator

License: Apache-2.0 Status: Pre-production Docs: Architecture

This is a work-in-progress implementation of IBC v1 for Cardano. It implements a Cardano-native realization of IBC protocol semantics for interoperability between Cardano and the Cosmos ecosystem. The bridge implements ICS-02 (clients), ICS-03 (connections), ICS-04 (channels and packets), ICS-20 (fungible token transfer), and the proof/path model of ICS-23 and ICS-24, while adapting Cardano to the IBC client model through the experimental 08-cardano-probabilistic light client. The current light client has explicit observer and settlement-heuristic trust assumptions; it is not equivalent to a Tendermint light client or BFT finality.

The implementation adheres to the inter-blockchain communication protocol standards.

Caution

Disclaimer

Please be aware that this is an incubator project, and it is neither complete nor sufficiently tested at this time. The source code and software artifacts in this repository are subject to your own discretion and risk, and are not suggested as adequate for a production bridge deployment.

While we strive for high functionality and user satisfaction, unforeseen issues may arise due to the experimental nature of this project.

Index

Status

Area Status Notes
Local devnet stack Active caribic provisions five Cardano producers through Yaci DevKit
Core IBC semantics Active Implements clients, connections, channels, packets, acknowledgements, and timeouts
ICS-20 transfer path Local: v8-classic Other local profiles need shared clock integration
Historical query backend Active Uses Yaci Store + Bridge Projection rather than a generic db-sync query surface
Public network integrations Pre-production Select paths exist for public testnets and external Cardano services, but the operating model is still evolving
Mithril light client and local setup Deprecated / disabled Not maintained for new deployments; source is retained only for historical reference and type compatibility
Production deployment Not recommended This repository should be treated as pre-production software

Trust Model & Security Considerations

There are currently protocol-level constraints that prevent IBC-style state proofs of Cardano, for example UTxO inclusion proofs. A valuable conversation on that topic can be found here: CIP-0165 (Canonical Ledger State).

The Cardano-native approach uses a bespoke Single Token Thread (STT) architecture alongside the 08-cardano-probabilistic light client to attain an analogous IBC state machine in Cardano semantics. The STT architecture over the IBC host state keyspace functions as an authenticated mutex for IBC host state mutation, where each authenticated mutation is tied to a corresponding merkle root of IBC state, while the probabilistic light client authenticates accepted Cardano history through configured settlement heuristics. This model is documented more deeply at Probabilistic Light Client Design.

A Cardano state root is only accepted once enough independent stake has built blocks on top of the block that carries it. The client needs at least 24 descendant blocks, at least 5 qualifying pools, and at least 5.11% of stake from those pools, and pools registered too recently do not count toward the last two.

Blocks stacking on an anchor block while depth, pool, and stake thresholds fill

24 blocks is a minimum, not a guarantee. If most blocks come from a few large pools, or from pools registered too recently to count, depth can reach 24 before enough independent pools and stake have taken part. In this run the root is only accepted at block 30.

The same thresholds taking 30 blocks to fill because most blocks come from a few large pools and newly registered pools

The verifier checks the structure and internal consistency of submitted block witnesses, but canonical block history and epoch context currently come from configured observer data. Safety therefore depends on those data sources, tuned acceptance parameters, and an honest observer or relayer surfacing conflicting context; this is an explicit trust assumption of the current pre-production design.

The light client itself never makes a network call. The Gateway gathers everything it needs from named sources, Hermes carries it inside MsgUpdateClient, and the Go module verifies block hashes, pool signatures, VRF proofs, and leader eligibility from the submitted bytes alone. The epoch context (stake distribution and epoch nonce) is the part it takes on trust. The animation shows exactly what the Gateway and Hermes ask each service for, first to build a light-client header and then to build, check, and submit a Cardano transaction.

Hermes, the Gateway, and the Cardano data services, showing the exact call made to each service and the header or transaction field it fills

The older Mithril light client and local Mithril setup are deprecated, disabled, and not maintained. They remain in the repository only for historical design reference and protobuf/type compatibility.

Overview

The repository is organized around these main areas:

  • cardano: Cardano on-chain validators, off-chain deployment code, and the Gateway.
  • cosmos: The standalone async-ICQ host, dormant VesselOracle module, shared Cardano light-client core, ibc-go v8 and v10 adapters, and preserved deprecated Mithril module. The v8 adapter targets Cosmos SDK 0.50; the async-ICQ host, VesselOracle, v10 adapters, and Mithril module target Cosmos SDK 0.53.
  • proto-types: Shared protobuf contracts and generated TypeScript bindings, including the dormant VesselOracle integration contract.
  • relayer: A Hermes fork with a native Cardano ChainEndpoint implementation.
  • caribic: The CLI for configuring, starting, stopping, and testing the local bridge stack.
  • chains: Managed Cardano and counterparty-chain runtime configuration, including the pinned ibc-go compatibility profiles.
  • dapps: Optional swap and explorer frontends.
  • packages and proto-types: Shared application packages and generated protocol bindings.
  • docs, studies, and manifests: Design documentation, analysis, and tracked deployment artifacts.

Architecture

Architecture: users, Hermes and the Cosmos chain on top, the Cardano Gateway and Cardano data services in the middle, and the Cardano chain with its on-chain validators at the bottom

Chain history comes from Yaci Store on every network. Yaci Store is an indexer rather than a node: it follows a Cardano node and writes each block into its own Postgres database as rows of blocks, transactions, inputs, UTxOs, pool registrations, and epoch nonces. A sidecar copies the bridge's own rows into bridge_* tables, and the Gateway reads all of it with plain SQL, plus Yaci's REST API for raw block bytes. On public networks Yaci syncs from a recent checkpoint, and Blockfrost supplies older epoch and pool history.

Yaci Store following a Cardano node, writing blocks into Postgres tables, and the Gateway querying those tables with SQL

All of the bridge's IBC state lives in one Merkle tree whose root sits in the HostState datum. Cardano validators check every update to that root, the light client carries it to Cosmos in an authenticated header, and each record is then proven against it with an ICS-23 membership proof. No step relies on trusting the Gateway or Hermes.

A root update enforced by the HostState validator, authenticated by the light client, and used to prove a single record

Additional architecture diagrams:

  • Gateway escrow flow: cardano/gateway/README.md#sendpacket-escrow-flow
  • Denom trace lifecycle: docs/denom-trace-mapping.md
  • Probabilistic light client: docs/probabilistic-light-client.md
  • Deprecated Mithril proof flow: docs/mithril-light-client.md#mithril-proof-flow-for-relaying
  • Diagram index: docs/architecture-overview.md

Relayer Implementation (Hermes)

This project uses a fork of the Hermes IBC relayer with native Cardano support. The relayer is integrated as a git submodule pointing to:

Fork Repository: https://github.com/cardano-foundation/hermes-relayer Branch: main

The Cardano implementation resides in relayer/crates/relayer/src/chain/cardano/ and includes:

  • ChainEndpoint trait implementation for Cardano
  • Hermes-specific SLIP-0010 Ed25519 mnemonic derivation using a Cardano-shaped path. This is not wallet-compatible Ed25519-BIP32/CIP-1852 derivation; verify the derived address before funding it.
  • Intent-bound Cardano transaction validation and Ed25519 signing using Pallas primitives
  • Gateway gRPC client for blockchain interaction
  • Cardano-specific IBC types (Header, ClientState, ConsensusState)
  • Full async runtime integration with Hermes's message-passing architecture
  • Complete protobuf generation for Gateway Query and Msg services

Hermes Configuration

Caution

When configuring Hermes, ensure your ~/.hermes/config.toml has the correct key_store_folder path. Use absolute paths, not tilde (~) notation, as tilde expansion may not work correctly:

[[chains]]
type = 'Cardano'
id = 'cardano-devnet'
bridge_manifest_path = '/absolute/path/to/bridge-manifest.json'
key_store_folder = '/Users/yourusername/.hermes/keys'  # Absolute path required

bridge_manifest_path is required for Cardano signing. It must name the trusted local deployment manifest that corresponds to the Gateway's BRIDGE_MANIFEST_PATH; never source it from the Gateway itself. caribic start resolves the active network profile's manifest, snapshots it into the owner-only ~/.hermes/signing-security directory, and writes that snapshot path into ~/.hermes/config.toml, failing before Hermes starts if the artifact is absent. The Gateway's deployment-artifact mounts are also read-only. Restart Hermes after changing or redeploying the manifest.

Hermes also requires signing_utxo_kupo_url and signing_ogmios_url. It resolves every regular and collateral input against the configured Kupo service and evaluates the exact unsigned CBOR with the configured Ogmios service before loading the signing key. After signing, Hermes submits the exact signed envelope directly to that Ogmios endpoint; the Gateway receives only its hash so it can confirm inclusion and finalize the corresponding pending IBC-tree update. For hosted Demeter endpoints, caribic start derives these settings from the active Gateway .env profile and stores any required API-key files with owner-only permissions.

Keep the signing limits in the Cardano chain configuration at values appropriate for the funded relayer wallet. In particular, max_wallet_lovelace_top_up bounds ADA the wallet may contribute beyond the exact fee and any explicitly requested outbound lovelace transfer.

The default local Gateway URL uses plaintext on loopback. Hermes rejects plaintext connections to non-loopback Gateway hosts. Remote deployments must use https://; configure gateway_tls_ca_file for a private CA and pair gateway_auth_token_file with the Gateway's GRPC_AUTH_TOKEN_FILE when bearer authentication is enabled. An independently configured misbehaviour_witness_gateway_url follows the same rules; use its corresponding misbehaviour_witness_gateway_tls_ca_file and misbehaviour_witness_gateway_auth_token_file settings when needed.

Architecture & Design Decisions

Transaction Signing Architecture

The Hermes relayer implements Cardano transaction validation and signing using Pallas, a pure Rust library for Cardano primitives. The architecture separates transaction construction from authorization and signing:

  • Gateway (NestJS/TypeScript) builds unsigned transactions using Lucid Evolution and handles all Cardano-specific domain logic (UTxO querying, fee calculation, and proof/header preparation)
  • Hermes Relayer (Rust) derives the expected effect from the IBC message, decodes exactly one Gateway transaction, and checks it against the operator-pinned bridge manifest and configured fee, collateral, transaction-size, validity-interval, total protocol-output value, network, signer, input, output, mint, and reference-script policy before producing a signature
  • Cardano validators remain the final authority for protocol state transitions; Hermes's policy prevents its fee key from authorizing an unrelated or materially broader transaction assembled by a compromised Gateway

This separation provides:

  • Clean boundaries between chain-specific logic (Gateway) and generic IBC relaying (Hermes)
  • Native integration with Hermes's keyring system following the same pattern as Cosmos SDK chains
  • A local authorization boundary between the network-facing transaction builder and the funded signing key
  • Easier testing and maintenance of validation and cryptographic signing separate from transaction construction

The Cardano chain implementation in Hermes (relayer/crates/relayer/src/chain/cardano/) follows the same architectural patterns as other supported chains, ensuring consistent behavior across the IBC ecosystem.

Getting Started

Prerequisites

The following components are required to run the project:

Verify Prerequisites

To check Docker, Docker Compose, Python, Aiken, Deno, Go, and the Linux-native Hermes build toolchain when applicable:

cd caribic
cargo run check

The command does not currently validate Node.js or Rust/Cargo; verify those separately with node --version and cargo --version.

OS and Architecture Considerations

This project uses Docker containers that require platform-specific images depending on your operating system and CPU architecture. Some Docker images (such as Kupo) support multiple architectures (AMD64/x86_64 and ARM64), but Docker may not automatically select the correct one.

If you encounter issues with containers crashing immediately or OOM (Out-Of-Memory) errors, you may need to explicitly specify the platform in the Docker Compose configuration:

  • ARM64 (Apple Silicon, M1/M2/M3 Macs): Ensure images specify platform: linux/arm64
  • AMD64/x86_64 (Intel/AMD processors): Use platform: linux/amd64 or omit the platform (defaults to AMD64)

Local Cardano images are pinned in chains/cardano/devkit/Dockerfile and chains/cardano/devkit/compose.yaml.

Running a local Cardano network

Local Cardano uses Yaci DevKit. See the Caribic guide for migration, startup timing and current limitations.

Warning

Mithril setup is deprecated, disabled, and not maintained. Do not use caribic start --with-mithril or caribic start mithril for new deployments. The Mithril sources and compose files remain only for historical reference and compatibility with old types.

Before using the CLI, build and install caribic locally:

cd caribic
cargo install --path . --force
cd ..

To start the managed local Cardano devnet together with the bridge components, run:

caribic start --clean

If you need to start components separately, use:

caribic start network
caribic start bridge

Testing against Cosmos chains

Important

Cosmos chains must explicitly support the Cardano light client and allow it via ibc.core.client.v1.Params.allowed_clients (e.g., 08-cardano-probabilistic). If the client type is not registered/allowed on the Cosmos chain, creating the counterparty client will fail and IBC connection/channel handshakes cannot proceed. Also ensure the relayer key on those chains is funded; Cosmos SDK accounts can return NotFound until they receive tokens.

Three reproducible local profiles are available through the cosmos chain adapter:

Profile Chain ID Semantics Current compatibility testing
v8-classic v8-classic-1 IBC Classic Enabled
v10-classic v10-classic-1 IBC Classic Waiting for local clock integration
v10-v2 v10-v2-1 IBC v2 Deferred

Here, Classic identifies the IBC v1 and ICS-20 v1 workflow, not identical packet bytes or ibc-go integration APIs. The v8 and v10 Classic profiles exercise the same protocol flow while exposing version-specific APIs and JSON packet encoding. See Classic compatibility across v8 and v10 for the relevant JSON ordering and protobuf namespace differences.

Select any lifecycle profile explicitly:

caribic chain start --chain cosmos --network v8-classic
caribic chain health --chain cosmos --network v8-classic
caribic chain stop --chain cosmos --network v8-classic

See Local Cosmos compatibility profiles for pinned commits, endpoints, deterministic accounts, and direct Docker commands.

Stopping the services

To stop the services:

caribic stop

Demo: Direct Cosmos Routes

Local and public-testnet flows use direct Cardano-to-target routes.

Direct routes require explicit target-chain support:

  • The target Cosmos chain must compile and register the Cardano light client module, and allow the relevant client type in IBC client parameters.
  • Cardano must support the target chain client type, usually Tendermint/CometBFT for Cosmos SDK chains.
  • Operators must create direct Cardano clients, connections, and channels for each target chain.
  • ICQ flows require the target chain to enable the relevant ICQ host/query module.

The migrated local network currently pairs with Cosmos v8-classic:

caribic setup route --from cardano --to cosmos --to-network v8-classic

Demo: Cross-chain token swap

Local demos currently use Cosmos v8-classic.

caribic start
caribic chain start --chain cosmos --network v8-classic
caribic setup route --from cardano --to cosmos --to-network v8-classic
caribic demo token-swap --chain cosmos --network v8-classic

Useful commands for local networks

Local account configuration

Configure funding addresses in cardano.bootstrap_addresses.

Test IBC primitives and lifecycles

For current end-to-end timeout and packet lifecycle validation, use the maintained integration suite:

caribic start --clean
caribic --verbose 5 test

Additional Resources

Troubleshooting

Cardano Node DiffusionError: Network.Socket.bind permission denied

If you encounter an error like DiffusionError Network.Socket.bind: permission denied (Operation not permitted) when starting the Cardano node, see the Cardano Forum thread on this issue.

If this doesn't resolve the issue, this is typically related to Docker runtime configuration. If using Colima on macOS, ensure you're using VirtioFS mount type by recreating Colima with colima delete followed by colima start --vm-type=vz --mount-type=virtiofs --network-address, and verify the cardano-node is configured to bind to 0.0.0.0 rather than a specific IP address.

Kudos to the Developers in the Cardano Ecosystem

This project stands on the shoulders of some incredible frameworks and tools developed by the Cardano community. Huge thanks to the developers behind these services—projects like this wouldn’t be possible without their hard work and innovation:

Contributing

All contributions are welcome! Please feel free to open a new thread on the issue tracker or submit a new pull request.

Please read Contributing in advance. Thank you for contributing!

License

This project is licensed under Apache 2.0.

Additional Documents

About

Cardano implementation of IBC v1

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

31 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages