diff --git a/go/go.mod b/go/go.mod index ed77d18b..56952e2a 100644 --- a/go/go.mod +++ b/go/go.mod @@ -5,6 +5,7 @@ go 1.22.2 toolchain go1.22.5 require ( + cosmossdk.io/api v0.3.1 cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/99designs/keyring v1.2.2 @@ -65,7 +66,6 @@ replace ( ) require ( - cosmossdk.io/api v0.3.1 // indirect cosmossdk.io/core v0.5.1 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -175,6 +175,7 @@ require ( golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect diff --git a/go/node/client/client.go b/go/node/client/client.go index 29785cbf..7a58f223 100644 --- a/go/node/client/client.go +++ b/go/node/client/client.go @@ -19,7 +19,7 @@ var ( const ( // DefaultClientAPIVersion indicates the default ApiVersion of the client. - DefaultClientAPIVersion = "v1beta2" + DefaultClientAPIVersion = "v1beta3" VersionV1beta3 = "v1beta3" ) @@ -33,26 +33,32 @@ type SetupFn func(interface{}) error // DefaultClientApiVersion will be used. // An error is returned if client discovery is not successful. func DiscoverClient(ctx context.Context, cctx sdkclient.Context, setup SetupFn, opts ...cltypes.ClientOption) error { - rpc, err := tmjclient.New(cctx.NodeURI) - if err != nil { - return err - } - result := new(Akash) - if !cctx.Offline { - params := make(map[string]interface{}) - _, _ = rpc.Call(ctx, "akash", params, result) - } - - // if client info is nil, mostly likely "akash" endpoint is not yet supported on the node - // fallback to manually set version to DefaultClientApiVersion - if result.ClientInfo == nil || cctx.Offline { + if cctx.Client == nil { + rpc, err := tmjclient.New(cctx.NodeURI) + if err != nil { + return err + } + + if !cctx.Offline { + params := make(map[string]interface{}) + _, _ = rpc.Call(ctx, "akash", params, result) + } + + // if client info is nil, mostly likely "akash" endpoint is not yet supported on the node + // fallback to manually set version to DefaultClientApiVersion + if result.ClientInfo == nil || cctx.Offline { + result.ClientInfo = &ClientInfo{ApiVersion: DefaultClientAPIVersion} + } + } else { result.ClientInfo = &ClientInfo{ApiVersion: DefaultClientAPIVersion} } var cl interface{} + var err error + switch result.ClientInfo.ApiVersion { case VersionV1beta3: cl, err = v1beta3.NewClient(ctx, cctx, opts...) @@ -72,25 +78,30 @@ func DiscoverClient(ctx context.Context, cctx sdkclient.Context, setup SetupFn, } func DiscoverLightClient(ctx context.Context, cctx sdkclient.Context, setup SetupFn) error { - rpc, err := tmjclient.New(cctx.NodeURI) - if err != nil { - return err - } - result := new(Akash) - if !cctx.Offline { - params := make(map[string]interface{}) - _, _ = rpc.Call(ctx, "akash", params, result) - } - - // if client info is nil, mostly likely "akash" endpoint is not yet supported on the node - // fallback to manually set version to DefaultClientApiVersion - if result.ClientInfo == nil || cctx.Offline { + if cctx.Client == nil { + rpc, err := tmjclient.New(cctx.NodeURI) + if err != nil { + return err + } + + if !cctx.Offline { + params := make(map[string]interface{}) + _, _ = rpc.Call(ctx, "akash", params, result) + } + + // if client info is nil, mostly likely "akash" endpoint is not yet supported on the node + // fallback to manually set version to DefaultClientApiVersion + if result.ClientInfo == nil || cctx.Offline { + result.ClientInfo = &ClientInfo{ApiVersion: DefaultClientAPIVersion} + } + } else { result.ClientInfo = &ClientInfo{ApiVersion: DefaultClientAPIVersion} } var cl interface{} + var err error switch result.ClientInfo.ApiVersion { case VersionV1beta3: diff --git a/go/node/client/types/options.go b/go/node/client/types/options.go index 0d888f23..52934abd 100644 --- a/go/node/client/types/options.go +++ b/go/node/client/types/options.go @@ -46,6 +46,7 @@ type ClientOptions struct { TimeoutHeight uint64 BroadcastTimeout time.Duration SkipConfirm bool + SignMode string } type ClientOption func(options *ClientOptions) error @@ -60,26 +61,8 @@ func NewTxFactory(cctx client.Context, opts ...ClientOption) (tx.Factory, error) } } - var signMode signing.SignMode - - switch cctx.SignModeStr { - case SignModeDirect: - signMode = signing.SignMode_SIGN_MODE_DIRECT - case SignModeLegacyAminoJSON: - signMode = signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON - case SignModeEIP191: - signMode = signing.SignMode_SIGN_MODE_EIP_191 - default: - return tx.Factory{}, fmt.Errorf("invalid sign mode \"%s\". expected %s|%s|%s", - cctx.SignModeStr, - SignModeDirect, - SignModeLegacyAminoJSON, - SignModeEIP191) - } - - txf := tx.Factory{} - - txf = txf.WithTxConfig(cctx.TxConfig). + txf := tx.Factory{}. + WithTxConfig(cctx.TxConfig). WithAccountRetriever(cctx.AccountRetriever). WithAccountNumber(clOpts.AccountNumber). WithSequence(clOpts.AccountSequence). @@ -91,8 +74,31 @@ func NewTxFactory(cctx client.Context, opts ...ClientOption) (tx.Factory, error) WithSimulateAndExecute(clOpts.Gas.Simulate). WithTimeoutHeight(clOpts.TimeoutHeight). WithMemo(clOpts.Note). - WithSignMode(signMode). - WithFees(clOpts.Fees) + WithFees(clOpts.Fees). + WithFromName(cctx.FromName) + + if !cctx.GenerateOnly { + var signMode signing.SignMode + + switch cctx.SignModeStr { + case SignModeDirect: + signMode = signing.SignMode_SIGN_MODE_DIRECT + case SignModeDirectAux: + signMode = signing.SignMode_SIGN_MODE_DIRECT_AUX + case SignModeLegacyAminoJSON: + signMode = signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON + case SignModeEIP191: + signMode = signing.SignMode_SIGN_MODE_EIP_191 + default: + return tx.Factory{}, fmt.Errorf("invalid sign mode \"%s\". expected %s|%s|%s", + cctx.SignModeStr, + SignModeDirect, + SignModeLegacyAminoJSON, + SignModeEIP191) + } + + txf = txf.WithSignMode(signMode) + } if !cctx.Offline { address := cctx.GetFromAddress() @@ -176,3 +182,10 @@ func WithSkipConfirm(val bool) ClientOption { return nil } } + +func WithSignMode(val string) ClientOption { + return func(options *ClientOptions) error { + options.SignMode = val + return nil + } +} diff --git a/go/node/client/v1beta3/client.go b/go/node/client/v1beta3/client.go index 1a6e57e4..7d4933f6 100644 --- a/go/node/client/v1beta3/client.go +++ b/go/node/client/v1beta3/client.go @@ -110,17 +110,18 @@ var ( // NewClient creates a new client. func NewClient(ctx context.Context, cctx sdkclient.Context, opts ...cltypes.ClientOption) (Client, error) { + nd := newNode(cctx) + tcl, cctx, err := newSerialTx(ctx, cctx, nd, opts...) + if err != nil { + return nil, err + } + cl := &client{ lightClient: lightClient{ qclient: newQueryClient(cctx), - node: newNode(cctx), + node: nd, }, - } - - var err error - cl.tx, err = newSerialTx(ctx, cctx, cl.node, opts...) - if err != nil { - return nil, err + tx: tcl, } return cl, nil @@ -165,6 +166,8 @@ func (cl *lightClient) PrintMessage(msg interface{}) error { err = cl.qclient.cctx.PrintProto(m) case []byte: err = cl.qclient.cctx.PrintString(fmt.Sprintf("%s\n", string(m))) + default: + err = cl.qclient.cctx.PrintObjectLegacy(m) } return err diff --git a/go/node/client/v1beta3/tx.go b/go/node/client/v1beta3/tx.go index c8a45087..b8715b49 100644 --- a/go/node/client/v1beta3/tx.go +++ b/go/node/client/v1beta3/tx.go @@ -232,27 +232,48 @@ type serialBroadcaster struct { log log.Logger } -func newSerialTx(ctx context.Context, cctx sdkclient.Context, nd *node, opts ...cltypes.ClientOption) (*serialBroadcaster, error) { - if err := validateBroadcastMode(cctx.BroadcastMode); err != nil { - return nil, err +func newSerialTx(ctx context.Context, cctx sdkclient.Context, nd *node, opts ...cltypes.ClientOption) (*serialBroadcaster, sdkclient.Context, error) { + if !cctx.GenerateOnly { + if err := validateBroadcastMode(cctx.BroadcastMode); err != nil { + return nil, cctx, err + } } - txf, err := cltypes.NewTxFactory(cctx, opts...) - if err != nil { - return nil, err + key := cctx.From + if key == "" { + key = cctx.FromName } - keyname := cctx.GetFromName() - info, err := txf.Keybase().Key(keyname) + info, err := cctx.Keyring.Key(key) if err != nil { - info, err = txf.Keybase().KeyByAddress(cctx.GetFromAddress()) + info, err = cctx.Keyring.KeyByAddress(cctx.GetFromAddress()) } if err != nil { - return nil, err + return nil, cctx, err } - txf = txf.WithFromName(info.Name) + if cctx.FromAddress == nil { + addr, err := info.GetAddress() + if err != nil { + return nil, cctx, err + } + + cctx = cctx.WithFromAddress(addr) + } + + if cctx.From == "" { + cctx = cctx.WithFrom(info.Name) + } + + if cctx.FromName == "" { + cctx = cctx.WithFromName(info.Name) + } + + txf, err := cltypes.NewTxFactory(cctx, opts...) + if err != nil { + return nil, cctx, err + } client := &serialBroadcaster{ ctx: ctx, @@ -274,7 +295,7 @@ func newSerialTx(ctx context.Context, cctx sdkclient.Context, nd *node, opts ... go client.sequenceSync() } - return client, nil + return client, cctx, nil } // BroadcastMsgs builds and broadcasts transaction. Thi transaction is composed of 1 or many messages. This allows several @@ -548,6 +569,15 @@ func (c *serialBroadcaster) buildAndBroadcastTx(ctx context.Context, ptxf client utx.SetFeeGranter(gAddr) } + if cctx.GenerateOnly { + txb, err := cctx.TxConfig.TxJSONEncoder()(utx.GetTx()) + if err != nil { + return nil, ptxf.Sequence(), err + } + + return txb, ptxf.Sequence(), nil + } + if !cctx.SkipConfirm { var out []byte if out, err = cctx.TxConfig.TxJSONEncoder()(utx.GetTx()); err != nil {