Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add batch operation for x/nft module #12187

Merged
merged 15 commits into from
Jun 15, 2022
107 changes: 107 additions & 0 deletions x/nft/keeper/nft_batch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/nft"
)

// BatchMint defines a method for minting a batch of nfts
func (k Keeper) BatchMint(ctx sdk.Context,
tokens []nft.NFT,
receiver sdk.AccAddress,
) error {
classIDs := make(map[string]bool, len(tokens))
for _, token := range tokens {
if !classIDs[token.ClassId] && !k.HasClass(ctx, token.ClassId) {
return sdkerrors.Wrap(nft.ErrClassNotExists, token.ClassId)
}

if k.HasNFT(ctx, token.ClassId, token.Id) {
return sdkerrors.Wrap(nft.ErrNFTExists, token.Id)
}

julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
k.setNFT(ctx, token)
k.setOwner(ctx, token.ClassId, token.Id, receiver)
k.incrTotalSupply(ctx, token.ClassId)

ctx.EventManager().EmitTypedEvent(&nft.EventMint{
ClassId: token.ClassId,
Id: token.Id,
Owner: receiver.String(),
})
classIDs[token.ClassId] = true
}
return nil
}

// BatchBurn defines a method for burning a batch of nfts from a specific classID.
// Note: When the upper module uses this method, it needs to authenticate nft
func (k Keeper) BatchBurn(ctx sdk.Context, classID string, nftIDs []string) error {
if !k.HasClass(ctx, classID) {
return sdkerrors.Wrap(nft.ErrClassNotExists, classID)
}

for _, nftID := range nftIDs {
if !k.HasNFT(ctx, classID, nftID) {
return sdkerrors.Wrap(nft.ErrNFTNotExists, nftID)
}

owner := k.GetOwner(ctx, classID, nftID)
nftStore := k.getNFTStore(ctx, classID)
nftStore.Delete([]byte(nftID))

k.deleteOwner(ctx, classID, nftID, owner)
ctx.EventManager().EmitTypedEvent(&nft.EventBurn{
ClassId: classID,
Id: nftID,
Owner: owner.String(),
})
}
k.updateTotalSupply(
ctx,
classID,
k.GetTotalSupply(ctx, classID)-uint64(len(nftIDs)),
)
return nil
}

// BatchUpdate defines a method for updating a batch of exist nfts
// Note: When the upper module uses this method, it needs to authenticate nft
func (k Keeper) BatchUpdate(ctx sdk.Context, tokens []nft.NFT) error {
classIDs := make(map[string]bool, len(tokens))
for _, token := range tokens {
if !classIDs[token.ClassId] && !k.HasClass(ctx, token.ClassId) {
return sdkerrors.Wrap(nft.ErrClassNotExists, token.ClassId)
}

if !k.HasNFT(ctx, token.ClassId, token.Id) {
return sdkerrors.Wrap(nft.ErrNFTNotExists, token.Id)
}
k.setNFT(ctx, token)
}
return nil
}

// BatchTransfer defines a method for sending a batch of nfts from one account to another account from a specific classID.
// Note: When the upper module uses this method, it needs to authenticate nft
func (k Keeper) BatchTransfer(ctx sdk.Context,
classID string,
nftIDs []string,
receiver sdk.AccAddress,
) error {
if !k.HasClass(ctx, classID) {
return sdkerrors.Wrap(nft.ErrClassNotExists, classID)
}

for _, nftID := range nftIDs {
if !k.HasNFT(ctx, classID, nftID) {
return sdkerrors.Wrap(nft.ErrNFTNotExists, nftID)
}

owner := k.GetOwner(ctx, classID, nftID)
k.deleteOwner(ctx, classID, nftID, owner)
k.setOwner(ctx, classID, nftID, receiver)
}
return nil
}
Loading