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 }