Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add FlagPrintEIP712MsgType #310

Merged
merged 1 commit into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ func ReadPersistentCommandFlags(clientCtx Context, flagSet *pflag.FlagSet) (Cont
clientCtx = clientCtx.WithSimulation(dryRun)
}

if !clientCtx.Simulate || flagSet.Changed(flags.FlagPrintEIP712MsgType) {
printEIP712, _ := flagSet.GetBool(flags.FlagPrintEIP712MsgType)
clientCtx = clientCtx.WithSimulation(printEIP712).WithPrintEIP712MsgType(printEIP712)
}

if clientCtx.KeyringDir == "" || flagSet.Changed(flags.FlagKeyringDir) {
keyringDir, _ := flagSet.GetString(flags.FlagKeyringDir)

Expand Down
10 changes: 9 additions & 1 deletion client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ type Context struct {
// IsAux is true when the signer is an auxiliary signer (e.g. the tipper).
IsAux bool

PrintEIP712MsgType bool

// TODO: Deprecated (remove).
LegacyAmino *codec.LegacyAmino
}
Expand Down Expand Up @@ -267,6 +269,12 @@ func (ctx Context) WithAux(isAux bool) Context {
return ctx
}

// WithPrintEIP712MsgType returns a copy of the context with an updated PrintEIP712MsgType value.
func (ctx Context) WithPrintEIP712MsgType(printEIP712MsgType bool) Context {
ctx.PrintEIP712MsgType = printEIP712MsgType
return ctx
}

// WithLedgerHasProto returns the context with the provided boolean value, indicating
// whether the target Ledger application can support Protobuf payloads.
func (ctx Context) WithLedgerHasProtobuf(val bool) Context {
Expand Down Expand Up @@ -369,7 +377,7 @@ func GetFromFields(clientCtx Context, kr keyring.Keyring, from string) (sdk.AccA
switch {
case clientCtx.Simulate:
if err != nil {
return nil, "", 0, fmt.Errorf("a valid bech32 address must be provided in simulation mode: %w", err)
return nil, "", 0, fmt.Errorf("a valid hex address must be provided in simulation mode: %w", err)
}

return addr, "", 0, nil
Expand Down
2 changes: 1 addition & 1 deletion client/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func TestGetFromFields(t *testing.T) {
},
from: "alice",
clientCtx: client.Context{}.WithSimulation(true),
expectedErr: "a valid bech32 address must be provided in simulation mode",
expectedErr: "a valid hex address must be provided in simulation mode",
},
{
keyring: func() keyring.Keyring {
Expand Down
3 changes: 3 additions & 0 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ const (
// Tendermint logging flags
FlagLogLevel = "log_level"
FlagLogFormat = "log_format"

FlagPrintEIP712MsgType = "print-eip712-msg-type"
)

// LineBreak can be included in a command list to provide a blank line
Expand Down Expand Up @@ -136,6 +138,7 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
// --gas can accept integers and "auto"
f.String(FlagGas, "", fmt.Sprintf("gas limit to set per-transaction; set to %q to calculate sufficient gas automatically. Note: %q option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of %q. (default %d)",
GasFlagAuto, GasFlagAuto, FlagFees, DefaultGasLimit))
f.Bool(FlagPrintEIP712MsgType, false, "ignore the --gas flag and perform a simulation of a transaction(but don't broadcast it) and print the EIP712 message type")

AddKeyringFlags(f)
}
Expand Down
87 changes: 82 additions & 5 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package tx

import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"os"
Expand All @@ -15,11 +17,14 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/keys/eth/ethsecp256k1"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
)

// Factory defines a client transaction factory that facilitates generating and
Expand Down Expand Up @@ -80,8 +85,13 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
memo, _ := flagSet.GetString(flags.FlagNote)
timeoutHeight, _ := flagSet.GetUint64(flags.FlagTimeoutHeight)

gasStr, _ := flagSet.GetString(flags.FlagGas)
gasSetting, _ := flags.ParseGasSetting(gasStr)
var gasSetting flags.GasSetting
dryRun, _ := flagSet.GetBool(flags.FlagDryRun)
printEIP712MsgType, _ := flagSet.GetBool(flags.FlagPrintEIP712MsgType)
if !dryRun && !printEIP712MsgType {
gasStr, _ := flagSet.GetString(flags.FlagGas)
gasSetting, _ = flags.ParseGasSetting(gasStr)
}

f := Factory{
txConfig: clientCtx.TxConfig,
Expand Down Expand Up @@ -170,7 +180,7 @@ func (f Factory) WithFees(fees string) Factory {
}

// WithTips returns a copy of the Factory with an updated tip.
func (f Factory) WithTips(tip string, tipper string) Factory {
func (f Factory) WithTips(tip, tipper string) Factory {
parsedTips, err := sdk.ParseCoinsNormalized(tip)
if err != nil {
panic(err)
Expand Down Expand Up @@ -399,6 +409,73 @@ func (f Factory) PrintUnsignedTx(clientCtx client.Context, msgs ...sdk.Msg) erro
return clientCtx.PrintString(fmt.Sprintf("%s\n", json))
}

func (f Factory) PrintEIP712MsgType(clientCtx client.Context, msgs ...sdk.Msg) error {
if len(msgs) != 1 {
return errors.New("only one message is supported")
}

unsignedTx, err := f.BuildUnsignedTx(msgs...)
if err != nil {
return err
}

txRawBytes, err := clientCtx.TxConfig.TxEncoder()(unsignedTx.GetTx())
if err != nil {
return err
}
txRawBytesHex := hex.EncodeToString(txRawBytes)

signerData := authsigning.SignerData{
Address: clientCtx.From,
ChainID: clientCtx.ChainID,
}

chainID, err := sdk.ParseChainID(clientCtx.ChainID)
if err != nil {
return fmt.Errorf("failed to parse chainID: %s", err)
}
msgTypes, signDoc, err := authtx.GetMsgTypes(signerData, unsignedTx.GetTx(), chainID)
if err != nil {
return fmt.Errorf("failed to get msg types: %s", err)
}
typedData, err := authtx.WrapTxToTypedData(chainID.Uint64(), signDoc, msgTypes)
if err != nil {
return fmt.Errorf("failed to wrap tx to typedData: %s", err)
}

eip712MsgTypes := typedData.Types
delete(eip712MsgTypes, "Tx")
delete(eip712MsgTypes, "Fee")
delete(eip712MsgTypes, "Coin")
delete(eip712MsgTypes, "EIP712Domain")

msgData := typedData.Message["msg1"].(map[string]interface{})
if msgData == nil {
return fmt.Errorf("failed to get msg data")
}
msgTypeUrl := msgData["type"].(string)

type EIP712TypedData struct {
MsgTypeUrl string `json:"MsgTypeUrl"`
EIP712MessageType apitypes.Types `json:"EIP712MessageType"`
MessageData map[string]interface{} `json:"MessageData"`
TxRawBytes string `json:"TxRawBytes"`
}

eip712TypedData := EIP712TypedData{
MsgTypeUrl: msgTypeUrl,
EIP712MessageType: eip712MsgTypes,
MessageData: msgData,
TxRawBytes: txRawBytesHex,
}
bz, err := json.MarshalIndent(eip712TypedData, "", " ")
if err != nil {
return err
}

return clientCtx.PrintString(fmt.Sprintf("%s\n", bz))
}

// BuildSimTx creates an unsigned tx with an empty single signature and returns
// the encoded transaction or an error if the unsigned transaction cannot be
// built.
Expand Down Expand Up @@ -437,7 +514,7 @@ func (f Factory) BuildSimTx(msgs ...sdk.Msg) ([]byte, error) {
func (f Factory) getSimPK() (cryptotypes.PubKey, error) {
var (
ok bool
pk cryptotypes.PubKey = &secp256k1.PubKey{} // use default public key type
pk cryptotypes.PubKey = &ethsecp256k1.PubKey{} // use default public key type
)

// Use the first element from the list of keys in order to generate a valid
Expand Down
4 changes: 4 additions & 0 deletions client/tx/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ func GenerateOrBroadcastTxWithFactory(clientCtx client.Context, txf Factory, msg
return txf.PrintUnsignedTx(clientCtx, msgs...)
}

if clientCtx.PrintEIP712MsgType {
return txf.PrintEIP712MsgType(clientCtx, msgs...)
}

return BroadcastTx(clientCtx, txf, msgs...)
}

Expand Down
4 changes: 2 additions & 2 deletions x/bank/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewSendTxCmd() *cobra.Command {
Short: "Send funds from one account to another.",
Long: `Send funds from one account to another.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
When using '--dry-run' a key name cannot be used, only a hex address.
`,
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -80,7 +80,7 @@ func NewMultiSendTxCmd() *cobra.Command {
By default, sends the [amount] to each address of the list.
Using the '--split' flag, the [amount] is split equally between the addresses.
Note, the '--from' flag is ignored as it is implied from [from_key_or_address].
When using '--dry-run' a key name cannot be used, only a bech32 address.
When using '--dry-run' a key name cannot be used, only a hex address.
`,
Args: cobra.MinimumNArgs(4),
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
Loading