cosmos-sdk/x/nft/handler.go

158 lines
4.4 KiB
Go

package nft
import (
"fmt"
abci "github.com/tendermint/tendermint/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/nft/internal/keeper"
"github.com/cosmos/cosmos-sdk/x/nft/internal/types"
)
// GenericHandler routes the messages to the handlers
func GenericHandler(k keeper.Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case types.MsgTransferNFT:
return HandleMsgTransferNFT(ctx, msg, k)
case types.MsgEditNFTMetadata:
return HandleMsgEditNFTMetadata(ctx, msg, k)
case types.MsgMintNFT:
return HandleMsgMintNFT(ctx, msg, k)
case types.MsgBurnNFT:
return HandleMsgBurnNFT(ctx, msg, k)
default:
errMsg := fmt.Sprintf("unrecognized nft message type: %T", msg)
return sdk.ErrUnknownRequest(errMsg).Result()
}
}
}
// HandleMsgTransferNFT handler for MsgTransferNFT
func HandleMsgTransferNFT(ctx sdk.Context, msg types.MsgTransferNFT, k keeper.Keeper,
) sdk.Result {
nft, err := k.GetNFT(ctx, msg.Denom, msg.ID)
if err != nil {
return err.Result()
}
// update NFT owner
nft.SetOwner(msg.Recipient)
// update the NFT (owners are updated within the keeper)
err = k.UpdateNFT(ctx, msg.Denom, nft)
if err != nil {
return err.Result()
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeTransfer,
sdk.NewAttribute(types.AttributeKeyRecipient, msg.Recipient.String()),
sdk.NewAttribute(types.AttributeKeyDenom, msg.Denom),
sdk.NewAttribute(types.AttributeKeyNFTID, msg.ID),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
),
})
return sdk.Result{Events: ctx.EventManager().Events()}
}
// HandleMsgEditNFTMetadata handler for MsgEditNFTMetadata
func HandleMsgEditNFTMetadata(ctx sdk.Context, msg types.MsgEditNFTMetadata, k keeper.Keeper,
) sdk.Result {
nft, err := k.GetNFT(ctx, msg.Denom, msg.ID)
if err != nil {
return err.Result()
}
// update NFT
nft.EditMetadata(msg.TokenURI)
err = k.UpdateNFT(ctx, msg.Denom, nft)
if err != nil {
return err.Result()
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeEditNFTMetadata,
sdk.NewAttribute(types.AttributeKeyDenom, msg.Denom),
sdk.NewAttribute(types.AttributeKeyNFTID, msg.ID),
sdk.NewAttribute(types.AttributeKeyNFTTokenURI, msg.TokenURI),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
),
})
return sdk.Result{Events: ctx.EventManager().Events()}
}
// HandleMsgMintNFT handles MsgMintNFT
func HandleMsgMintNFT(ctx sdk.Context, msg types.MsgMintNFT, k keeper.Keeper,
) sdk.Result {
nft := types.NewBaseNFT(msg.ID, msg.Recipient, msg.TokenURI)
err := k.MintNFT(ctx, msg.Denom, &nft)
if err != nil {
return err.Result()
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeMintNFT,
sdk.NewAttribute(types.AttributeKeyRecipient, msg.Recipient.String()),
sdk.NewAttribute(types.AttributeKeyDenom, msg.Denom),
sdk.NewAttribute(types.AttributeKeyNFTID, msg.ID),
sdk.NewAttribute(types.AttributeKeyNFTTokenURI, msg.TokenURI),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
),
})
return sdk.Result{Events: ctx.EventManager().Events()}
}
// HandleMsgBurnNFT handles MsgBurnNFT
func HandleMsgBurnNFT(ctx sdk.Context, msg types.MsgBurnNFT, k keeper.Keeper,
) sdk.Result {
_, err := k.GetNFT(ctx, msg.Denom, msg.ID)
if err != nil {
return err.Result()
}
// remove NFT
err = k.DeleteNFT(ctx, msg.Denom, msg.ID)
if err != nil {
return err.Result()
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeBurnNFT,
sdk.NewAttribute(types.AttributeKeyDenom, msg.Denom),
sdk.NewAttribute(types.AttributeKeyNFTID, msg.ID),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender.String()),
),
})
return sdk.Result{Events: ctx.EventManager().Events()}
}
// EndBlocker is run at the end of the block
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
return nil
}