github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/cmd/fbchaincli/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  
     6  	interfacetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
     7  
     8  	authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
     9  
    10  	"github.com/fibonacci-chain/fbc/app"
    11  	"github.com/fibonacci-chain/fbc/app/codec"
    12  	"github.com/fibonacci-chain/fbc/app/crypto/ethsecp256k1"
    13  	fbchain "github.com/fibonacci-chain/fbc/app/types"
    14  	"github.com/fibonacci-chain/fbc/cmd/client"
    15  	sdkclient "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    17  	clientkeys "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/keys"
    18  	clientrpc "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/rpc"
    19  	sdkcodec "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
    22  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    23  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    24  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    25  	authcmd "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/client/cli"
    26  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/client/utils"
    27  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    28  	tmamino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino"
    29  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/multisig"
    30  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/cli"
    31  	"github.com/fibonacci-chain/fbc/x/dex"
    32  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
    33  	"github.com/fibonacci-chain/fbc/x/order"
    34  	tokencmd "github.com/fibonacci-chain/fbc/x/token/client/cli"
    35  	"github.com/spf13/cobra"
    36  )
    37  
    38  var (
    39  	cdc          = codec.MakeCodec(app.ModuleBasics)
    40  	interfaceReg = codec.MakeIBC(app.ModuleBasics)
    41  )
    42  
    43  func main() {
    44  	// Configure cobra to sort commands
    45  	cobra.EnableCommandSorting = false
    46  
    47  	tmamino.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName)
    48  	tmamino.RegisterKeyType(ethsecp256k1.PrivKey{}, ethsecp256k1.PrivKeyName)
    49  	multisig.RegisterKeyType(ethsecp256k1.PubKey{}, ethsecp256k1.PubKeyName)
    50  
    51  	keys.CryptoCdc = cdc
    52  	clientkeys.KeysCdc = cdc
    53  
    54  	// Read in the configuration file for the sdk
    55  	config := sdk.GetConfig()
    56  	fbchain.SetBech32Prefixes(config)
    57  	fbchain.SetBip44CoinType(config)
    58  	config.Seal()
    59  
    60  	rootCmd := &cobra.Command{
    61  		Use:   "fbchaincli",
    62  		Short: "Command line interface for interacting with fbchaind",
    63  	}
    64  
    65  	// Add --chain-id to persistent flags and mark it required
    66  	rootCmd.PersistentFlags().String(flags.FlagChainID, server.ChainID, "Chain ID of tendermint node")
    67  	rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error {
    68  		utils.SetParseAppTx(wrapDecoder(parseMsgEthereumTx, parseProtobufTx))
    69  		return client.InitConfig(rootCmd)
    70  	}
    71  	protoCdc := sdkcodec.NewProtoCodec(interfaceReg)
    72  	proxy := sdkcodec.NewCodecProxy(protoCdc, cdc)
    73  	// Construct Root Command
    74  	rootCmd.AddCommand(
    75  		clientrpc.StatusCommand(),
    76  		sdkclient.ConfigCmd(app.DefaultCLIHome),
    77  		queryCmd(proxy, interfaceReg),
    78  		txCmd(proxy, interfaceReg),
    79  		flags.LineBreak,
    80  		client.KeyCommands(),
    81  		client.AddrCommands(),
    82  		flags.LineBreak,
    83  		version.Cmd,
    84  		flags.NewCompletionCmd(rootCmd, true),
    85  	)
    86  
    87  	// Add flags and prefix all env exposed with FBChain
    88  	executor := cli.PrepareMainCmd(rootCmd, "FBChain", app.DefaultCLIHome)
    89  
    90  	err := executor.Execute()
    91  	if err != nil {
    92  		panic(fmt.Errorf("failed executing CLI command: %w", err))
    93  	}
    94  }
    95  
    96  func queryCmd(proxy *sdkcodec.CodecProxy, reg interfacetypes.InterfaceRegistry) *cobra.Command {
    97  	queryCmd := &cobra.Command{
    98  		Use:     "query",
    99  		Aliases: []string{"q"},
   100  		Short:   "Querying subcommands",
   101  	}
   102  	cdc := proxy.GetCdc()
   103  	queryCmd.AddCommand(
   104  		authcmd.GetAccountCmd(cdc),
   105  		flags.LineBreak,
   106  		authcmd.QueryTxsByEventsCmd(cdc),
   107  		authcmd.QueryTxCmd(proxy),
   108  		flags.LineBreak,
   109  	)
   110  
   111  	// add modules' query commands
   112  	app.ModuleBasics.AddQueryCommands(queryCmd, cdc)
   113  	app.ModuleBasics.AddQueryCommandsV2(queryCmd, proxy, reg)
   114  
   115  	return queryCmd
   116  }
   117  
   118  func txCmd(proxy *sdkcodec.CodecProxy, reg interfacetypes.InterfaceRegistry) *cobra.Command {
   119  	txCmd := &cobra.Command{
   120  		Use:   "tx",
   121  		Short: "Transactions subcommands",
   122  	}
   123  	cdc := proxy.GetCdc()
   124  	txCmd.AddCommand(
   125  		tokencmd.SendTxCmd(cdc),
   126  		flags.LineBreak,
   127  		authcmd.GetSignCommand(cdc),
   128  		authcmd.GetMultiSignCommand(cdc),
   129  		flags.LineBreak,
   130  		authcmd.GetBroadcastCommand(cdc),
   131  		authcmd.GetEncodeCommand(cdc),
   132  		authcmd.GetDecodeCommand(cdc),
   133  		flags.LineBreak,
   134  	)
   135  
   136  	// add modules' tx commands
   137  	app.ModuleBasics.AddTxCommands(txCmd, cdc)
   138  	app.ModuleBasics.AddTxCommandsV2(txCmd, proxy, reg)
   139  
   140  	// remove auth and bank commands as they're mounted under the root tx command
   141  	var cmdsToRemove []*cobra.Command
   142  
   143  	for _, cmd := range txCmd.Commands() {
   144  		if cmd.Use == auth.ModuleName ||
   145  			cmd.Use == order.ModuleName ||
   146  			cmd.Use == dex.ModuleName ||
   147  			cmd.Use == bank.ModuleName {
   148  			cmdsToRemove = append(cmdsToRemove, cmd)
   149  		}
   150  	}
   151  
   152  	txCmd.RemoveCommand(cmdsToRemove...)
   153  
   154  	return txCmd
   155  }
   156  
   157  func wrapDecoder(handlers ...utils.ParseAppTxHandler) utils.ParseAppTxHandler {
   158  	return func(cdc *sdkcodec.CodecProxy, txBytes []byte) (sdk.Tx, error) {
   159  		var (
   160  			tx  sdk.Tx
   161  			err error
   162  		)
   163  		for _, handler := range handlers {
   164  			tx, err = handler(cdc, txBytes)
   165  			if nil == err && tx != nil {
   166  				return tx, err
   167  			}
   168  		}
   169  		return tx, err
   170  	}
   171  }
   172  func parseMsgEthereumTx(cdc *sdkcodec.CodecProxy, txBytes []byte) (sdk.Tx, error) {
   173  	var tx evmtypes.MsgEthereumTx
   174  	// try to decode through RLP first
   175  	if err := authtypes.EthereumTxDecode(txBytes, &tx); err == nil {
   176  		return &tx, nil
   177  	}
   178  	//try to decode through animo if it is not RLP-encoded
   179  	if err := cdc.UnmarshalBinaryLengthPrefixed(txBytes, &tx); err != nil {
   180  		return nil, err
   181  	}
   182  	return &tx, nil
   183  }
   184  
   185  func parseProtobufTx(cdc *sdkcodec.CodecProxy, txBytes []byte) (sdk.Tx, error) {
   186  	tx, err := evmtypes.TxDecoder(cdc)(txBytes, evmtypes.IGNORE_HEIGHT_CHECKING)
   187  	if nil != err {
   188  		return nil, err
   189  	}
   190  	switch realTx := tx.(type) {
   191  	case *authtypes.IbcTx:
   192  		return authtypes.FromProtobufTx(cdc, realTx)
   193  	}
   194  	return tx, err
   195  }