From 2bed6f6c39a8b78f906bc41c51b72616295909ce Mon Sep 17 00:00:00 2001 From: Wojtek <103407812+wojtek-coreum@users.noreply.github.com> Date: Mon, 16 Oct 2023 11:31:16 +0200 Subject: [PATCH] Add recipient to FT and NFT mint CLI commands (#669) # Description # Reviewers checklist: - [ ] Try to write more meaningful comments with clear actions to be taken. - [ ] Nit-picking should be unblocking. Focus on core issues. # Authors checklist - [x] Provide a concise and meaningful description - [x] Review the code yourself first, before making the PR. - [x] Annotate your PR in places that require explanation. - [x] Think and try to split the PR to smaller PR if it is big. --- .github/workflows/ci.yml | 2 +- x/asset/ft/client/cli/tx.go | 18 ++++++++---- x/asset/ft/client/cli/tx_test.go | 12 +++++++- x/asset/nft/client/cli/query_test.go | 2 +- x/asset/nft/client/cli/tx.go | 18 ++++++++---- x/asset/nft/client/cli/tx_test.go | 42 ++++++++++++++++++++++++++-- 6 files changed, 79 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34ed1ae5c..bcbdbbf63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -100,7 +100,7 @@ jobs: if: ${{ matrix.linter-cache }} with: path: ~/.cache/golangci-lint - key: ${{ runner.os }}-linter-cache + key: ${{ runner.os }}-linter-cache-2 - name: Get Date id: get-year-week run: | diff --git a/x/asset/ft/client/cli/tx.go b/x/asset/ft/client/cli/tx.go index 5b47f4d1c..3ac48e272 100644 --- a/x/asset/ft/client/cli/tx.go +++ b/x/asset/ft/client/cli/tx.go @@ -31,6 +31,7 @@ const ( MintLimitFlag = "mint-limit" BurnLimitFlag = "burn-limit" ExpirationFlag = "expiration" + RecipientFlag = "recipient" ) // GetTxCmd returns the transaction commands for this module. @@ -170,9 +171,9 @@ $ %s tx %s issue WBTC wsatoshi 8 100000 "Wrapped Bitcoin Token" --from [issuer] } // CmdTxMint returns Mint cobra command. -func CmdTxMint() *cobra.Command { //nolint:dupl // all CLI commands are similar. +func CmdTxMint() *cobra.Command { cmd := &cobra.Command{ - Use: "mint [amount] --from [sender]", + Use: "mint [amount] --from [sender] --recipient [recipient]", Args: cobra.ExactArgs(1), Short: "mint new amount of fungible token", Long: strings.TrimSpace( @@ -191,14 +192,20 @@ $ %s tx %s mint 100000ABC-%s --from [sender] } sender := clientCtx.GetFromAddress() + recipient, err := cmd.Flags().GetString(RecipientFlag) + if err != nil { + return errors.WithStack(err) + } + amount, err := sdk.ParseCoinNormalized(args[0]) if err != nil { return sdkerrors.Wrap(err, "invalid amount") } msg := &types.MsgMint{ - Sender: sender.String(), - Coin: amount, + Sender: sender.String(), + Recipient: recipient, + Coin: amount, } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) @@ -206,12 +213,13 @@ $ %s tx %s mint 100000ABC-%s --from [sender] } flags.AddTxFlagsToCmd(cmd) + cmd.Flags().String(RecipientFlag, "", "Address to send minted tokens to, if not specified minted tokens are sent to the issuer") return cmd } // CmdTxBurn returns Burn cobra command. -func CmdTxBurn() *cobra.Command { //nolint:dupl // all CLI commands are similar. +func CmdTxBurn() *cobra.Command { cmd := &cobra.Command{ Use: "burn [amount] --from [sender]", Args: cobra.ExactArgs(1), diff --git a/x/asset/ft/client/cli/tx_test.go b/x/asset/ft/client/cli/tx_test.go index c3eb03ed6..4cbad6efe 100644 --- a/x/asset/ft/client/cli/tx_test.go +++ b/x/asset/ft/client/cli/tx_test.go @@ -83,6 +83,16 @@ func TestMintBurn(t *testing.T) { requireT.NoError(coreumclitestutil.ExecQueryCmd(ctx, bankcli.GetCmdQueryTotalSupply(), []string{"--denom", denom}, &supplyRsp)) requireT.Equal(sdk.NewInt64Coin(denom, 877).String(), supplyRsp.String()) + // mint to recipient + recipient := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + args = append([]string{coinToMint.String(), "--recipient", recipient.String()}, txValidator1Args(testNetwork)...) + _, err = coreumclitestutil.ExecTxCmd(ctx, testNetwork, cli.CmdTxMint(), args) + requireT.NoError(err) + + requireT.NoError(coreumclitestutil.ExecQueryCmd(ctx, bankcli.GetBalancesCmd(), []string{recipient.String()}, &balanceRsp)) + requireT.Equal(sdkmath.NewInt(100).String(), balanceRsp.Balances.AmountOf(denom).String()) + // burn tokens coinToMint = sdk.NewInt64Coin(denom, 200) args = append([]string{coinToMint.String()}, txValidator1Args(testNetwork)...) @@ -93,7 +103,7 @@ func TestMintBurn(t *testing.T) { requireT.Equal(sdkmath.NewInt(677).String(), balanceRsp.Balances.AmountOf(denom).String()) requireT.NoError(coreumclitestutil.ExecQueryCmd(ctx, bankcli.GetCmdQueryTotalSupply(), []string{"--denom", denom}, &supplyRsp)) - requireT.Equal(sdk.NewInt64Coin(denom, 677).String(), supplyRsp.String()) + requireT.Equal(sdk.NewInt64Coin(denom, 777).String(), supplyRsp.String()) } func TestFreezeAndQueryFrozen(t *testing.T) { diff --git a/x/asset/nft/client/cli/query_test.go b/x/asset/nft/client/cli/query_test.go index 9a0bd6c42..98ae96039 100644 --- a/x/asset/nft/client/cli/query_test.go +++ b/x/asset/nft/client/cli/query_test.go @@ -153,7 +153,7 @@ func mint( func issueClass( requireT *require.Assertions, ctx client.Context, - symbol, name, description, url, urlHash string, + symbol, name, description, url, urlHash string, //nolint:unparam testNetwork *network.Network, royaltyRate string, features ...types.ClassFeature, diff --git a/x/asset/nft/client/cli/tx.go b/x/asset/nft/client/cli/tx.go index 59f35a343..206e731ca 100644 --- a/x/asset/nft/client/cli/tx.go +++ b/x/asset/nft/client/cli/tx.go @@ -20,6 +20,7 @@ import ( const ( FeaturesFlag = "features" RoyaltyRateFlag = "royalty-rate" + RecipientFlag = "recipient" ) // GetTxCmd returns the transaction commands for this module. @@ -145,17 +146,23 @@ $ %s tx %s mint abc-%s id1 https://my-nft-meta.invalid/1 e000624 --from [sender] } sender := clientCtx.GetFromAddress() + recipient, err := cmd.Flags().GetString(RecipientFlag) + if err != nil { + return errors.WithStack(err) + } + classID := args[0] ID := args[1] uri := args[2] uriHash := args[3] msg := &types.MsgMint{ - Sender: sender.String(), - ClassID: classID, - ID: ID, - URI: uri, - URIHash: uriHash, + Sender: sender.String(), + Recipient: recipient, + ClassID: classID, + ID: ID, + URI: uri, + URIHash: uriHash, } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) @@ -163,6 +170,7 @@ $ %s tx %s mint abc-%s id1 https://my-nft-meta.invalid/1 e000624 --from [sender] } flags.AddTxFlagsToCmd(cmd) + cmd.Flags().String(RecipientFlag, "", "Address to send minted token to, if not specified minted token is sent to the class issuer") return cmd } diff --git a/x/asset/nft/client/cli/tx_test.go b/x/asset/nft/client/cli/tx_test.go index 6c076a5d0..3cbf4e9db 100644 --- a/x/asset/nft/client/cli/tx_test.go +++ b/x/asset/nft/client/cli/tx_test.go @@ -8,6 +8,8 @@ import ( "github.com/cometbft/cometbft/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/nft" + cosmoscli "github.com/cosmos/cosmos-sdk/x/nft/client/cli" "github.com/google/uuid" "github.com/stretchr/testify/require" @@ -17,6 +19,8 @@ import ( "github.com/CoreumFoundation/coreum/v3/x/asset/nft/types" ) +const nftID = "nft-1" + func TestCmdTxIssueClass(t *testing.T) { requireT := require.New(t) testNetwork := network.New(t) @@ -41,6 +45,42 @@ func TestCmdTxIssueClass(t *testing.T) { requireT.Equal(uint32(0), res.Code, "can't submit IssueClass tx", res) } +func TestCmdMintToRecipient(t *testing.T) { + requireT := require.New(t) + testNetwork := network.New(t) + + symbol := "nft" + uuid.NewString()[:4] + validator := testNetwork.Validators[0] + ctx := validator.ClientCtx + + // create class + classID := issueClass( + requireT, + ctx, + symbol, + "class name", + "class description", + "https://my-class-meta.invalid/1", + "", + testNetwork, + "0.0", + types.ClassFeature_freezing, + ) + // mint nft + recipient := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + args := []string{classID, nftID, "", "", "--recipient", recipient.String()} + args = append(args, txValidator1Args(testNetwork)...) + _, err := coreumclitestutil.ExecTxCmd(ctx, testNetwork, cli.CmdTxMint(), args) + requireT.NoError(err) + + // query recipient + + var resp nft.QueryOwnerResponse + args = []string{classID, nftID} + requireT.NoError(coreumclitestutil.ExecQueryCmd(ctx, cosmoscli.GetCmdQueryOwner(), args, &resp)) + requireT.Equal(recipient.String(), resp.Owner) +} + func TestCmdFreeze(t *testing.T) { requireT := require.New(t) testNetwork := network.New(t) @@ -63,7 +103,6 @@ func TestCmdFreeze(t *testing.T) { types.ClassFeature_freezing, ) // mint nft - nftID := "nft-1" mint( requireT, ctx, @@ -120,7 +159,6 @@ func TestCmdWhitelist(t *testing.T) { types.ClassFeature_whitelisting, ) // mint nft - nftID := "nft-1" mint( requireT, ctx,