
Cosmos
- 4 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Develop Cosmos SDK modules: keepers, Msg/Query services, genesis, app wiring with depinject, and upgrade migrations.
About
A reference for building application-specific blockchains with the Cosmos SDK, covering module structure, state via keepers, and the app lifecycle. A developer uses it when implementing or wiring SDK modules, services, and migrations.
- Module components, keepers, and Protobuf/gRPC Msg/Query services
- Genesis, BeginBlock/EndBlock, depinject wiring, and upgrade migrations
Cosmos by the numbers
- 4 all-time installs (skills.sh)
- Ranked #347 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill cosmosAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Develop Cosmos SDK modules: keepers, Msg/Query services, genesis, app wiring with depinject, and upgrade migrations.
Files
Skill based on Cosmos SDK, generated fromsources/cosmos. Doc path:sources/cosmos/docs/docs/,sources/cosmos/README.md, andsources/cosmos/x/.
The Cosmos SDK is a modular framework for building application-specific blockchains. Applications are composed of modules that own state (via keepers), expose Msg and Query services (Protobuf/gRPC), and plug into the app lifecycle (genesis, BeginBlock, EndBlock, upgrades). Use this skill when implementing or wiring SDK modules, keepers, services, depinject, or migrations.
Core References
| Topic | Description | Reference |
|---|---|---|
| Modules intro | Role of modules, main components, composability and capabilities | core-modules-intro |
| Module manager | AppModule interfaces, BasicManager, Manager, execution order | core-module-manager |
| Messages and queries | Msg/Query types, gRPC services, legacy paths, protobuf | core-messages-queries |
| Keeper | Type definition, store access, inter-module access, methods | core-keeper |
| Genesis | GenesisState, DefaultGenesis, ValidateGenesis, Init/ExportGenesis | core-genesis |
| App anatomy | App type, constructor, InitChainer, PreBlocker, Begin/EndBlocker | core-app-anatomy |
| BaseApp and store | ABCI, routers, volatile states; multistore, KVStore, IAVL | core-baseapp-store |
Features
| Topic | Description | Reference |
|---|---|---|
| Msg services | Implementing Msg service, validation, state transition, events | features-msg-services |
| Query services | gRPC Query implementation, module_query_safe | features-query-services |
| depinject | Module config proto, ProvideModule, app wiring | features-depinject |
| Upgrades | ConsensusVersion, in-place migrations, RegisterMigration | features-upgrade |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Errors | Registration, wrapping, ABCI helpers | best-practices-errors |
| Module structure | Recommended folder and file layout | best-practices-module-structure |
Generation Info
- Source:
sources/cosmos - Git SHA:
3067281a7f07871745e893376fcc243815a14189 - Generated: 2026-02-24
Error Handling
Modules should define and register their own errors so failed messages or handlers return clear, identifiable errors. Use the SDK errors package for registration and ABCI mapping.
Registration
Define and register errors in x/{module}/errors.go (or types/errors.go). Each error has:
- Codespace: Usually the module name (e.g.
"distribution"), unique per module. - Code:
uint32, unique within the module. Must be > 1 (1 is reserved for internal errors).
Example pattern:
var (
ErrInvalidRequest = sdkerrors.Register(ModuleName, 2, "invalid request")
ErrSomeCondition = sdkerrors.Register(ModuleName, 3, "description")
)The SDK also provides common errors in types/errors/errors.go; use or wrap them when appropriate.
Wrapping
Return registered errors as-is or wrap them for extra context:
return sdkerrors.Wrap(ErrInvalidRequest, "from_address is empty")Use errors.Is(err, ErrInvalidRequest) to check the error kind regardless of wrapping.
ABCI
Registered errors can be mapped to ABCI info via the errors package (e.g. ABCIInfo). Helpers like ResponseCheckTxWithEvents, ResponseExecTxResultWithEvents, and QueryResult build CheckTx, ExecTxResult, and ResponseQuery from errors in the ABCI++ model.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/12-errors.md
-->
Recommended Module Structure
Suggested layout for a Cosmos SDK module. Treat as guidance; adapt to your project.
Proto
Under proto/{project}/{module}/{version}/:
{module}.proto: Shared message types.event.proto: Event types.genesis.proto: Genesis state.query.proto: Query service and request/response types.tx.proto: Msg service and request/response types.
Go layout (x/{module})
- client/cli:
query.go,tx.gofor CLI commands;testutil/for CLI tests. - exported/: Exported types used in expected keeper interfaces to avoid import cycles and keep contracts canonical.
- keeper/:
keeper.go,msg_server.go,grpc_query.go,genesis.go,keys.go,invariants.go,querier.go(legacy),hooks.goif needed. - module/:
module.go(AppModule, AppModuleBasic);abci.gofor BeginBlocker/EndBlocker;autocli.gofor autocli options. - simulation/:
decoder.go,genesis.go,operations.go,params.gofor simapp. - Root:
codec.go,errors.go,events.go,expected_keepers.go,genesis.go,keys.go,msgs.go,params.go, plus generated*.pb.go.README.mdfor spec and concepts.
Key files
- expected_keepers.go: Interfaces for other modules' keepers this module depends on.
- errors.go: Sentinel errors registered with the SDK errors package.
- events.go: Event types and constructors (and generated
events.pb.go).
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/11-structure.md
-->
Anatomy of a Cosmos SDK Application
The full-node binary (e.g. appd) runs the state machine. The core is defined in app.go: app type, constructor, and lifecycle hooks.
App Type
- Embed runtime.App (wraps BaseApp and module manager). Runtime configures modules via dependency injection and app wiring.
- App wiring: Config file (e.g.
app_config.go/app.yaml) lists modules and orders for InitGenesis, Pre/Begin/EndBlocker, etc. - appCodec: Default is Protobuf; used to serialize/deserialize state.
- legacyAmino: Still referenced where not yet migrated; avoid for new code.
Constructor
- Build codec and register module codecs (BasicManager).
- Create app with BaseApp, codec, store keys.
- Instantiate keepers (order matters: dependencies first).
- Build module manager with all AppModules; set InitGenesis, PreBlocker, BeginBlocker, EndBlocker orders.
- Register Msg services, gRPC Query services, legacy routes; register invariants.
- Set InitChainer, PreBlocker, BeginBlocker, EndBlocker, AnteHandler.
- Mount stores and return the app.
State is loaded from ~/.app/data on restart or from genesis on first start.
Lifecycle Hooks
- InitChainer: Runs on
InitChain(height 0). Calls module manager'sInitGenesisin configured order. Set viaSetInitChainer. - PreBlocker: Runs before BeginBlock; can change consensus params; if it returns
ConsensusParamsChanged=true, the caller must refresh consensus params in the finalize context. - BeginBlocker / EndBlocker: Run at block start/end. Composed of each module's BeginBlock/EndBlock in manager order. Set via
SetBeginBlocker/SetEndBlocker. Keep logic deterministic and cheap (no gas limit here).
EncodingConfig
Holds InterfaceRegistry, Codec, TxConfig, and Amino. Used for (de)serialization and tx handling (e.g. SIGN_MODE_DIRECT, SIGN_MODE_LEGACY_AMINO_JSON).
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/beginner/00-app-anatomy.md
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-apps/00-runtime.md
-->
BaseApp and Store
BaseApp
BaseApp implements the ABCI and routing layer:
- ABCI: CheckTx, FinalizeBlock, Commit, InitChain, PrepareProposal, ProcessProposal. CometBFT sends transaction bytes; BaseApp decodes, validates, routes messages, and returns results.
- Msg service router: Routes
sdk.Msgbytype_urlto module Msg services. - gRPC query router: Routes gRPC queries to module Query services.
- AnteHandler: Signature verification, fees, pre-message checks (CheckTx and FinalizeBlock).
- Volatile states:
checkState(CheckTx),finalizeBlockState(FinalizeBlock),prepareProposalState,processProposalState. Only the commit store is persisted; others are cached/branched and reset or re-initialized on Commit.
Apps extend BaseApp (usually via runtime.App) and set InitChainer, PreBlocker, BeginBlocker, EndBlocker, AnteHandler.
Store
- Multistore: Root store is a store of KVStores. Each module gets one or more stores identified by a key held only by that module's keeper.
- KVStore / CommitKVStore: Key-value interface; CommitKVStore can commit. Modules use KVStore (no commit capability) from context. Default implementation: IAVL store (versioned, O(log n) get/set, iterable).
- Wrappers:
CacheKVStore(branch/cache for revertible writes),GasKv(gas on read/write),Prefix(key prefixing),TraceKv,ListenKv. Transient stores are discarded at end of block. - Context:
ctx.KVStore(storeKey)returns the module's KVStore (gas-wrapped). Branching the multistore gives isolated state for a block or transaction.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/advanced/00-baseapp.md
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/advanced/04-store.md
-->
Module Genesis
Modules that own state define their genesis subset: a GenesisState type and methods to default, validate, initialize, and export it.
GenesisState
Define in genesis.proto; the struct holds all module values needed at chain init. Commonly named GenesisState.
Methods
- DefaultGenesis: Returns default
GenesisState(e.g. for tests). Part ofHasGenesisBasics/ genesis interfaces. - ValidateGenesis: Validates raw genesis JSON; unmarshal then run module-specific checks. Called before init.
- InitGenesis: Runs on
InitChainwhen the app starts from genesis. Receives the module'sGenesisState; uses the keeper to set initial state. Order is set via the module manager'sSetOrderInitGenesis(respect dependencies, e.g. genutil after staking, capability before others). - ExportGenesis: Builds
GenesisStatefrom current state; used for exports and hard-fork upgrades. Order viaSetOrderExportGenesis.
GenesisTxHandler
Modules can submit state transitions before the first block via GenesisTxHandler. Used by x/genutil for validator genesis txs.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/08-genesis.md
-->
Keepers
A keeper is the gatekeeper of a module's store(s). It holds the store key(s) and defines the only way to read/write that subset of state. This supports the object-capabilities model: access is by holding a reference to the keeper, not by permission lists.
Type Definition
Typically in x/{module}/keeper/keeper.go:
type Keeper struct {
// External keepers (interfaces from expected_keepers.go)
// storeKey(s)
// codec (BinaryCodec/JSONCodec/Codec)
// authority (module or account that can change params)
}- External keepers: Other modules' keepers required by this module, declared as interfaces in
expected_keepers.go. - storeKey: Grants access to the module's KVStore(s) in the multistore. Never expose to other modules.
- codec: For marshalling/unmarshalling state (stores persist
[]byte). - authority: Account or module allowed to change module parameters (replaces deprecated params module).
NewKeeper is called from the app constructor; pass store keys, codec, and any required keeper references in dependency order.
Methods
Keepers expose getters and setters. Validation should be done in the Msg server; keeper methods stay simple.
- Getter: Get store from
ctxwithstoreKey, optionally useprefix.Storefor a key subset,Get(key), unmarshal with codec, return. - Setter: Get store, marshal value,
Set(key, value). - Use
Iterator(start, end)for range iteration (e.g. accounts, balances).
Only the keeper should hold the key to its store(s). To let another module access your state, pass it a reference to your keeper so it uses your exported methods.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/06-keeper.md
-->
Messages and Queries
Messages trigger state transitions; queries read state. They are the main objects modules handle via Msg services and Query services.
Messages
- Defined in Protobuf; each module has a Msg service (e.g. in
tx.proto) with one RPC per message type. - Each RPC has one request type (must implement
sdk.Msg) and one response type. Naming:Msg<Name>,Msg<Name>Response. sdk.Msgis an alias ofproto.Message. Signers are usually specified viacosmos.msg.v1.signerprotobuf option; for custom signers usesigning.CustomGetSignerand provide via depinject.- BaseApp decodes the tx, runs AnteHandler, then routes each message by
type_urlto the module's Msg service viaMsgServiceRouter. - Register the Msg service in the module's
RegisterServiceswith the generatedRegisterMsgServer; register the service descriptor inRegisterInterfaceswithRegisterMsgServiceDesc.
Queries
- gRPC: Define a
Queryservice inquery.proto. Implement the generatedQueryServerin the keeper (e.g.keeper/grpc_query.go). Usesdk.UnwrapSDKContext(ctx)to getsdk.Contextin handlers. Register withRegisterQueryServerinRegisterServices. - Legacy: Path format
queryCategory/queryRoute/queryType/arg1/arg2/.... Implement a querier and CLI query commands that build this path. - Store queries: Use
clientCtx.QueryABCI(req)for direct store queries with Merkle proofs.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/02-messages-and-queries.md
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/05-protobuf-annotations.md
-->
Module Manager
Modules implement AppModule (and related interfaces) so the application's module manager can manage them. The manager drives message/query routing and the order of PreBlocker, BeginBlocker, EndBlocker, InitGenesis, etc.
Application Module Interfaces
Prefer the Core API appmodule package for new modules (less SDK coupling). Legacy: module package.
- AppModuleBasic (legacy): Stateless/independent methods (codec, interfaces, gRPC gateway). Use
module.CoreAppModuleBasicAdaptorfor new modules. Managed by BasicManager. - AppModule: Stateful and inter-module methods. Implement extension interfaces only for what the module needs (e.g. HasBeginBlocker, HasEndBlocker, HasServices, HasGenesis).
Key extension interfaces:
HasGenesis/HasABCIGenesis: Genesis init/export.HasPreBlocker,HasBeginBlocker,HasEndBlocker: Block lifecycle.HasPrecommit,HasPrepareCheckState: Commit-phase hooks.HasServices: Register gRPC Msg/Query services.HasInvariants(legacy): Register invariants.HasConsensusVersion: For upgrades.
BasicManager
Holds all AppModuleBasic. Methods: RegisterLegacyAminoCodec, RegisterInterfaces, DefaultGenesis, ValidateGenesis, RegisterGRPCGatewayRoutes, AddTxCommands, AddQueryCommands. Built in init() or app constructor.
Manager
Holds all AppModule and defines execution order:
SetOrderInitGenesis,SetOrderExportGenesis: Genesis order (respect module dependencies, e.g. genutil after staking).SetOrderPreBlockers,SetOrderBeginBlockers,SetOrderEndBlockers: Block lifecycle order.SetOrderPrecommiters,SetOrderPrepareCheckStaters: Commit-phase order.SetOrderMigrations: Upgrade migration order.
Other methods: RegisterInvariants, RegisterServices, InitGenesis, ExportGenesis, BeginBlock, EndBlock, Precommit, PrepareCheckState.
Implement interfaces in ./x/{module}/module.go; the concrete type often embeds the keeper and AppModuleBasic.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/01-module-manager.md
-->
Cosmos SDK Modules Introduction
Modules implement most of an application's logic. Developers compose modules to build application-specific blockchains. The SDK core provides ABCI boilerplate, multistore, server, and interfaces; modules implement business logic and state.
Main Components
- Keeper: Manages access to the module's store(s) and state. Only the keeper holds the store key(s).
- Msg service: Protobuf service that processes messages when BaseApp routes them to the module. Triggers state transitions.
- Query service: Processes queries routed by BaseApp; exposes the module's state subset.
- AppModule / AppModuleBasic: Implemented in
module.goso the module can be managed by the module manager.
Modules live by convention in ./x/{module_name}/. They define a subset of state (one or more KVStores) and a subset of message types.
Design Principles
- Composability: Integrate with SDK core and other modules. Expose store access only via the keeper.
- Specialization: One concern per module; avoid batching unrelated functionality. Enables reuse and upgrades.
- Capabilities: Access to another module's store is by passing a reference to that module's keeper (object-capabilities model). The keeper defines how and under what conditions its store is accessed.
Flow
Transaction → BaseApp decodes and routes messages → Message routed to module's Msg service → Module handles message and updates state → Result returned to consensus engine.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/00-intro.md
- https://docs.cosmos.network/
-->
Modules and depinject
depinject wires modules in app.go. To be depinject-ready a module must declare its configuration and dependencies; the app then configures and injects the module without manual keeper ordering.
Module configuration
Define configuration in Protobuf at {moduleName}/module/v1/module.proto:
go_importmust point to the module's Go package.- Message fields define options (e.g.
max_metadata_len). These are set inapp_config.goorapp.yamlby the chain developer.
Run codegen (make proto-gen); the config type is used when wiring.
Dependency definition (module.go)
1. In init(), register the module config type and wiring with depinject. 2. Implement appmodule.AppModule. 3. Define a depinject.In struct with the module's required inputs (other keepers, config, store keys, etc.). Use optional:"true" for optional deps. 4. Define a depinject.Out struct with outputs (e.g. the module and its keeper). 5. Implement ProvideModule: accept the In struct, instantiate keeper and module, return the Out struct. Return a type that implements cosmossdk.io/core/appmodule.AppModule and the needed extension interfaces.
All types and fields used in In/Out must be exported so depinject can reflect on them.
App integration
Chain developers list the module in the app wiring config (app_config.go / app.yaml) and ensure the module is included in the depinject graph (e.g. via RegisterModules or config-driven discovery). No manual keeper construction is needed for the module's own keeper and dependencies.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/15-depinject.md
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-apps/01-app-go-di.md
-->
Msg Services
Each module implements a Protobuf Msg service that processes sdk.Msg requests. BaseApp routes messages to the correct module's Msg service during FinalizeBlock (DeliverTx).
Implementation
- Define the service in
tx.proto; Protobuf generates aMsgServerinterface. Implement it on the keeper or amsgServerstruct that embeds the keeper (e.g.keeper/msg_server.go). - Get
sdk.Contextfrom the handler'scontext.Contextwithsdk.UnwrapSDKContext(ctx). - Register the implementation in
RegisterServiceswith the generatedRegisterMsgServer.
Handler Steps
1. Validation: Perform all stateful and stateless checks. The signer is charged gas. Prefer a separate validation function that takes state as arguments for testability. Do not rely on deprecated ValidateBasic for full validation.
2. State transition: Use keeper getters/setters to apply the transition.
3. Events: Emit events before returning:
ctx.EventManager().EmitTypedEvent(&module.EventXYZ{...})(protobuf-based), orctx.EventManager().EmitEvent(sdk.NewEvent(type, sdk.NewAttribute(k, v), ...)).
Return value and error are wrapped with sdk.WrapServiceResult(ctx, res, err), which marshals the response and attaches events.
Telemetry
You can record metrics from msg server methods (e.g. vesting events) for observability.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/03-msg-services.md
-->
Query Services
Modules expose gRPC Query services defined in query.proto. BaseApp routes queries to the module's Query service. Implement the generated QueryServer interface on the keeper (e.g. in keeper/grpc_query.go).
Implementation
- Each RPC in the Query service becomes a method on
QueryServer. First parameter iscontext.Context; usesdk.UnwrapSDKContext(ctx)to getsdk.Contextfor store access. - Register the implementation in
RegisterServiceswith the generatedRegisterQueryServer. - Wire gRPC-gateway routes in
RegisterGRPCGatewayRouteson AppModuleBasic so REST clients can call the same endpoints.
Module-query-safe
The cosmos.query.v1.module_query_safe Protobuf option marks a query as safe to call from inside the state machine (e.g. from another keeper, ADR-033, or CosmWasm). When set to true:
- The query must be deterministic (same height → same response) and not introduce state-machine-breaking changes across patch versions.
- Gas must be tracked so high-computation queries cannot be used without gas accounting.
Use this only for queries that meet these guarantees; otherwise do not mark them module_query_safe.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/04-query-services.md
-->
Upgrading Modules
In-place store migrations let modules upgrade to new versions with breaking state changes. Each module declares a consensus version and registers migration handlers for version bumps.
ConsensusVersion
- Implement
ConsensusVersion() uint64on AppModule. Start at 1; increment when the module introduces breaking state or logic changes. - Versions are hard-coded by the module developer.
Registering migrations
In RegisterServices, use the Configurator to register migrations:
cfg.RegisterMigration(types.ModuleName, fromVersion, func(ctx sdk.Context) error {
// Migrate store from fromVersion to fromVersion+1.
return nil
})- Register one migration per version step (e.g. 1→2, 2→3). If a version bump has no store changes, register a no-op.
- If a migration is missing for a version,
RunMigrationscan panic during upgrade.
Migration scripts
- Put migration logic in a
migrations/package (e.g.x/bank/migrations/v2). Use a Migrator type that holds the keeper (or store service and codec) so the migration function can access the store. - In
RegisterServices, call into the migration package, e.g.v2.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc).
Example: bank's migration from version 1 to 2 updated balance key format (e.g. per ADR-028). Implement similar functions for key layout or schema changes.
<!-- Source references:
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-modules/13-upgrade.md
- https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/advanced/15-upgrade.md
-->