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

Enhance nft module #189

Merged
merged 17 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions modules/nft/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,17 @@ func (s *IntegrationTestSuite) TestNft() {
denomName := "name"
denom := "denom"
schema := "schema"
symbol := "symbol"
mintRestricted := true
updateRestricted := false

//------test GetCmdIssueDenom()-------------
args := []string{
fmt.Sprintf("--%s=%s", nftcli.FlagDenomName, denomName),
fmt.Sprintf("--%s=%s", nftcli.FlagSchema, schema),
fmt.Sprintf("--%s=%s", nftcli.FlagSymbol, symbol),
fmt.Sprintf("--%s=%t", nftcli.FlagMintRestricted, mintRestricted),
fmt.Sprintf("--%s=%t", nftcli.FlagUpdateRestricted, updateRestricted),

fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
Expand All @@ -94,6 +100,9 @@ func (s *IntegrationTestSuite) TestNft() {
denomItem := respType.(*nfttypes.Denom)
s.Require().Equal(denomName, denomItem.Name)
s.Require().Equal(schema, denomItem.Schema)
s.Require().Equal(symbol, denomItem.Symbol)
s.Require().Equal(mintRestricted, denomItem.MintRestricted)
s.Require().Equal(updateRestricted, denomItem.UpdateRestricted)

//------test GetCmdQueryDenoms()-------------
respType = proto.Message(&nfttypes.QueryDenomsResponse{})
Expand Down Expand Up @@ -271,4 +280,31 @@ func (s *IntegrationTestSuite) TestNft() {
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), respType))
supplyResp = respType.(*nfttypes.QuerySupplyResponse)
s.Require().Equal(uint64(1), supplyResp.Amount)

//------test GetCmdTransferDenom()-------------
args = []string{
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
}

respType = proto.Message(&sdk.TxResponse{})

bz, err = nfttestutil.TransferDenomExec(val.ClientCtx, from.String(), val2.Address.String(), denomID, args...)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), respType), bz.String())
txResp = respType.(*sdk.TxResponse)
s.Require().Equal(expectedCode, txResp.Code)

respType = proto.Message(&nfttypes.Denom{})
bz, err = nfttestutil.QueryDenomExec(val.ClientCtx, denomID)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), respType))
denomItem2 := respType.(*nfttypes.Denom)
s.Require().Equal(val2.Address.String(), denomItem2.Creator)
s.Require().Equal(denomName, denomItem2.Name)
s.Require().Equal(schema, denomItem2.Schema)
s.Require().Equal(symbol, denomItem2.Symbol)
s.Require().Equal(mintRestricted, denomItem2.MintRestricted)
s.Require().Equal(updateRestricted, denomItem2.UpdateRestricted)
}
25 changes: 16 additions & 9 deletions modules/nft/client/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,30 @@ const (
FlagRecipient = "recipient"
FlagOwner = "owner"

FlagDenomName = "name"
FlagDenomID = "denom-id"
FlagSchema = "schema"
FlagDenomName = "name"
FlagDenomID = "denom-id"
FlagSchema = "schema"
FlagSymbol = "symbol"
FlagMintRestricted = "mint-restricted"
FlagUpdateRestricted = "update-restricted"
)

var (
FsIssueDenom = flag.NewFlagSet("", flag.ContinueOnError)
FsMintNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsEditNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsTransferNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsQuerySupply = flag.NewFlagSet("", flag.ContinueOnError)
FsQueryOwner = flag.NewFlagSet("", flag.ContinueOnError)
FsIssueDenom = flag.NewFlagSet("", flag.ContinueOnError)
FsMintNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsEditNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsTransferNFT = flag.NewFlagSet("", flag.ContinueOnError)
FsQuerySupply = flag.NewFlagSet("", flag.ContinueOnError)
FsQueryOwner = flag.NewFlagSet("", flag.ContinueOnError)
FsTransferDenom = flag.NewFlagSet("", flag.ContinueOnError)
)

func init() {
FsIssueDenom.String(FlagSchema, "", "Denom data structure definition")
FsIssueDenom.String(FlagDenomName, "", "The name of the denom")
FsIssueDenom.String(FlagSymbol, "", "The symbol of the denom")
FsIssueDenom.Bool(FlagMintRestricted, false, "mint restricted of nft under denom")
FsIssueDenom.Bool(FlagUpdateRestricted, false, "update restricted of nft under denom")
chengwenxi marked this conversation as resolved.
Show resolved Hide resolved

FsMintNFT.String(FlagTokenURI, "", "URI for supplemental off-chain tokenData (should return a JSON object)")
FsMintNFT.String(FlagRecipient, "", "Receiver of the nft, if not filled, the default is the sender of the transaction")
Expand Down
61 changes: 61 additions & 0 deletions modules/nft/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func NewTxCmd() *cobra.Command {
GetCmdEditNFT(),
GetCmdTransferNFT(),
GetCmdBurnNFT(),
GetCmdTransferDenom(),
)

return txCmd
Expand All @@ -46,6 +47,9 @@ func GetCmdIssueDenom() *cobra.Command {
"$ %s tx nft issue <denom-id> "+
"--from=<key-name> "+
"--name=<denom-name> "+
"--symbol=<denom-symbol> "+
"--mint-restricted=<mint-restricted> "+
"--update-restricted=<update-restricted> "+
"--schema=<schema-content or path to schema.json> "+
"--chain-id=<chain-id> "+
"--fees=<fee>",
Expand All @@ -66,6 +70,18 @@ func GetCmdIssueDenom() *cobra.Command {
if err != nil {
return err
}
symbol, err := cmd.Flags().GetString(FlagSymbol)
if err != nil {
return err
}
mintRestricted, err := cmd.Flags().GetBool(FlagMintRestricted)
if err != nil {
return err
}
updateRestricted, err := cmd.Flags().GetBool(FlagUpdateRestricted)
if err != nil {
return err
}
optionsContent, err := ioutil.ReadFile(schema)
if err == nil {
schema = string(optionsContent)
Expand All @@ -76,6 +92,9 @@ func GetCmdIssueDenom() *cobra.Command {
denomName,
schema,
clientCtx.GetFromAddress().String(),
symbol,
mintRestricted,
updateRestricted,
)
if err := msg.ValidateBasic(); err != nil {
return err
Expand All @@ -84,6 +103,8 @@ func GetCmdIssueDenom() *cobra.Command {
},
}
cmd.Flags().AddFlagSet(FsIssueDenom)
_ = cmd.MarkFlagRequired(FlagMintRestricted)
_ = cmd.MarkFlagRequired(FlagUpdateRestricted)
flags.AddTxFlagsToCmd(cmd)

return cmd
Expand Down Expand Up @@ -303,3 +324,43 @@ func GetCmdBurnNFT() *cobra.Command {

return cmd
}

// GetCmdTransferDenom is the CLI command for sending a TransferDenom transaction
func GetCmdTransferDenom() *cobra.Command {
cmd := &cobra.Command{
Use: "transfer-denom [recipient] [denom-id]",
Long: "Transfer an Denom to a recipient.",
Example: fmt.Sprintf(
"$ %s tx nft transfer-denom <denom-id> <recipient> "+
"--from=<key-name> "+
"--chain-id=<chain-id> "+
"--fees=<fee>",
version.AppName,
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

if _, err := sdk.AccAddressFromBech32(args[1]); err != nil {
return err
}

msg := types.NewMsgTransferDenom(
args[0],
clientCtx.GetFromAddress().String(),
args[1],
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
cmd.Flags().AddFlagSet(FsTransferDenom)
flags.AddTxFlagsToCmd(cmd)

return cmd
}
39 changes: 38 additions & 1 deletion modules/nft/client/rest/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"testing"

"github.com/tendermint/tendermint/crypto"

"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/suite"
"github.com/tidwall/gjson"
Expand Down Expand Up @@ -50,7 +52,7 @@ func TestIntegrationTestSuite(t *testing.T) {

func (s *IntegrationTestSuite) TestNft() {
val := s.network.Validators[0]

recipient := sdk.AccAddress(crypto.AddressHash([]byte("dgsbl")))
// ---------------------------------------------------------------------------

from := val.Address
Expand All @@ -62,12 +64,18 @@ func (s *IntegrationTestSuite) TestNft() {
denomName := "name"
denom := "denom"
schema := "schema"
symbol := "symbol"
mintRestricted := true
updateRestricted := false
baseURL := val.APIAddress

//------test GetCmdIssueDenom()-------------
args := []string{
fmt.Sprintf("--%s=%s", nftcli.FlagDenomName, denomName),
fmt.Sprintf("--%s=%s", nftcli.FlagSymbol, symbol),
fmt.Sprintf("--%s=%s", nftcli.FlagSchema, schema),
fmt.Sprintf("--%s=%t", nftcli.FlagMintRestricted, mintRestricted),
fmt.Sprintf("--%s=%t", nftcli.FlagUpdateRestricted, updateRestricted),

fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
Expand All @@ -94,6 +102,9 @@ func (s *IntegrationTestSuite) TestNft() {
denomItem := respType.(*nfttypes.QueryDenomResponse)
s.Require().Equal(denomName, denomItem.Denom.Name)
s.Require().Equal(schema, denomItem.Denom.Schema)
s.Require().Equal(symbol, denomItem.Denom.Symbol)
s.Require().Equal(mintRestricted, denomItem.Denom.MintRestricted)
s.Require().Equal(updateRestricted, denomItem.Denom.UpdateRestricted)

//------test GetCmdQueryDenoms()-------------
url = fmt.Sprintf("%s/irismod/nft/denoms", baseURL)
Expand Down Expand Up @@ -167,4 +178,30 @@ func (s *IntegrationTestSuite) TestNft() {
collectionResp := respType.(*nfttypes.QueryCollectionResponse)
s.Require().Equal(1, len(collectionResp.Collection.NFTs))

//------test GetCmdTransferDenom()-------------
args = []string{
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
}

respType = proto.Message(&sdk.TxResponse{})

bz, err = nfttestutil.TransferDenomExec(val.ClientCtx, from.String(), recipient.String(), denomID, args...)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), respType), bz.String())
txResp = respType.(*sdk.TxResponse)
s.Require().Equal(expectedCode, txResp.Code)

respType = proto.Message(&nfttypes.Denom{})
bz, err = nfttestutil.QueryDenomExec(val.ClientCtx, denomID)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.JSONMarshaler.UnmarshalJSON(bz.Bytes(), respType))
denomItem2 := respType.(*nfttypes.Denom)
s.Require().Equal(recipient.String(), denomItem2.Creator)
s.Require().Equal(denomName, denomItem2.Name)
s.Require().Equal(schema, denomItem2.Schema)
s.Require().Equal(symbol, denomItem2.Symbol)
s.Require().Equal(mintRestricted, denomItem2.MintRestricted)
s.Require().Equal(updateRestricted, denomItem2.UpdateRestricted)
}
13 changes: 8 additions & 5 deletions modules/nft/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ const (
)

type issueDenomReq struct {
BaseReq rest.BaseReq `json:"base_req"`
Owner string `json:"owner"`
ID string `json:"id"`
Name string `json:"name"`
Schema string `json:"schema"`
BaseReq rest.BaseReq `json:"base_req"`
Owner string `json:"owner"`
ID string `json:"id"`
Name string `json:"name"`
Schema string `json:"schema"`
Symbol string `json:"symbol"`
MintRestricted bool `json:"mint_restricted"`
UpdateRestricted bool `json:"update_restricted"`
}

type mintNFTReq struct {
Expand Down
2 changes: 1 addition & 1 deletion modules/nft/client/rest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func issueDenomHandlerFn(cliCtx client.Context) http.HandlerFunc {
}

// create the message
msg := types.NewMsgIssueDenom(req.ID, req.Name, req.Schema, req.Owner)
msg := types.NewMsgIssueDenom(req.ID, req.Name, req.Schema, req.Owner, req.Symbol, req.MintRestricted, req.UpdateRestricted)
if err := msg.ValidateBasic(); err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
Expand Down
11 changes: 11 additions & 0 deletions modules/nft/client/testutil/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,14 @@ func QueryNFTExec(clientCtx client.Context, denomID string, tokenID string, extr

return clitestutil.ExecTestCLICmd(clientCtx, nftcli.GetCmdQueryNFT(), args)
}

func TransferDenomExec(clientCtx client.Context, from string, recipient string, denomID string, extraArgs ...string) (testutil.BufferWriter, error) {
args := []string{
denomID,
recipient,
fmt.Sprintf("--%s=%s", flags.FlagFrom, from),
}

args = append(args, extraArgs...)
return clitestutil.ExecTestCLICmd(clientCtx, nftcli.GetCmdTransferDenom(), args)
}
4 changes: 4 additions & 0 deletions modules/nft/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
res, err := msgServer.BurnNFT(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)

case *types.MsgTransferDenom:
res, err := msgServer.TransferDenom(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)

default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized nft message type: %T", msg)
}
Expand Down
8 changes: 4 additions & 4 deletions modules/nft/keeper/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func (k Keeper) SetCollection(ctx sdk.Context, collection types.Collection) erro

// GetCollection returns the collection by the specified denom ID
func (k Keeper) GetCollection(ctx sdk.Context, denomID string) (types.Collection, error) {
denom, err := k.GetDenom(ctx, denomID)
if err != nil {
denom, found := k.GetDenom(ctx, denomID)
if !found {
return types.Collection{}, sdkerrors.Wrapf(types.ErrInvalidDenom, "denomID %s not existed ", denomID)
}

Expand All @@ -44,8 +44,8 @@ func (k Keeper) GetCollection(ctx sdk.Context, denomID string) (types.Collection

// GetPaginateCollection returns the collection by the specified denom ID
func (k Keeper) GetPaginateCollection(ctx sdk.Context, request *types.QueryCollectionRequest, denomID string) (types.Collection, *query.PageResponse, error) {
denom, err := k.GetDenom(ctx, denomID)
if err != nil {
denom, found := k.GetDenom(ctx, denomID)
if !found {
return types.Collection{}, nil, sdkerrors.Wrapf(types.ErrInvalidDenom, "denomID %s not existed ", denomID)
}
var nfts []exported.NFT
Expand Down
11 changes: 7 additions & 4 deletions modules/nft/keeper/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ func (suite *KeeperSuite) TestSetCollection() {
nft2 := types.NewBaseNFT(tokenID2, tokenNm, address, tokenURI, tokenData)

denomE := types.Denom{
Id: denomID,
Name: denomNm,
Schema: schema,
Creator: address.String(),
Id: denomID,
Name: denomNm,
Schema: schema,
Creator: address.String(),
Symbol: denomSymbol,
MintRestricted: true,
UpdateRestricted: true,
}

collection2 := types.Collection{
Expand Down
Loading