> ## Documentation Index
> Fetch the complete documentation index at: https://cosmos-docs-sync-security-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup

## Synopsis

Learn how to configure light client modules and create clients using core IBC and the `02-client` submodule.

A last step to finish the development of the light client, is to implement the `AppModuleBasic` interface to allow it to be added to the chain's `app.go` alongside other light client types the chain enables.

Finally, a succinct rundown is given of the remaining steps to make the light client operational, getting the light client type passed through governance and creating the clients.

## Configuring a light client module

An IBC light client module must implement the [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/main/types/module/module.go#L50) interface in order to register its concrete types against the core IBC interfaces defined in `modules/core/exported`. This is accomplished via the `RegisterInterfaces` method which provides the light client module with the opportunity to register codec types using the chain's `InterfaceRegistry`. Please refer to the [`07-tendermint` codec registration](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/light-clients/07-tendermint/codec.go#L11).

The `AppModuleBasic` interface may also be leveraged to install custom CLI handlers for light client module users. Light client modules can safely no-op for interface methods which it does not wish to implement.

Please refer to the [core IBC documentation](/ibc/next/ibc/integration#integrating-light-clients) for how to configure additional light client modules alongside `07-tendermint` in `app.go`.

See below for an example of the `07-tendermint` implementation of `AppModuleBasic`.

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
var _ module.AppModuleBasic = AppModuleBasic{
}

/ AppModuleBasic defines the basic application module used by the tendermint light client.
/ Only the RegisterInterfaces function needs to be implemented. All other function perform
/ a no-op.
type AppModuleBasic struct{
}

/ Name returns the tendermint module name.
func (AppModuleBasic)

Name()

string {
    return ModuleName
}

/ RegisterLegacyAminoCodec performs a no-op. The Tendermint client does not support amino.
func (AppModuleBasic)

RegisterLegacyAminoCodec(*codec.LegacyAmino) {
}

/ RegisterInterfaces registers module concrete types into protobuf Any. This allows core IBC
/ to unmarshal tendermint light client types.
func (AppModuleBasic)

RegisterInterfaces(registry codectypes.InterfaceRegistry) {
    RegisterInterfaces(registry)
}

/ DefaultGenesis performs a no-op. Genesis is not supported for the tendermint light client.
func (AppModuleBasic)

DefaultGenesis(cdc codec.JSONCodec)

json.RawMessage {
    return nil
}

/ ValidateGenesis performs a no-op. Genesis is not supported for the tendermint light client.
func (AppModuleBasic)

ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage)

error {
    return nil
}

/ RegisterGRPCGatewayRoutes performs a no-op.
func (AppModuleBasic)

RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
}

/ GetTxCmd performs a no-op. Please see the 02-client cli commands.
func (AppModuleBasic)

GetTxCmd() *cobra.Command {
    return nil
}

/ GetQueryCmd performs a no-op. Please see the 02-client cli commands.
func (AppModuleBasic)

GetQueryCmd() *cobra.Command {
    return nil
}
```

## Creating clients

A client is created by executing a new `MsgCreateClient` transaction composed with a valid `ClientState` and initial `ConsensusState` encoded as protobuf `Any`s.
Generally, this is performed by an off-chain process known as an [IBC relayer](https://github.com/cosmos/ibc/tree/main/spec/relayer/ics-018-relayer-algorithms) however, this is not a strict requirement.

See below for a list of IBC relayer implementations:

* [cosmos/relayer](https://github.com/cosmos/relayer)
* [informalsystems/hermes](https://github.com/informalsystems/hermes)
* [confio/ts-relayer](https://github.com/confio/ts-relayer)

Stateless checks are performed within the [`ValidateBasic`](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/types/msgs.go#L48) method of `MsgCreateClient`.

```protobuf expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
/ MsgCreateClient defines a message to create an IBC client
message MsgCreateClient {
  option (gogoproto.goproto_getters) = false;

  / light client state
  google.protobuf.Any client_state = 1 [(gogoproto.moretags) = "yaml:\"client_state\""];
  / consensus state associated with the client that corresponds to a given
  / height.
  google.protobuf.Any consensus_state = 2 [(gogoproto.moretags) = "yaml:\"consensus_state\""];
  / signer address
  string signer = 3;
}
```

Leveraging protobuf `Any` encoding allows core IBC to [unpack](https://github.com/cosmos/ibc-go/blob/47162061bcbfe74df791161059715a635e31c604/modules/core/keeper/msg_server.go#L38) the `ClientState` into its respective interface type registered previously using the light client module's `RegisterInterfaces` method.

Within the `02-client` submodule, the [`ClientState` is then initialized](https://github.com/cosmos/ibc-go/blob/47162061bcbfe74df791161059715a635e31c604/modules/core/02-client/keeper/client.go#L40-L42) with its own isolated key-value store, namespaced using a unique client identifier.

In order to successfully create an IBC client using a new client type, it [must be supported](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/02-client/keeper/client.go#L19-L25). Light client support in IBC is gated by on-chain governance. The allow list may be updated by submitting a new governance proposal to update the `02-client` parameter `AllowedClients`.

See below for example:

```shell theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
%s tx gov submit-proposal <path/to/proposal.json> --from <key_or_address>
```

where `proposal.json` contains:

```json expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
{
  "title": "IBC Clients Param Change",
  "summary": "Update allowed clients",
  "messages": [
    {
  "@type": "/ibc.core.client.v1.MsgUpdateParams",
  "signer": "cosmos1...", / The gov module account address
      "params": {
  "allowed_clients": ["06-solomachine",
  "07-tendermint",
  "0x-new-client"]
      }
    }
  ],
  "metadata": "AQ==",
  "deposit": "100stake"
}
```

If the `AllowedClients` list contains a single element that is equal to the wildcard `"*"`, then all client types are allowed and it is thus not necessary to submit a governance proposal to update the parameter.
