diff --git a/internal/x/paychan/client/cmd/cmd.go b/internal/x/paychan/client/cmd/cmd.go index 5a262519..0c704389 100644 --- a/internal/x/paychan/client/cmd/cmd.go +++ b/internal/x/paychan/client/cmd/cmd.go @@ -3,11 +3,12 @@ package cli import ( "fmt" + "github.com/cosmos/cosmos-sdk/client/context" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" "github.com/spf13/cobra" - //"github.com/cosmos/cosmos-sdk/client/context" - //sdk "github.com/cosmos/cosmos-sdk/types" - //"github.com/cosmos/cosmos-sdk/wire" //"github.com/cosmos/cosmos-sdk/x/auth" + "github.com/kava-labs/kava/internal/x/paychan" ) // list of functions that return pointers to cobra commands @@ -24,50 +25,178 @@ import ( // create state update (sender signs) (just a half signed close tx, (json encoded?)) // close paychan (receiver signs) (provide state update as arg) -// example from x/auth -/* -func GetAccountCmd(storeName string, cdc *wire.Codec, decoder auth.AccountDecoder) *cobra.Command { - return &cobra.Command{ - Use: "account [address]", - Short: "Query account balance", - Args: cobra.ExactArgs(1), +func CreatePaychanCmd(cdc *wire.Codec) *cobra.Command { + flagTo := "to" + flagAmount := "amount" + + cmd := &cobra.Command{ + Use: "create", + Short: "Create a new payment channel", + Long: "Create a new payment channel from a local address to a remote address, funded with some amount of coins. These coins are removed from the sender account and put into the payment channel.", + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - - // find the key to look up the account - addr := args[0] - - key, err := sdk.GetAccAddressBech32(addr) - if err != nil { - return err - } - - // perform query + // get args: from, to, amount + // create a "client context" stuct populated with info from common flags ctx := context.NewCoreContextFromViper() - res, err := ctx.Query(auth.AddressStoreKey(key), storeName) + // ChainID: chainID, + // Height: viper.GetInt64(client.FlagHeight), + // Gas: viper.GetInt64(client.FlagGas), + // TrustNode: viper.GetBool(client.FlagTrustNode), + // FromAddressName: viper.GetString(client.FlagName), + // NodeURI: nodeURI, + // AccountNumber: viper.GetInt64(client.FlagAccountNumber), + // Sequence: viper.GetInt64(client.FlagSequence), + // Client: rpc, + // Decoder: nil, + // AccountStore: "acc", + + // Get sender adress + senderAddress, err := ctx.GetFromAddress() if err != nil { return err } - // Check if account was found - if res == nil { - return sdk.ErrUnknownAddress("No account with address " + addr + - " was found in the state.\nAre you sure there has been a transaction involving it?") - } - - // decode the value - account, err := decoder(res) + // Get receiver address + toStr := viper.GetString(flagTo) + receiverAddress, err := sdk.GetAccAddressBech32(toStr) if err != nil { return err } - // print out whole account - output, err := wire.MarshalJSONIndent(cdc, account) + // Get channel funding amount + amountString := viper.GetString(flagAmount) + amount, err := sdk.ParseCoins(amountString) if err != nil { return err } - fmt.Println(string(output)) - return nil + + // Create the create channel msg to send + // TODO write NewMsgCreate func? + msg := paychan.MsgCreate{ + sender: senderAddress, + receiver: receiverAddress, + amount: amount, + } + // Build and sign the transaction, then broadcast to Tendermint + res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc) + if err != nil { + return err + } + fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String()) }, } + cmd.Flags().String(flagTo, "", "Recipient address of the payment channel") + cmd.Flags().String(flagAmount, "", "Amount of coins to fund the paymetn channel with") + return cmd +} + +func CreateNewStateCmd(cdc *wire.Codec) *cobra.Command { + flagId := "id" + flagTo := "to" + flagAmount := "amount" + + cmd := &cobra.Command{ + Use: "localstate", + Short: "Create a payment channel claim", + Long: "", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + // sender(name) receiver id + + // create a "client context" stuct populated with info from common flags + ctx := context.NewCoreContextFromViper() + // Get sender adress + senderAddress, err := ctx.GetFromAddress() + if err != nil { + return err + } + // Get id + id := viper.GetInt(flagId) + // Get receiver address + toStr := viper.GetString(flagTo) + receiverAddress, err := sdk.GetAccAddressBech32(toStr) + if err != nil { + return err + } + // Get channel receiver amount + amountString := viper.GetString(flagAmount) + amount, err := sdk.ParseCoins(amountString) + if err != nil { + return err + } + + // create MsgClose + + msg := paychan.MsgClose{ + sender: senderAddress, + receiver: receiverAddress, + id: id, + receiverAmount: amount, + } + + // half sign it + + txBytes, err := EnsureSignBuild(ctx, ctx.FromAddressName, msg, cdc) + if err != nil { + return err + } + + // print it out + + fmt.Println(txBytes) + + }, + } + cmd.Flags().Int(flagId, 0, "ID of the payment channel.") + cmd.Flags().String(flagTo, "", "Recipient address of the payment channel") + cmd.Flags().String(flagAmount, "", "Amount of coins to fund the paymetn channel with") + return cmd +} + +// sign and build the transaction from the msg +func EnsureSignBuild(ctx context.CoreContext, name string, msg sdk.Msg, cdc *wire.Codec) ([]byte, error) { + + ctx, err = EnsureAccountNumber(ctx) + if err != nil { + return nil, err + } + // default to next sequence number if none provided + ctx, err = EnsureSequence(ctx) + if err != nil { + return nil, err + } + + passphrase, err := ctx.GetPassphraseFromStdin(name) + if err != nil { + return nil, err + } + + txBytes, err := ctx.SignAndBuild(name, passphrase, msg, cdc) + if err != nil { + return nil, err + } + + return txBytes +} + +func ClosePaychanCmd(cdc *wire.Codec) *cobra.Command { + flagId := "id" + flagTo := "to" + flagState := "state" + + cmd := &cobra.Command{ + Use: "close", + Short: "Close a payment channel", + Long: "", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + // get sender, reciver, id + // get state + // sign the state tx with receiver + // broadcast to tendermint + }, + } + //cmd.Flags().String(flagTo, "", "Recipient address of the payment channel") + //cmd.Flags().String(flagAmount, "", "Amount of coins to fund the paymetn channel with") + return cmd } -*/