Skip to content

Commit

Permalink
add /accounts endpoints but failing
Browse files Browse the repository at this point in the history
  • Loading branch information
faboweb authored and ebuchman committed Mar 17, 2018
1 parent 0d423ae commit 0121c98
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 42 deletions.
114 changes: 94 additions & 20 deletions client/lcd/lcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ func TestVersion(t *testing.T) {
}

func TestNodeStatus(t *testing.T) {
ch := server.StartServer(t)
defer close(ch)
_, _ = startServer(t)
// TODO need to kill server after
prepareClient(t)

cdc := app.MakeCodec()
Expand All @@ -153,8 +153,8 @@ func TestNodeStatus(t *testing.T) {
}

func TestBlock(t *testing.T) {
ch := server.StartServer(t)
defer close(ch)
_, _ = startServer(t)
// TODO need to kill server after
prepareClient(t)

cdc := app.MakeCodec()
Expand Down Expand Up @@ -184,9 +184,8 @@ func TestBlock(t *testing.T) {
}

func TestValidators(t *testing.T) {
ch := server.StartServer(t)
defer close(ch)

_, _ = startServer(t)
// TODO need to kill server after
prepareClient(t)
cdc := app.MakeCodec()
r := initRouter(cdc)
Expand Down Expand Up @@ -214,6 +213,67 @@ func TestValidators(t *testing.T) {
require.Equal(t, http.StatusNotFound, res.Code)
}

func TestCoinSend(t *testing.T) {
addr, seed := startServer(t)
// TODO need to kill server after
prepareClient(t)
cdc := app.MakeCodec()
r := initRouter(cdc)

// query empty
res := request(t, r, "GET", "/accounts/1234567890123456789012345678901234567890", nil)
require.Equal(t, http.StatusNoContent, res.Code, res.Body.String())

// query
res = request(t, r, "GET", "/accounts/"+addr.String(), nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())

assert.Equal(t, `{
"coins": [
{
"denom": "mycoin",
"amount": 9007199254740992
}
]
}`, res.Body.String())

// create account for default coins
var jsonStr = []byte(fmt.Sprintf(`{"name":"test", "password":"1234567890", "seed": "%s"}`, seed))
res = request(t, r, "POST", "/keys", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())

// create random account
res = request(t, r, "GET", "/keys/seed", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
receiveSeed := res.Body.String()

jsonStr = []byte(fmt.Sprintf(`{"name":"receive", "password":"1234567890", "seed": "%s"}`, receiveSeed))
res = request(t, r, "POST", "/keys", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
receiveAddr := res.Body.String()

// send
jsonStr = []byte(`{"name":"test", "password":"1234567890", "amount":[{
"denom": "mycoin",
"amount": 1
}]}`)
res = request(t, r, "POST", "/accounts/"+receiveAddr+"/send", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())

// check if received
res = request(t, r, "GET", "/accounts/"+receiveAddr, nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())

assert.Equal(t, `{
"coins": [
{
"denom": "mycoin",
"amount": 1
}
]
}`, res.Body.String())
}

//__________________________________________________________
// helpers

Expand All @@ -226,6 +286,8 @@ func prepareClient(t *testing.T) {
app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db)
viper.Set(client.FlagNode, "localhost:46657")

_ = client.GetKeyBase(db)

header := abci.Header{Height: 1}
app.BeginBlock(abci.RequestBeginBlock{Header: header})
app.Commit()
Expand All @@ -244,11 +306,31 @@ func setupViper() func() {
}
}

func startServer(t *testing.T) {
// from baseoind.main
func defaultOptions(addr string) func(args []string) (json.RawMessage, error) {
return func(args []string) (json.RawMessage, error) {
opts := fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "mycoin",
"amount": 9007199254740992
}
]
}]
}`, addr)
return json.RawMessage(opts), nil
}
}

func startServer(t *testing.T) (types.Address, string) {
defer setupViper()()
// init server
initCmd := server.InitCmd(mock.GenInitOptions, log.NewNopLogger())
err := initCmd.RunE(nil, nil)
addr, secret, err := server.GenerateCoinKey()
require.NoError(t, err)
initCmd := server.InitCmd(defaultOptions(addr.String()), log.NewNopLogger())
err = initCmd.RunE(nil, nil)
require.NoError(t, err)

// start server
Expand All @@ -258,6 +340,8 @@ func startServer(t *testing.T) {

err = runOrTimeout(startCmd, timeout)
require.NoError(t, err)

return addr, secret
}

// copied from server/start_test.go
Expand All @@ -281,16 +365,6 @@ func runOrTimeout(cmd *cobra.Command, timeout time.Duration) error {
}
}

func createKey(t *testing.T, r http.Handler) string {
var jsonStr = []byte(`{"name":"test", "password":"1234567890"}`)
res := request(t, r, "POST", "/keys", jsonStr)

assert.Equal(t, http.StatusOK, res.Code, res.Body.String())

addr := res.Body.String()
return addr
}

func request(t *testing.T, r http.Handler, method string, path string, payload []byte) *httptest.ResponseRecorder {
req, err := http.NewRequest(method, path, bytes.NewBuffer(payload))
require.Nil(t, err)
Expand Down
4 changes: 4 additions & 0 deletions client/lcd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
tx "github.com/cosmos/cosmos-sdk/client/tx"
version "github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/wire"
auth "github.com/cosmos/cosmos-sdk/x/auth/rest"
bank "github.com/cosmos/cosmos-sdk/x/bank/rest"
)

const (
Expand Down Expand Up @@ -52,5 +54,7 @@ func initRouter(cdc *wire.Codec) http.Handler {
keys.RegisterRoutes(r)
rpc.RegisterRoutes(r)
tx.RegisterRoutes(r, cdc)
auth.RegisterRoutes(r, cdc, "main")
bank.RegisterRoutes(r, cdc)
return r
}
4 changes: 2 additions & 2 deletions x/auth/commands/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (

// GetAccountCmd for the auth.BaseAccount type
func GetAccountCmdDefault(storeName string, cdc *wire.Codec) *cobra.Command {
return GetAccountCmd(storeName, cdc, getParseAccount(cdc))
return GetAccountCmd(storeName, cdc, GetParseAccount(cdc))
}

func getParseAccount(cdc *wire.Codec) sdk.ParseAccount {
func GetParseAccount(cdc *wire.Codec) sdk.ParseAccount {
return func(accBytes []byte) (sdk.Account, error) {
acct := new(auth.BaseAccount)
err := cdc.UnmarshalBinary(accBytes, &acct)
Expand Down
66 changes: 66 additions & 0 deletions x/auth/rest/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package rest

import (
"encoding/hex"
"encoding/json"
"fmt"
"net/http"

"github.com/gorilla/mux"

"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
)

type commander struct {
storeName string
cdc *wire.Codec
parser sdk.ParseAccount
}

func QueryAccountRequestHandler(storeName string, cdc *wire.Codec, parser sdk.ParseAccount) func(http.ResponseWriter, *http.Request) {
c := commander{storeName, cdc, parser}
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
addr := vars["address"]
bz, err := hex.DecodeString(addr)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
key := sdk.Address(bz)

res, err := client.Query(key, c.storeName)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Could't query account. Error: %s", err.Error())))
return
}

// the query will return empty if there is no data for this account
if len(res) == 0 {
w.WriteHeader(http.StatusNoContent)
return
}

// parse out the value
account, err := c.parser(res)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Could't parse query result. Result: %s. Error: %s", res, err.Error())))
return
}

// print out whole account
output, err := json.MarshalIndent(account, "", " ")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Could't marshall query result. Error: %s", err.Error())))
return
}

w.Write(output)
}
}
11 changes: 11 additions & 0 deletions x/auth/rest/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package rest

import (
"github.com/cosmos/cosmos-sdk/wire"
auth "github.com/cosmos/cosmos-sdk/x/auth/commands"
"github.com/gorilla/mux"
)

func RegisterRoutes(r *mux.Router, cdc *wire.Codec, storeName string) {
r.HandleFunc("/accounts/{address}", QueryAccountRequestHandler(storeName, cdc, auth.GetParseAccount(cdc))).Methods("GET")
}
61 changes: 41 additions & 20 deletions x/bank/commands/sendtx.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"github.com/cosmos/cosmos-sdk/client/builder"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"

"github.com/cosmos/cosmos-sdk/x/bank"
cryptokeys "github.com/tendermint/go-crypto/keys"
)

const (
Expand All @@ -20,8 +20,8 @@ const (
)

// SendTxCommand will create a send tx and sign it with the given key
func SendTxCmd(cdc *wire.Codec) *cobra.Command {
cmdr := commander{cdc}
func SendTxCmd(Cdc *wire.Codec) *cobra.Command {
cmdr := Commander{Cdc}
cmd := &cobra.Command{
Use: "send",
Short: "Create and sign a send tx",
Expand All @@ -32,18 +32,32 @@ func SendTxCmd(cdc *wire.Codec) *cobra.Command {
return cmd
}

type commander struct {
cdc *wire.Codec
type Commander struct {
Cdc *wire.Codec
}

func (c commander) sendTxCmd(cmd *cobra.Command, args []string) error {

func (c Commander) sendTxCmd(cmd *cobra.Command, args []string) error {
// get the from address
from, err := builder.GetFromAddress()
if err != nil {
return err
}

// parse coins
amount := viper.GetString(flagAmount)
coins, err := sdk.ParseCoins(amount)
if err != nil {
return err
}

// parse destination address
dest := viper.GetString(flagTo)
bz, err := hex.DecodeString(dest)
if err != nil {
return err
}
to := sdk.Address(bz)

// build send msg
msg, err := buildMsg(from)
if err != nil {
Expand All @@ -60,25 +74,32 @@ func (c commander) sendTxCmd(cmd *cobra.Command, args []string) error {
return nil
}

func buildMsg(from sdk.Address) (sdk.Msg, error) {
func BuildMsg(from sdk.Address, to sdk.Address, coins sdk.Coins) sdk.Msg {
input := bank.NewInput(from, coins)
output := bank.NewOutput(to, coins)
msg := bank.NewSendMsg([]bank.Input{input}, []bank.Output{output})
return msg
}

// parse coins
amount := viper.GetString(flagAmount)
coins, err := sdk.ParseCoins(amount)
func (c Commander) SignMessage(msg sdk.Msg, kb cryptokeys.Keybase, accountName string, password string) ([]byte, error) {
// sign and build
bz := msg.GetSignBytes()
sig, pubkey, err := kb.Sign(accountName, password, bz)
if err != nil {
return nil, err
}
sigs := []sdk.StdSignature{{
PubKey: pubkey,
Signature: sig,
Sequence: viper.GetInt64(flagSequence),
}}

// parse destination address
dest := viper.GetString(flagTo)
bz, err := hex.DecodeString(dest)
// marshal bytes
tx := sdk.NewStdTx(msg, sigs)

txBytes, err := c.Cdc.MarshalBinary(tx)
if err != nil {
return nil, err
}
to := sdk.Address(bz)

input := bank.NewInput(from, coins)
output := bank.NewOutput(to, coins)
msg := bank.NewSendMsg([]bank.Input{input}, []bank.Output{output})
return msg, nil
return txBytes, nil
}
10 changes: 10 additions & 0 deletions x/bank/rest/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package rest

import (
"github.com/cosmos/cosmos-sdk/wire"
"github.com/gorilla/mux"
)

func RegisterRoutes(r *mux.Router, cdc *wire.Codec) {
r.HandleFunc("/accounts/{address}/send", SendRequestHandler(cdc)).Methods("POST")
}
Loading

0 comments on commit 0121c98

Please sign in to comment.