mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 03:07:28 +00:00 
			
		
		
		
	* wip: refactor to allow multiple bep3 assets * update tests * sims: validate asset before claiming * move asset supply to params * update tests * fix sims * fix tests * wip: add migration from v0.9 -> v0.10 bep3 * fix build and migration tests * nit: rename file * move asset supply out of params * update committee tests * fix sims * address review comments * address review comments * address review comments
		
			
				
	
	
		
			338 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package cli
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/hex"
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/cosmos/cosmos-sdk/client"
 | 
						|
	"github.com/cosmos/cosmos-sdk/client/context"
 | 
						|
	"github.com/cosmos/cosmos-sdk/client/flags"
 | 
						|
	"github.com/cosmos/cosmos-sdk/codec"
 | 
						|
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						|
	"github.com/spf13/cobra"
 | 
						|
	"github.com/spf13/viper"
 | 
						|
	tmtime "github.com/tendermint/tendermint/types/time"
 | 
						|
 | 
						|
	"github.com/kava-labs/kava/x/bep3/types"
 | 
						|
)
 | 
						|
 | 
						|
// Query atomic swaps flags
 | 
						|
const (
 | 
						|
	flagInvolve    = "involve"
 | 
						|
	flagExpiration = "expiration"
 | 
						|
	flagStatus     = "status"
 | 
						|
	flagDirection  = "direction"
 | 
						|
)
 | 
						|
 | 
						|
// GetQueryCmd returns the cli query commands for this module
 | 
						|
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	// Group bep3 queries under a subcommand
 | 
						|
	bep3QueryCmd := &cobra.Command{
 | 
						|
		Use:                        "bep3",
 | 
						|
		Short:                      "Querying commands for the bep3 module",
 | 
						|
		DisableFlagParsing:         true,
 | 
						|
		SuggestionsMinimumDistance: 2,
 | 
						|
		RunE:                       client.ValidateCmd,
 | 
						|
	}
 | 
						|
 | 
						|
	bep3QueryCmd.AddCommand(flags.GetCommands(
 | 
						|
		QueryCalcSwapIDCmd(queryRoute, cdc),
 | 
						|
		QueryCalcRandomNumberHashCmd(queryRoute, cdc),
 | 
						|
		QueryGetAssetSupplyCmd(queryRoute, cdc),
 | 
						|
		QueryGetAssetSuppliesCmd(queryRoute, cdc),
 | 
						|
		QueryGetAtomicSwapCmd(queryRoute, cdc),
 | 
						|
		QueryGetAtomicSwapsCmd(queryRoute, cdc),
 | 
						|
		QueryParamsCmd(queryRoute, cdc),
 | 
						|
	)...)
 | 
						|
 | 
						|
	return bep3QueryCmd
 | 
						|
}
 | 
						|
 | 
						|
// QueryCalcRandomNumberHashCmd calculates the random number hash for a number and timestamp
 | 
						|
func QueryCalcRandomNumberHashCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "calc-rnh [unix-timestamp]",
 | 
						|
		Short:   "calculates an example random number hash from an optional timestamp",
 | 
						|
		Example: "bep3 calc-rnh now",
 | 
						|
		Args:    cobra.MaximumNArgs(1),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			userTimestamp := "now"
 | 
						|
			if len(args) > 0 {
 | 
						|
				userTimestamp = args[0]
 | 
						|
			}
 | 
						|
 | 
						|
			// Timestamp defaults to time.Now() unless it's explicitly set
 | 
						|
			var timestamp int64
 | 
						|
			if strings.Compare(userTimestamp, "now") == 0 {
 | 
						|
				timestamp = tmtime.Now().Unix()
 | 
						|
			} else {
 | 
						|
				userTimestamp, err := strconv.ParseInt(userTimestamp, 10, 64)
 | 
						|
				if err != nil {
 | 
						|
					return err
 | 
						|
				}
 | 
						|
				timestamp = userTimestamp
 | 
						|
			}
 | 
						|
 | 
						|
			// Load hex-encoded cryptographically strong pseudo-random number
 | 
						|
			randomNumber, err := types.GenerateSecureRandomNumber()
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			randomNumberHash := types.CalculateRandomHash(randomNumber, timestamp)
 | 
						|
 | 
						|
			// Prepare random number, timestamp, and hash for output
 | 
						|
			randomNumberStr := fmt.Sprintf("Random number: %s\n", hex.EncodeToString(randomNumber))
 | 
						|
			timestampStr := fmt.Sprintf("Timestamp: %d\n", timestamp)
 | 
						|
			randomNumberHashStr := fmt.Sprintf("Random number hash: %s", hex.EncodeToString(randomNumberHash))
 | 
						|
			output := []string{randomNumberStr, timestampStr, randomNumberHashStr}
 | 
						|
			return cliCtx.PrintOutput(strings.Join(output, ""))
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// QueryCalcSwapIDCmd calculates the swapID for a random number hash, sender, and sender other chain
 | 
						|
func QueryCalcSwapIDCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "calc-swapid [random-number-hash] [sender] [sender-other-chain]",
 | 
						|
		Short:   "calculate swap ID for the given random number hash, sender, and sender other chain",
 | 
						|
		Example: "bep3 calc-swapid 0677bd8a303dd981810f34d8e5cc6507f13b391899b84d3c1be6c6045a17d747 kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny bnb1ud3q90r98l3mhd87kswv3h8cgrymzeljct8qn7",
 | 
						|
		Args:    cobra.MinimumNArgs(3),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			// Parse query params
 | 
						|
			randomNumberHash, err := hex.DecodeString(args[0])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			sender, err := sdk.AccAddressFromBech32(args[1])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			senderOtherChain := args[2]
 | 
						|
 | 
						|
			// Calculate swap ID and convert to human-readable string
 | 
						|
			swapID := types.CalculateSwapID(randomNumberHash, sender, senderOtherChain)
 | 
						|
			return cliCtx.PrintOutput(hex.EncodeToString(swapID))
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// QueryGetAssetSupplyCmd queries as asset's current in swap supply, active, supply, and supply limit
 | 
						|
func QueryGetAssetSupplyCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "supply [denom]",
 | 
						|
		Short:   "get information about an asset's supply",
 | 
						|
		Example: "bep3 supply bnb",
 | 
						|
		Args:    cobra.ExactArgs(1),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			// Prepare query params
 | 
						|
			bz, err := cdc.MarshalJSON(types.NewQueryAssetSupply(args[0]))
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Execute query
 | 
						|
			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAssetSupply), bz)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Decode and print results
 | 
						|
			var assetSupply types.AssetSupply
 | 
						|
			cdc.MustUnmarshalJSON(res, &assetSupply)
 | 
						|
			return cliCtx.PrintOutput(assetSupply)
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// QueryGetAssetSuppliesCmd queries AssetSupplies in the store
 | 
						|
func QueryGetAssetSuppliesCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "supplies",
 | 
						|
		Short:   "get a list of all asset supplies",
 | 
						|
		Example: "bep3 supplies",
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAssetSupplies), nil)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			var assetSupplies types.AssetSupplies
 | 
						|
			cdc.MustUnmarshalJSON(res, &assetSupplies)
 | 
						|
 | 
						|
			if len(assetSupplies) == 0 {
 | 
						|
				return fmt.Errorf("There are currently no asset supplies")
 | 
						|
			}
 | 
						|
 | 
						|
			cliCtx = cliCtx.WithHeight(height)
 | 
						|
			return cliCtx.PrintOutput(assetSupplies)
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// QueryGetAtomicSwapCmd queries an AtomicSwap by swapID
 | 
						|
func QueryGetAtomicSwapCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "swap [swap-id]",
 | 
						|
		Short:   "get atomic swap information",
 | 
						|
		Example: "bep3 swap 6682c03cc3856879c8fb98c9733c6b0c30758299138166b6523fe94628b1d3af",
 | 
						|
		Args:    cobra.ExactArgs(1),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			// Decode swapID's hex encoded string to []byte
 | 
						|
			swapID, err := hex.DecodeString(args[0])
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Prepare query params
 | 
						|
			bz, err := cdc.MarshalJSON(types.NewQueryAtomicSwapByID(swapID))
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Execute query
 | 
						|
			res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAtomicSwap), bz)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			var atomicSwap types.AugmentedAtomicSwap
 | 
						|
			cdc.MustUnmarshalJSON(res, &atomicSwap)
 | 
						|
 | 
						|
			cliCtx = cliCtx.WithHeight(height)
 | 
						|
			return cliCtx.PrintOutput(atomicSwap)
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// QueryGetAtomicSwapsCmd queries AtomicSwaps in the store
 | 
						|
func QueryGetAtomicSwapsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	cmd := &cobra.Command{
 | 
						|
		Use:   "swaps",
 | 
						|
		Short: "query atomic swaps with optional filters",
 | 
						|
		Long: strings.TrimSpace(`Query for all paginated atomic swaps that match optional filters:
 | 
						|
Example:
 | 
						|
$ kvcli q bep3 swaps --involve=kava1l0xsq2z7gqd7yly0g40y5836g0appumark77ny
 | 
						|
$ kvcli q bep3 swaps --expiration=280
 | 
						|
$ kvcli q bep3 swaps --status=(Open|Completed|Expired)
 | 
						|
$ kvcli q bep3 swaps --direction=(Incoming|Outgoing)
 | 
						|
$ kvcli q bep3 swaps --page=2 --limit=100
 | 
						|
`,
 | 
						|
		),
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			bechInvolveAddr := viper.GetString(flagInvolve)
 | 
						|
			strExpiration := viper.GetString(flagExpiration)
 | 
						|
			strSwapStatus := viper.GetString(flagStatus)
 | 
						|
			strSwapDirection := viper.GetString(flagDirection)
 | 
						|
			page := viper.GetInt(flags.FlagPage)
 | 
						|
			limit := viper.GetInt(flags.FlagLimit)
 | 
						|
 | 
						|
			var involveAddr sdk.AccAddress
 | 
						|
			var expiration uint64
 | 
						|
			var swapStatus types.SwapStatus
 | 
						|
			var swapDirection types.SwapDirection
 | 
						|
 | 
						|
			params := types.NewQueryAtomicSwaps(page, limit, involveAddr, expiration, swapStatus, swapDirection)
 | 
						|
 | 
						|
			if len(bechInvolveAddr) != 0 {
 | 
						|
				involveAddr, err := sdk.AccAddressFromBech32(bechInvolveAddr)
 | 
						|
				if err != nil {
 | 
						|
					return err
 | 
						|
				}
 | 
						|
				params.Involve = involveAddr
 | 
						|
			}
 | 
						|
 | 
						|
			if len(strExpiration) != 0 {
 | 
						|
				expiration, err := strconv.ParseUint(strExpiration, 10, 64)
 | 
						|
				if err != nil {
 | 
						|
					return err
 | 
						|
				}
 | 
						|
				params.Expiration = expiration
 | 
						|
			}
 | 
						|
 | 
						|
			if len(strSwapStatus) != 0 {
 | 
						|
				swapStatus := types.NewSwapStatusFromString(strSwapStatus)
 | 
						|
				if !swapStatus.IsValid() {
 | 
						|
					return fmt.Errorf("invalid swap status %s", strSwapStatus)
 | 
						|
				}
 | 
						|
				params.Status = swapStatus
 | 
						|
			}
 | 
						|
 | 
						|
			if len(strSwapDirection) != 0 {
 | 
						|
				swapDirection := types.NewSwapDirectionFromString(strSwapDirection)
 | 
						|
				if !swapDirection.IsValid() {
 | 
						|
					return fmt.Errorf("invalid swap direction %s", strSwapDirection)
 | 
						|
				}
 | 
						|
				params.Direction = swapDirection
 | 
						|
			}
 | 
						|
 | 
						|
			bz, err := cdc.MarshalJSON(params)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetAtomicSwaps), bz)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			var matchingAtomicSwaps types.AugmentedAtomicSwaps
 | 
						|
			cdc.UnmarshalJSON(res, &matchingAtomicSwaps)
 | 
						|
 | 
						|
			if len(matchingAtomicSwaps) == 0 {
 | 
						|
				return fmt.Errorf("No matching atomic swaps found")
 | 
						|
			}
 | 
						|
 | 
						|
			cliCtx = cliCtx.WithHeight(height)
 | 
						|
			return cliCtx.PrintOutput(matchingAtomicSwaps) // nolint:errcheck
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	cmd.Flags().Int(flags.FlagPage, 1, "pagination page of atomic swaps to to query for")
 | 
						|
	cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of atomic swaps to query for")
 | 
						|
	cmd.Flags().String(flagInvolve, "", "(optional) filter by atomic swaps that involve an address")
 | 
						|
	cmd.Flags().String(flagExpiration, "", "(optional) filter by atomic swaps that expire before a block height")
 | 
						|
	cmd.Flags().String(flagStatus, "", "(optional) filter by atomic swap status, status: open/completed/expired")
 | 
						|
	cmd.Flags().String(flagDirection, "", "(optional) filter by atomic swap direction, direction: incoming/outgoing")
 | 
						|
 | 
						|
	return cmd
 | 
						|
}
 | 
						|
 | 
						|
// QueryParamsCmd queries the bep3 module parameters
 | 
						|
func QueryParamsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
 | 
						|
	return &cobra.Command{
 | 
						|
		Use:     "params",
 | 
						|
		Short:   "get the bep3 module parameters",
 | 
						|
		Example: "bep3 params",
 | 
						|
		Args:    cobra.NoArgs,
 | 
						|
		RunE: func(cmd *cobra.Command, args []string) error {
 | 
						|
			cliCtx := context.NewCLIContext().WithCodec(cdc)
 | 
						|
 | 
						|
			// Query
 | 
						|
			route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetParams)
 | 
						|
			res, _, err := cliCtx.QueryWithData(route, nil)
 | 
						|
			if err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// Decode and print results
 | 
						|
			var out types.Params
 | 
						|
			cdc.MustUnmarshalJSON(res, &out)
 | 
						|
			return cliCtx.PrintOutput(out)
 | 
						|
		},
 | 
						|
	}
 | 
						|
}
 |