{"id":13566277,"url":"https://github.com/informalsystems/hermes-sdk","last_synced_at":"2025-12-30T00:22:02.710Z","repository":{"id":196513281,"uuid":"696271913","full_name":"informalsystems/hermes-sdk","owner":"informalsystems","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-12T14:06:43.000Z","size":19970,"stargazers_count":6,"open_issues_count":50,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-13T22:03:40.573Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/informalsystems.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-09-25T12:35:34.000Z","updated_at":"2024-04-22T08:33:50.635Z","dependencies_parsed_at":null,"dependency_job_id":"ecdcf361-4257-4d8a-aee8-628aefd5aaa3","html_url":"https://github.com/informalsystems/hermes-sdk","commit_stats":null,"previous_names":["informalsystems/hermes-sdk"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/informalsystems%2Fhermes-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/informalsystems%2Fhermes-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/informalsystems%2Fhermes-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/informalsystems%2Fhermes-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/informalsystems","download_url":"https://codeload.github.com/informalsystems/hermes-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247097936,"owners_count":20883125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T13:02:05.953Z","updated_at":"2025-12-30T00:22:02.671Z","avatar_url":"https://github.com/informalsystems.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Hermes SDK - Next Generation IBC Relayer Framework\n\n[![Build Status][build-image]][build-link]\n[![Apache 2.0 Licensed][license-image]][license-link]\n![Rust Stable][rustc-image]\n![Rust 1.79+][rustc-version]\n\n## Work in Progress\n\nHermes SDK is work-in-progress. At the current stage, a minimal implementation\nof Cosmos-to-Cosmos relaying has been implemented, however\n_this is not yet ready for production use_. We are also experimenting or\nactively working to support relaying for\n[Starknet](https://github.com/informalsystems/ibc-starknet) and Sovereign SDK\nat the moment.\n\nFor any questions or concerns, please open an issue in this repo, or send an email to [`hermes@informal.systems`](mailto:hermes@informal.systems).\n\n## Overview\n\nHermes SDK is a next-generation [IBC](https://www.ibcprotocol.dev/) relayer framework\nfor building high performance and modular IBC relayers. At its core, Hermes SDK makes\nuse of [_context-generic programming_](https://patterns.contextgeneric.dev/),\na new programming paradigm in Rust, to implement the IBC relayer as highly modular\ncomponents that can be customized and reused easily.\n\n### Inter-Blockchain Communication (IBC) and Relaying\n\nFor readers who are new to the project, [IBC](https://www.ibcprotocol.dev/) is a protocol\nthat enables secure communication between two blockchains in a permissionless way.\nIBC mirrors the concepts of networking protocols, with each message sent from one\nchain to another being represented as an _IBC packet_.\nAt a high level, we can think of blockchains as _pure state machines_ that have no access\nto external I/O. To facilitate communication between two blockchains, a _relayer_ is\nused to deliver the IBC packets from a _source_ chain to a _destination_ chain.\n\nWe can think of IBC relaying similar to mail delivery in the real life. Consider the\ncase which Alice wants to send a letter to Bob. She would first put her letter in\nan envelop, and write down the sender and recipient address. The letter is placed\nin a mailbox at Alice's home, which is picked up by a mailman who delivers it\nto Bob's home. In the case of IBC, Alice and Bob would be two chains A and B,\nand the mailman would be an IBC relayer. The envelop would be an IBC packet,\nand the mailboxes would be _provable storage locations_ on the respective chains.\n\nAlthough the concept of IBC relaying is relatively simple, similar to real world\nmail delivery, complexity arises when there are many packets need to be delivered.\nThere are many cross-cutting concerns in IBC relaying, including latency\n(time for a packet to be delivered), throughput (number of packets delivered per timeframe),\nreliability (failure recovery), efficiency (avoid delivering the same packet multiple times),\nand cost (batch delivery to reduce transaction cost). Instead of choosing a specific\nstrategy, Hermes SDK allows different relaying strategies to be implemented to\nbalance different trade offs.\n\n### Context-Generic Programming (CGP)\n\nHermes SDK makes heavy use of a new programming paradigm, context-generic programming,\nwhich is developed by us to implement the relayer as a collection of loosely-coupled\ncomponents. At a high level, CGP allows code to be written to be generic over a\ncontext type, i.e. the type that is used as `Self`. With that, we can easily define\nmultiple context types that re-use the same context-generic code through minimal wiring.\n\nFor readers with object-oriented programming (OOP) background, CGP shares some\nsimilarities with advanced OOP concepts, such as mixins and dependency injection.\nThe main difference is that CGP offers polymorphism at _compile time_, with no\ndynamic dispatch involved at runtime. With the use of associated types, CGP also\nallows strongly-typed relations to be established between different types, thus\nachieving type safety without any use of upcast or downcast operation.\n\nIn Hermes SDK, we make use of the [`cgp`](https://github.com/contextgeneric/cgp)\ncrate to define context-generic components. To learn more about CGP, readers are\nencouraged to read the in-progress book,\n[Context-Generic Programming Patterns](https://patterns.contextgeneric.dev/).\n\n### Heterogeneous Chain Relaying\n\nCompared to alternative IBC relayers, Hermes SDK is built with first-class\nsupport for IBC relaying between different implementations of blockchains.\nWhen IBC was first developed, the initial focus was on supporting communication\nbetween blockchains in the Cosmos ecosystem, which are implemented using\n[CometBFT](https://github.com/cometbft/cometbft) and\n[CosmosSDK](https://github.com/cosmos/cosmos-sdk).\nAs a result, many early IBC relayer implementations are strongly coupled\nwith Cosmos-specific assumptions on how the chain is implemented.\n\nAs IBC gains traction within Cosmos, the use of IBC is now expanding beyond\nthe Cosmos ecosystem, to other blockchain ecosystems such as Starknet.\nA main challenge in supporting non-Cosmos blockchains with existing IBC\nrelayers is that these blockchains may have entirely different ways of\nhow to interact with the chain, including how queries are made, how\nmessages and events are formatted, how transactions are signed and submitted,\nhow to track the consensus finality of chains, etc.\n\nTo expand beyond Cosmos, the core relaying logic of Hermes SDK is fully\nabstract, and makes no assumption about how to interact with a chain.\nAll chain types in Hermes SDK, including height, message, event,\ntransaction, and errors, are defined as _abstract_ associated types\nthat can be instantiated with any concrete chain-specific types.\nHermes SDK provides abstract interfaces such as the `MessageSender`\ntrait, with very little restriction on how chains can implement these\ninterfaces.\n\nAt the moment, we have two sub-projects that make use of Hermes SDK\nto implement Cosmos to non-Cosmos relaying for\n[Starknet](https://github.com/informalsystems/ibc-starknet) and\n[Sovereign SDK](https://github.com/informalsystems/hermes-sovereign-relayer).\n\n### Fully Abstract Core Relayer Logic\n\nThe core relaying logic of Hermes SDK is implemented in the\n[`hermes-relayer-components`](./crates/relayer/relayer-components/) crate.\nWhen inspecting the [`Cargo.toml` manifest](./crates/relayer/relayer-components/Cargo.toml),\nyou may notice that aside from the core CGP components definition, there\nis no use of any implementation-specific crates, such as `std` and `tokio`.\nThis shows that the core logic of Hermes SDK is _fully abstract_, and can be\ninstantiated with any concrete implementation.\n\nHermes SDK not only abstract over the concrete chain implementation,\nbut also everything else, including error handling, logging, and async runtime.\nThis means that one can easily build a custom IBC relayer that runs\nin restricted environment, such as on Wasm web applications, or in\nsandboxed test environments such as [Kani](https://model-checking.github.io/kani/).\n\n### Type-Safe Relaying\n\nHermes SDK makes heavy use of associated types to make use of types abstractly.\nThis allows the core relaying logic to differentiate values coming from different\nchains as different abstract types, even when they have the same underlying\nconcrete type. Because of that, we can make use of the strong type system in\nRust to ensure that the core relaying logic is implemented correctly.\n\nFor a simplified demonstraction, consider the implementation of the mailman\ndelivery example that we covered earlier. After the mailman collects Alice's\nletter, it is supposed read the recipient's address on the envelop, and deliver\nit to Bob. However, we may make a mistake in the mailman's program, and read\nthe sender's address. When using common programming techniques, such an error\nwould only be caught during runtime, when the mailman knocks Alice's door\nand try to deliver the letter she sent to Bob. But with the techniques used\nin Hermes SDK, the sender's address would have a different abstract type than\nthe recipient's address, and hence it would result in a compilation error\nin the mailman's program.\n\nThe actual logic for IBC relaying is more complicated than the simplified\nmailman delivery example, so there are many more places to potentially make\nsuch mistakes. Furthermore, it can be difficult to track where the mistake\nhappens, because errors may happen only after the mistaken value has flowed\nto other parts of the code base.\n\nBy making use of CGP and the strong type system provided by Rust, Hermes SDK\noffers unique advantage over other IBC relaying implementations that the\ncore relaying logic is not only correct _now_, but that it will always\nremain correct in the _future_. We do not need to rely on an expert developer\nto carefully audit the relayer code to ensure that it is correct. Instead,\nthe Rust compiler helps to the job, and will raise an error any time a\ndeveloper mistakenly mixes up values coming from different chains.\n\n### Context-Generic Chain Clients\n\nThe primary use case for Hermes SDK is to implement IBC relaying. But to do\nthat, we first need to implement clients for communicating with a chain\nfull node. It turns out that there are sufficiently many client-side\nfeatures required, that we have implemented fairly rich chain client libraries\nfor Hermes SDK.\n\nMost of the chain-specific client implementations in Hermes SDK are implemented\nas context-generic components. This means that one can potentially reuse some\nof the chain components to build other kinds of client-side blockchain\napplications. Compared to other chain client libraries, the chain clients\nprovided by Hermes SDK is more extensible and customizable through CGP.\n\n### Build Your Own Relayer\n\nHermes SDK provides concrete relay contexts that are ready to use, without\nrequiring the end user to understand CGP. However, the default relay context\nmay not satisfy the need for all potential use cases. For example, a chain\nmay have implemented some new features which require custom behavior from\nthe chain client.\n\nMost commonly, users would submit feature request to the relayer's project\nto add custom behavior to specific chains. However, doing so repeatedly\ncan bloat the relayer's code base, and make it more challenging to reason\nabout the special case behavior. In our case, we instead offer Hermes SDK\nas a library, which users can make use of to build their own custom relayer.\n\nWith CGP, developers can reuse chain components provided by Hermes SDK,\nwithout having to fork the entire code base. At the same time, any chain\ncomponent is fully replaceable with customized implementations.\n\n### Reproducible Test Framework\n\nHermes SDK offers a comprehensive test framework for testing the relayer.\nThe Hermes SDK IBC test suite is written as abstract tests that can work\nwith any concrete chain and relay contexts.\n\nHermes SDK also provides chain bootstrapping implementations, which would\nbootstrap new blockchain instances to be used for each test case. The\nbootstrapping helps ensure that each test is reproducible, and simplifies\nthe need to manually setup blockchain instances before running the tests.\n\n## Requirements\n\nThe crates in this project require Rust with version `1.79.0` or later.\n\n## Hermes Guide\n\nWe have a comprehensive guide at [hermes.informal.systems](http://hermes.informal.systems).\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Versioning\n\nWe follow [Semantic Versioning](https://semver.org/), though APIs are still\nunder active development.\n\n## Resources\n\n- [IBC Website](https://cosmos.network/ibc)\n- [IBC Specification](https://github.com/cosmos/ibc)\n- [IBC Modules in Go](https://github.com/cosmos/ibc-go)\n- [IBC Relayer in Typescript](https://github.com/confio/ts-relayer)\n- [IBC Relayer in Go](https://github.com/cosmos/relayer)\n\n## License\n\nCopyright © 2023 Informal Systems Inc. and Hermes authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use the files in this repository except in compliance with the License. You may obtain a copy of the License at\n\n    https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n\n[build-image]: https://github.com/informalsystems/hermes-sdk/workflows/Rust/badge.svg\n[build-link]: https://github.com/informalsystems/hermes-sdk/actions?query=workflow%3ARust\n[license-image]: https://img.shields.io/badge/license-Apache_2.0-blue.svg\n[license-link]: https://github.com/informalsystems/hermes/blob/master/LICENSE\n[rustc-image]: https://img.shields.io/badge/rustc-stable-blue.svg\n[rustc-version]: https://img.shields.io/badge/rustc-1.79+-blue.svg","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finformalsystems%2Fhermes-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finformalsystems%2Fhermes-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finformalsystems%2Fhermes-sdk/lists"}