package keeper
import (
"context"
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cybercongress/go-cyber/v7/x/tokenfactory/types"
)
type msgServer struct {
Keeper
}
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
return &msgServer{Keeper: keeper}
}
var _ types.MsgServer = msgServer{}
func (server msgServer) CreateDenom(goCtx context.Context, msg *types.MsgCreateDenom) (*types.MsgCreateDenomResponse, error) {
if err := msg.ValidateBasic(); err != nil {
return nil, err
}
ctx := sdk.UnwrapSDKContext(goCtx)
denom, err := server.Keeper.CreateDenom(ctx, msg.Sender, msg.Subdenom)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgCreateDenom,
sdk.NewAttribute(types.AttributeCreator, msg.Sender),
sdk.NewAttribute(types.AttributeNewTokenDenom, denom),
),
})
return &types.MsgCreateDenomResponse{
NewTokenDenom: denom,
}, nil
}
func (server msgServer) Mint(goCtx context.Context, msg *types.MsgMint) (*types.MsgMintResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
_, denomExists := server.bankKeeper.GetDenomMetaData(ctx, msg.Amount.Denom)
if !denomExists {
return nil, types.ErrDenomDoesNotExist.Wrapf("denom: %s", msg.Amount.Denom)
}
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
if msg.MintToAddress == "" {
msg.MintToAddress = msg.Sender
}
err = server.Keeper.mintTo(ctx, msg.Amount, msg.MintToAddress)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgMint,
sdk.NewAttribute(types.AttributeMintToAddress, msg.Sender),
sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()),
),
})
return &types.MsgMintResponse{}, nil
}
func (server msgServer) Burn(goCtx context.Context, msg *types.MsgBurn) (*types.MsgBurnResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
if msg.BurnFromAddress == "" {
msg.BurnFromAddress = msg.Sender
} else if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableBurnFrom) {
return nil, types.ErrCapabilityNotEnabled
}
err = server.Keeper.burnFrom(ctx, msg.Amount, msg.BurnFromAddress)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgBurn,
sdk.NewAttribute(types.AttributeBurnFromAddress, msg.Sender),
sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()),
),
})
return &types.MsgBurnResponse{}, nil
}
func (server msgServer) ForceTransfer(goCtx context.Context, msg *types.MsgForceTransfer) (*types.MsgForceTransferResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableForceTransfer) {
return nil, types.ErrCapabilityNotEnabled
}
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Amount.GetDenom())
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
err = server.Keeper.forceTransfer(ctx, msg.Amount, msg.TransferFromAddress, msg.TransferToAddress)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgForceTransfer,
sdk.NewAttribute(types.AttributeTransferFromAddress, msg.TransferFromAddress),
sdk.NewAttribute(types.AttributeTransferToAddress, msg.TransferToAddress),
sdk.NewAttribute(types.AttributeAmount, msg.Amount.String()),
),
})
return &types.MsgForceTransferResponse{}, nil
}
func (server msgServer) ChangeAdmin(goCtx context.Context, msg *types.MsgChangeAdmin) (*types.MsgChangeAdminResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Denom)
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
err = server.Keeper.setAdmin(ctx, msg.Denom, msg.NewAdmin)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgChangeAdmin,
sdk.NewAttribute(types.AttributeDenom, msg.GetDenom()),
sdk.NewAttribute(types.AttributeNewAdmin, msg.NewAdmin),
),
})
return &types.MsgChangeAdminResponse{}, nil
}
func (server msgServer) SetDenomMetadata(goCtx context.Context, msg *types.MsgSetDenomMetadata) (*types.MsgSetDenomMetadataResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
if !types.IsCapabilityEnabled(server.Keeper.enabledCapabilities, types.EnableSetMetadata) {
return nil, types.ErrCapabilityNotEnabled
}
err := msg.Metadata.Validate()
if err != nil {
return nil, err
}
authorityMetadata, err := server.Keeper.GetAuthorityMetadata(ctx, msg.Metadata.Base)
if err != nil {
return nil, err
}
if msg.Sender != authorityMetadata.GetAdmin() {
return nil, types.ErrUnauthorized
}
server.Keeper.bankKeeper.SetDenomMetaData(ctx, msg.Metadata)
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.TypeMsgSetDenomMetadata,
sdk.NewAttribute(types.AttributeDenom, msg.Metadata.Base),
sdk.NewAttribute(types.AttributeDenomMetadata, msg.Metadata.String()),
),
})
return &types.MsgSetDenomMetadataResponse{}, nil
}
func (server msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
if server.authority != req.Authority {
return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", server.authority, req.Authority)
}
ctx := sdk.UnwrapSDKContext(goCtx)
if err := server.SetParams(ctx, req.Params); err != nil {
return nil, err
}
return &types.MsgUpdateParamsResponse{}, nil
}