# How Starship Enables Inter-Blockchain Communication (IBC) Support

> Starship enables Inter-Blockchain Communication (IBC) support by querying on-chain state, aggregating channel data, and exposing discovery endpoints via gRPC and REST. Learn how Starship enhances Cosmos-SDK interoperability.

- Repository: [Hyperweb/starship](https://github.com/hyperweb-io/starship)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Starship enables Inter-Blockchain Communication (IBC) support by querying on-chain state from Cosmos-SDK chains, aggregating channel and connection data into protobuf models, and exposing discovery endpoints via gRPC and REST.**

The `hyperweb-io/starship` registry service acts as a central discovery hub for IBC topology. It inspects live chain states to build a unified view of cross-chain connections, making IBC path discovery programmatically accessible for developers and external services.

## Architecture of Starship IBC Discovery

Starship’s IBC support relies on a **configuration-driven relayer setup** paired with **active on-chain querying** to construct a real-time registry of inter-blockchain connections.

### Configuration-Driven Relayer Setup

The registry reads the `relayers` section of the Starship configuration to identify active IBC paths. Each relayer (such as Hermes or ts-relayer) creates the necessary IBC client, connection, and channel objects on the source chains. The registry service uses this configuration to determine which chain pairs to monitor, then queries their on-chain states directly to verify and aggregate connection metadata.

### On-Chain Data Aggregation with ChainClient

For every configured chain, the `ChainClient.GetChainInfo` method in [`starship/registry/chain.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/chain.go) (lines 10-55) performs three critical queries:

1. **Channel ports** via `Ibc_Channel` query to enumerate active channels.
2. **Connection details** via `Ibc_Connection` query (see `getConnectionClient`) to fetch connection identifiers.
3. **Counter-party chain ID** via `Ibc_ClientState` query to unpack the Tendermint client state and resolve the remote chain identifier (`getChainIdFromClient`).

The method aggregates these results into a slice of `ChainIBCInfo` structs containing local and counter-party `IBCInfo`, along with channel ordering, version, and state data. The `ChainIBCInfos` collection is then converted to protobuf format via `ToProto()` for transport.

```go
// starship/registry/chain.go
func (c *ChainClient) GetChainInfo() (ChainIBCInfos, error) {
    // …query channels, connections, client state…
    // build ChainIBCInfo structs
}

```

## Core Registry Endpoints for IBC Queries

The registry handler exposes three RPC methods that allow users to discover IBC connections at different granularity levels.

### ListIBC and ListChainIBC Handlers

Implemented in [`starship/registry/handler.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/handler.go) (lines 51-63), the `ListIBC` endpoint iterates over all configured `chainClients`, invokes `GetChainInfo` for each, and concatenates the protobuf results into a comprehensive list.

```go
// starship/registry/handler.go
func (a *AppServer) ListIBC(ctx context.Context, _ *emptypb.Empty) (*pb.ResponseListIBC, error) {
    var resData []*pb.IBCData
    for _, client := range a.chainClients {
        infos, err := client.GetChainInfo()
        if err != nil { return nil, err }
        resData = append(resData, infos.ToProto()...)
    }
    return &pb.ResponseListIBC{Data: resData}, nil
}

```

`ListChainIBC` filters this aggregation to return only connections where the specified chain participates, enabling targeted queries for specific network topologies.

### GetIBCInfo for Specific Chain Pairs

The `GetIBCInfo` handler accepts a pair of chain IDs, loads the source chain’s `ChainClient`, retrieves its full IBC list, and scans for the matching counter-party entry. When found, it returns a single `IBCData` record containing the channel ID, connection ID, client ID, and state; otherwise, it returns an error indicating no path exists between the requested chains.

## Protocol Buffer Definitions and Generated Code

The data models and service definitions reside in the `starship/proto/registry/` directory.

**`ibc.proto`** defines the core structures:
- `IBCChain`: Chain identifiers and metadata.
- `ChannelData`: Channel ID, port ID, ordering, and state.
- `IBCData`: Complete connection record linking two chains via channels and connections.

**`service.proto`** declares the RPC methods:
- `ListIBC`: `GET /ibc` – Returns all IBC connections.
- `ListChainIBC`: `GET /ibc/{chain}` – Returns connections for a specific chain.
- `GetIBCInfo`: `GET /ibc/{chain_1}/{chain_2}` – Returns details for a specific pair.

The build process generates:
- [`starship/registry/registry/service_grpc.pb.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/registry/service_grpc.pb.go): gRPC client and server interfaces.
- [`starship/registry/registry/service.pb.gw.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/registry/service.pb.gw.go): REST-gateway HTTP handlers that map the above routes to the Go methods.

## Practical Usage Examples

### Querying All IBC Connections via gRPC

Use the generated client stub from [`service_grpc.pb.go`](https://github.com/hyperweb-io/starship/blob/main/service_grpc.pb.go) (lines 139-144) to fetch the complete IBC topology:

```go
import (
    "context"
    "log"

    pb "github.com/hyperweb-io/starship/registry/registry"
    "google.golang.org/grpc"
)

func main() {
    conn, err := grpc.Dial("localhost:9090", grpc.WithInsecure())
    if err != nil { log.Fatalf("dial: %v", err) }
    defer conn.Close()

    client := pb.NewRegistryClient(conn)
    resp, err := client.ListIBC(context.Background(), &pb.Empty{})
    if err != nil { log.Fatalf("ListIBC: %v", err) }

    for _, ibc := range resp.Data {
        log.Printf("%s ↔ %s (channel %s)", ibc.Chain_1.ChainName, ibc.Chain_2.ChainName, ibc.Channels[0].ChannelId)
    }
}

```

### HTTP Requests for Chain-Specific Data

Retrieve IBC connections for a single chain using the REST gateway mapped in [`service.pb.gw.go`](https://github.com/hyperweb-io/starship/blob/main/service.pb.gw.go):

```bash
curl http://localhost:8080/ibc/osmosis-1

```

Fetch detailed connection information between two specific chains:

```bash
curl http://localhost:8080/ibc/osmosis-1/juno-2

```

The second request returns a JSON object containing the `IBCData` structure, including channel IDs, connection IDs, and client states for the Osmosis-Juno path.

## Summary

- **Starship IBC support** centers on the registry service, which queries live chain states to discover active channels and connections.
- The **`ChainClient.GetChainInfo`** method in [`chain.go`](https://github.com/hyperweb-io/starship/blob/main/chain.go) aggregates channel, connection, and client-state data into `ChainIBCInfo` structs.
- Three **gRPC/HTTP endpoints**—`ListIBC`, `ListChainIBC`, and `GetIBCInfo`—expose this data via the handlers defined in [`handler.go`](https://github.com/hyperweb-io/starship/blob/main/handler.go).
- **Protocol buffer definitions** in `ibc.proto` and `service.proto` generate type-safe Go code and REST-gateway bindings for cross-language compatibility.
- Configuration-driven relayer definitions inform the registry which chain pairs to monitor, ensuring the discovery service reflects the actual IBC topology defined in the Starship environment.

## Frequently Asked Questions

### How does Starship discover IBC connections between chains?

Starship discovers IBC connections by querying the on-chain state of each configured chain through the `ChainClient`. It inspects the IBC module’s channel, connection, and client state stores to build a complete map of active paths, then aggregates this data into the registry service.

### What endpoints are available for querying IBC data?

The registry exposes three primary endpoints: `ListIBC` returns all connections across every monitored chain; `ListChainIBC` filters results to a specific chain; and `GetIBCInfo` retrieves detailed connection metadata for a specific pair of chain IDs. These are available via both gRPC and REST.

### Which source files handle the IBC discovery logic?

The discovery logic is split between [`starship/registry/chain.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/chain.go), which contains the `GetChainInfo` method for on-chain queries, and [`starship/registry/handler.go`](https://github.com/hyperweb-io/starship/blob/main/starship/registry/handler.go), which implements the `ListIBC`, `ListChainIBC`, and `GetIBCInfo` RPC handlers. Protocol definitions live in `starship/proto/registry/ibc.proto` and `service.proto`.

### How does the registry know which chains to monitor for IBC paths?

The registry reads the `relayers` section of the Starship configuration file to identify which chains have active relayers (such as Hermes or ts-relayer) linking them. This configuration determines the set of chain clients instantiated to query for IBC state.