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

chore: Experiment with gnoclient API #11

Closed
wants to merge 2 commits into from
Closed
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
218 changes: 6 additions & 212 deletions framework/call.go
Original file line number Diff line number Diff line change
@@ -1,68 +1,19 @@
package gnomobile

import (
"encoding/json"
"fmt"

"github.com/gnolang/gno/tm2/pkg/amino"
rpc_client "github.com/gnolang/gno/tm2/pkg/bft/rpc/client"
ctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/core/types"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/keys"
"github.com/gnolang/gno/tm2/pkg/errors"
"github.com/gnolang/gno/tm2/pkg/sdk/vm"
"github.com/gnolang/gno/tm2/pkg/std"
)

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/common.go
type BaseOptions struct {
Home string
Remote string
Quiet bool
InsecurePasswordStdin bool
Config string
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/root.go
type baseCfg struct {
BaseOptions
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/maketx.go
type makeTxCfg struct {
rootCfg *baseCfg

gasWanted int64
gasFee string
memo string

broadcast bool
chainID string
}

func (m *makeTxCfg) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
RootCfg *baseCfg

GasWanted int64
GasFee string
Memo string

Broadcast bool
ChainID string
}{
RootCfg: m.rootCfg,
GasWanted: m.gasWanted,
GasFee: m.gasFee,
Memo: m.memo,
Broadcast: m.broadcast,
ChainID: m.chainID,
})
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/query.go
type queryCfg struct {
rootCfg *baseCfg
remote string

data string
height int64
Expand All @@ -74,7 +25,7 @@ type queryCfg struct {

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/sign.go
type signCfg struct {
rootCfg *baseCfg
kb keys.Keybase

txPath string
chainID string
Expand All @@ -90,169 +41,17 @@ type signCfg struct {

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/broadcast.go
type broadcastCfg struct {
rootCfg *baseCfg
remote string

dryRun bool

// internal
tx *std.Tx
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/call.go
type callCfg struct {
rootCfg *makeTxCfg

send string
pkgPath string
funcName string
args commands.StringArr
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/call.go
func execCall(cfg *callCfg, nameOrBech32 string, password string) error {
if cfg.pkgPath == "" {
return errors.New("pkgpath not specified")
}
if cfg.funcName == "" {
return errors.New("func not specified")
}
if cfg.rootCfg.gasWanted == 0 {
return errors.New("gas-wanted not specified")
}
if cfg.rootCfg.gasFee == "" {
return errors.New("gas-fee not specified")
}

// read statement.
fnc := cfg.funcName

// read account pubkey.
kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.rootCfg.Home)
if err != nil {
return err
}
info, err := kb.GetByNameOrAddress(nameOrBech32)
if err != nil {
return err
}
caller := info.GetAddress()
// info.GetPubKey()

// Parse send amount.
send, err := std.ParseCoins(cfg.send)
if err != nil {
return errors.Wrap(err, "parsing send coins")
}

// parse gas wanted & fee.
gaswanted := cfg.rootCfg.gasWanted
gasfee, err := std.ParseCoin(cfg.rootCfg.gasFee)
if err != nil {
return errors.Wrap(err, "parsing gas fee coin")
}

// construct msg & tx and marshal.
msg := vm.MsgCall{
Caller: caller,
Send: send,
PkgPath: cfg.pkgPath,
Func: fnc,
Args: cfg.args,
}
tx := std.Tx{
Msgs: []std.Msg{msg},
Fee: std.NewFee(gaswanted, gasfee),
Signatures: nil,
Memo: cfg.rootCfg.memo,
}

if cfg.rootCfg.broadcast {
err := signAndBroadcast(cfg.rootCfg, tx, kb, nameOrBech32, password)
if err != nil {
return err
}
} else {
errors.New(string(amino.MustMarshalJSON(tx)))
}
return nil
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/addpkg.go
func signAndBroadcast(
cfg *makeTxCfg,
tx std.Tx,
kb keys.Keybase,
nameOrBech32 string,
password string,
) error {
baseopts := cfg.rootCfg
txopts := cfg

// query account
kb, err := keys.NewKeyBaseFromDir(baseopts.Home)
if err != nil {
return err
}
info, err := kb.GetByNameOrAddress(nameOrBech32)
if err != nil {
return err
}
accountAddr := info.GetAddress()

qopts := &queryCfg{
rootCfg: baseopts,
path: fmt.Sprintf("auth/accounts/%s", accountAddr),
}
qres, err := queryHandler(qopts)
if err != nil {
return errors.Wrap(err, "query account")
}
var qret struct{ BaseAccount std.BaseAccount }
err = amino.UnmarshalJSON(qres.Response.Data, &qret)
if err != nil {
return err
}

// sign tx
accountNumber := qret.BaseAccount.AccountNumber
sequence := qret.BaseAccount.Sequence
sopts := &signCfg{
rootCfg: baseopts,
sequence: sequence,
accountNumber: accountNumber,
chainID: txopts.chainID,
nameOrBech32: nameOrBech32,
txJSON: amino.MustMarshalJSON(tx),
pass: password,
}

signedTx, err := SignHandler(sopts)
if err != nil {
return errors.Wrap(err, "sign tx")
}

// broadcast signed tx
bopts := &broadcastCfg{
rootCfg: baseopts,
tx: signedTx,
}
bres, err := broadcastHandler(bopts)
if err != nil {
return errors.Wrap(err, "broadcast tx")
}
if bres.CheckTx.IsErr() {
return errors.Wrap(bres.CheckTx.Error, "check transaction failed: log:%s", bres.CheckTx.Log)
}
if bres.DeliverTx.IsErr() {
return errors.Wrap(bres.DeliverTx.Error, "deliver transaction failed: log:%s", bres.DeliverTx.Log)
}

return nil
}

// From https://github.com/gnolang/gno/blob/master/tm2/pkg/crypto/keys/client/query.go
func queryHandler(cfg *queryCfg) (*ctypes.ResultABCIQuery, error) {
remote := cfg.rootCfg.Remote
remote := cfg.remote
if remote == "" || remote == "y" {
return nil, errors.New("missing remote url")
}
Expand All @@ -278,7 +77,7 @@ func broadcastHandler(cfg *broadcastCfg) (*ctypes.ResultBroadcastTxCommit, error
return nil, errors.New("invalid tx")
}

remote := cfg.rootCfg.Remote
remote := cfg.remote
if remote == "" || remote == "y" {
return nil, errors.New("missing remote url")
}
Expand Down Expand Up @@ -314,11 +113,6 @@ func SignHandler(cfg *signCfg) (*std.Tx, error) {
return nil, errors.New("invalid tx content")
}

kb, err := keys.NewKeyBaseFromDir(cfg.rootCfg.Home)
if err != nil {
return nil, err
}

err = amino.UnmarshalJSON(cfg.txJSON, &tx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -351,7 +145,7 @@ func SignHandler(cfg *signCfg) (*std.Tx, error) {
return nil, nil
}

sig, pub, err := kb.Sign(cfg.nameOrBech32, cfg.pass, signbz)
sig, pub, err := cfg.kb.Sign(cfg.nameOrBech32, cfg.pass, signbz)
if err != nil {
return nil, err
}
Expand Down
Loading