add /accounts endpoints but failing
This commit is contained in:
parent
0d423ae066
commit
0121c98a1e
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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 (
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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 (
|
||||
|
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -60,25 +74,32 @@ func (c commander) sendTxCmd(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func buildMsg(from sdk.Address) (sdk.Msg, error) {
|
||||
|
||||
// parse coins
|
||||
amount := viper.GetString(flagAmount)
|
||||
coins, err := sdk.ParseCoins(amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse destination address
|
||||
dest := viper.GetString(flagTo)
|
||||
bz, err := hex.DecodeString(dest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
to := sdk.Address(bz)
|
||||
|
||||
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, nil
|
||||
return msg
|
||||
}
|
||||
|
||||
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),
|
||||
}}
|
||||
|
||||
// marshal bytes
|
||||
tx := sdk.NewStdTx(msg, sigs)
|
||||
|
||||
txBytes, err := c.Cdc.MarshalBinary(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return txBytes, nil
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/commands"
|
||||
)
|
||||
|
||||
type SendBody struct {
|
||||
// fees is not used currently
|
||||
// Fees sdk.Coin `json="fees"`
|
||||
Amount sdk.Coins `json="amount"`
|
||||
LocalAccountName string `json="account"`
|
||||
Password string `json="password"`
|
||||
}
|
||||
|
||||
func SendRequestHandler(cdc *wire.Codec) func(http.ResponseWriter, *http.Request) {
|
||||
c := commands.Commander{cdc}
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// collect data
|
||||
vars := mux.Vars(r)
|
||||
address := vars["address"]
|
||||
|
||||
var m SendBody
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&m)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
kb, err := keys.GetKeyBase()
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
info, err := kb.Get(m.LocalAccountName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
bz, err := hex.DecodeString(address)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
to := sdk.Address(bz)
|
||||
|
||||
// build
|
||||
msg := commands.BuildMsg(info.Address(), to, m.Amount)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// sign
|
||||
txBytes, err := c.SignMessage(msg, kb, m.LocalAccountName, m.Password)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// send
|
||||
res, err := client.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
output, err := json.MarshalIndent(res, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue