package keeper import ( "context" "fmt" "cosmossdk.io/collections" storetypes "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/mint/types" ) // Keeper of the mint store type Keeper struct { cdc codec.BinaryCodec storeService storetypes.KVStoreService stakingKeeper types.StakingKeeper bankKeeper types.BankKeeper feeCollectorName string // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. authority string Schema collections.Schema Params collections.Item[types.Params] Minter collections.Item[types.Minter] // mintFn is a function that encompasses all minting logic run in the x/mint begin blocker. mintFn MintFn } type InitOption func(*Keeper) // WithMintFn sets a custom minting function for the x/mint keeper. func WithMintFn(mintFn MintFn) InitOption { return func(k *Keeper) { k.mintFn = mintFn } } // NewKeeper creates a new mint Keeper instance. // // The mint keeper is always initialized with the DefaultMintFn but this can be overridden with the // WithMintFn option. func NewKeeper( cdc codec.BinaryCodec, storeService storetypes.KVStoreService, sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, feeCollectorName string, authority string, opts ...InitOption, ) Keeper { // ensure mint module account is set if addr := ak.GetModuleAddress(types.ModuleName); addr == nil { panic(fmt.Sprintf("the x/%s module account has not been set", types.ModuleName)) } sb := collections.NewSchemaBuilder(storeService) k := Keeper{ cdc: cdc, storeService: storeService, stakingKeeper: sk, bankKeeper: bk, feeCollectorName: feeCollectorName, authority: authority, Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), Minter: collections.NewItem(sb, types.MinterKey, "minter", codec.CollValue[types.Minter](cdc)), mintFn: DefaultMintFn(types.DefaultInflationCalculationFn), } schema, err := sb.Build() if err != nil { panic(err) } k.Schema = schema for _, opt := range opts { opt(&k) } return k } // GetAuthority returns the x/mint module's authority. func (k Keeper) GetAuthority() string { return k.authority } // Logger returns a module-specific logger. func (k Keeper) Logger(ctx context.Context) log.Logger { sdkCtx := sdk.UnwrapSDKContext(ctx) return sdkCtx.Logger().With("module", "x/"+types.ModuleName) } // StakingTokenSupply implements an alias call to the underlying staking keeper's // StakingTokenSupply to be used in BeginBlocker. func (k Keeper) StakingTokenSupply(ctx context.Context) (math.Int, error) { return k.stakingKeeper.StakingTokenSupply(ctx) } // BondedRatio implements an alias call to the underlying staking keeper's // BondedRatio to be used in BeginBlocker. func (k Keeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) { return k.stakingKeeper.BondedRatio(ctx) } // MintCoins implements an alias call to the underlying supply keeper's // MintCoins to be used in BeginBlocker. func (k Keeper) MintCoins(ctx context.Context, newCoins sdk.Coins) error { if newCoins.Empty() { // skip as no coins need to be minted return nil } return k.bankKeeper.MintCoins(ctx, types.ModuleName, newCoins) } // AddCollectedFees implements an alias call to the underlying supply keeper's // AddCollectedFees to be used in BeginBlocker. func (k Keeper) AddCollectedFees(ctx context.Context, fees sdk.Coins) error { return k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.feeCollectorName, fees) }