--- title: Setup sidebar_label: Setup sidebar_position: 9 slug: /ibc/light-clients/setup --- # Setup :::note 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](../../01-ibc/02-integration.md#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 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 // 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 %s tx gov submit-proposal --from ``` where `proposal.json` contains: ```json { "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.