Merge branch 'develop' into cwgoes/nextvalset

This commit is contained in:
Christopher Goes 2018-10-09 06:33:19 +02:00
commit 9c53f5aadf
14 changed files with 507 additions and 160 deletions

View File

@ -90,7 +90,7 @@ FEATURES
* [gaia-lite] [\#966](https://github.com/cosmos/cosmos-sdk/issues/966) Add support for `generate_only=true` query argument to generate offline unsigned transactions * [gaia-lite] [\#966](https://github.com/cosmos/cosmos-sdk/issues/966) Add support for `generate_only=true` query argument to generate offline unsigned transactions
* [gaia-lite] [\#1953](https://github.com/cosmos/cosmos-sdk/issues/1953) Add /sign endpoint to sign transactions generated with `generate_only=true`. * [gaia-lite] [\#1953](https://github.com/cosmos/cosmos-sdk/issues/1953) Add /sign endpoint to sign transactions generated with `generate_only=true`.
* [gaia-lite] [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) Add /broadcast endpoint to broadcast transactions signed by the /sign endpoint. * [gaia-lite] [\#1954](https://github.com/cosmos/cosmos-sdk/issues/1954) Add /broadcast endpoint to broadcast transactions signed by the /sign endpoint.
* [gaia-lite] [\#2113](https://github.com/cosmos/cosmos-sdk/issues/2113) Rename `/accounts/{address}/send` to `/bank/accounts/{address}/transfers` * [gaia-lite] [\#2113](https://github.com/cosmos/cosmos-sdk/issues/2113) Rename `/accounts/{address}/send` to `/bank/accounts/{address}/transfers`, rename `/accounts/{address}` to `/auth/accounts/{address}`
* Gaia CLI (`gaiacli`) * Gaia CLI (`gaiacli`)
* [cli] Cmds to query staking pool and params * [cli] Cmds to query staking pool and params

View File

@ -8,7 +8,6 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -61,7 +60,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
name = "inmemorykey" name = "inmemorykey"
} else { } else {
if len(args) != 1 || len(args[0]) == 0 { if len(args) != 1 || len(args[0]) == 0 {
return errors.New("you must provide a name for the key") return errMissingName()
} }
name = args[0] name = args[0]
kb, err = GetKeyBase() kb, err = GetKeyBase()
@ -144,11 +143,16 @@ func printCreate(info keys.Info, seed string) {
if !viper.GetBool(flagNoBackup) { if !viper.GetBool(flagNoBackup) {
out.Seed = seed out.Seed = seed
} }
json, err := MarshalJSON(out) var jsonString []byte
if viper.GetBool(client.FlagIndentResponse) {
jsonString, err = cdc.MarshalJSONIndent(out, "", " ")
} else {
jsonString, err = cdc.MarshalJSON(out)
}
if err != nil { if err != nil {
panic(err) // really shouldn't happen... panic(err) // really shouldn't happen...
} }
fmt.Println(string(json)) fmt.Println(string(jsonString))
default: default:
panic(fmt.Sprintf("I can't speak: %s", output)) panic(fmt.Sprintf("I can't speak: %s", output))
} }
@ -165,20 +169,25 @@ type NewKeyBody struct {
} }
// add new key REST handler // add new key REST handler
func AddNewKeyRequestHandler(w http.ResponseWriter, r *http.Request) { func AddNewKeyRequestHandler(indent bool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var kb keys.Keybase var kb keys.Keybase
var m NewKeyBody var m NewKeyBody
kb, err := GetKeyBase() kb, err := GetKeyBase()
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
err = json.Unmarshal(body, &m) err = json.Unmarshal(body, &m)
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
@ -186,21 +195,24 @@ func AddNewKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
} }
if m.Name == "" { if m.Name == "" {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("You have to specify a name for the locally stored account.")) err = errMissingName()
w.Write([]byte(err.Error()))
return return
} }
if m.Password == "" { if m.Password == "" {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("You have to specify a password for the locally stored account.")) err = errMissingPassword()
w.Write([]byte(err.Error()))
return return
} }
// check if already exists // check if already exists
infos, err := kb.List() infos, err := kb.List()
for _, i := range infos { for _, info := range infos {
if i.GetName() == m.Name { if info.GetName() == m.Name {
w.WriteHeader(http.StatusConflict) w.WriteHeader(http.StatusConflict)
w.Write([]byte(fmt.Sprintf("Account with name %s already exists.", m.Name))) err = errKeyNameConflict(m.Name)
w.Write([]byte(err.Error()))
return return
} }
} }
@ -226,16 +238,9 @@ func AddNewKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
keyOutput.Seed = seed keyOutput.Seed = seed
bz, err := json.Marshal(keyOutput) PostProcessResponse(w, cdc, keyOutput, indent)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
} }
w.Write(bz)
} }
// function to just a new seed to display in the UI before actually persisting it in the keybase // function to just a new seed to display in the UI before actually persisting it in the keybase
func getSeed(algo keys.SigningAlgo) string { func getSeed(algo keys.SigningAlgo) string {
kb := client.MockKeyBase() kb := client.MockKeyBase()
@ -258,3 +263,82 @@ func SeedRequestHandler(w http.ResponseWriter, r *http.Request) {
seed := getSeed(algo) seed := getSeed(algo)
w.Write([]byte(seed)) w.Write([]byte(seed))
} }
// RecoverKeyBody is recover key request REST body
type RecoverKeyBody struct {
Password string `json:"password"`
Seed string `json:"seed"`
}
// RecoverRequestHandler performs key recover request
func RecoverRequestHandler(indent bool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
name := vars["name"]
var m RecoverKeyBody
body, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
err = cdc.UnmarshalJSON(body, &m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}
if name == "" {
w.WriteHeader(http.StatusBadRequest)
err = errMissingName()
w.Write([]byte(err.Error()))
return
}
if m.Password == "" {
w.WriteHeader(http.StatusBadRequest)
err = errMissingPassword()
w.Write([]byte(err.Error()))
return
}
if m.Seed == "" {
w.WriteHeader(http.StatusBadRequest)
err = errMissingSeed()
w.Write([]byte(err.Error()))
return
}
kb, err := GetKeyBase()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
// check if already exists
infos, err := kb.List()
for _, info := range infos {
if info.GetName() == name {
w.WriteHeader(http.StatusConflict)
err = errKeyNameConflict(name)
w.Write([]byte(err.Error()))
return
}
}
info, err := kb.CreateKey(name, m.Seed, m.Password)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
keyOutput, err := Bech32KeyOutput(info)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
PostProcessResponse(w, cdc, keyOutput, indent)
}
}

View File

@ -68,14 +68,14 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body) decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&m) err := decoder.Decode(&m)
if err != nil { if err != nil {
w.WriteHeader(400) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
kb, err = GetKeyBase() kb, err = GetKeyBase()
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
@ -83,10 +83,10 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
// TODO handle error if key is not available or pass is wrong // TODO handle error if key is not available or pass is wrong
err = kb.Delete(name, m.Password) err = kb.Delete(name, m.Password)
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
w.WriteHeader(200) w.WriteHeader(http.StatusOK)
} }

19
client/keys/errors.go Normal file
View File

@ -0,0 +1,19 @@
package keys
import "fmt"
func errKeyNameConflict(name string) error {
return fmt.Errorf("acount with name %s already exists", name)
}
func errMissingName() error {
return fmt.Errorf("you have to specify a name for the locally stored account")
}
func errMissingPassword() error {
return fmt.Errorf("you have to specify a password for the locally stored account")
}
func errMissingSeed() error {
return fmt.Errorf("you have to specify seed for key recover")
}

View File

@ -1,7 +1,6 @@
package keys package keys
import ( import (
"encoding/json"
"net/http" "net/http"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -35,35 +34,31 @@ func runListCmd(cmd *cobra.Command, args []string) error {
// REST // REST
// query key list REST handler // query key list REST handler
func QueryKeysRequestHandler(w http.ResponseWriter, r *http.Request) { func QueryKeysRequestHandler(indent bool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
kb, err := GetKeyBase() kb, err := GetKeyBase()
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
infos, err := kb.List() infos, err := kb.List()
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
// an empty list will be JSONized as null, but we want to keep the empty list // an empty list will be JSONized as null, but we want to keep the empty list
if len(infos) == 0 { if len(infos) == 0 {
w.Write([]byte("[]")) PostProcessResponse(w, cdc, "[]", indent)
return return
} }
keysOutput, err := Bech32KeysOutput(infos) keysOutput, err := Bech32KeysOutput(infos)
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
output, err := json.MarshalIndent(keysOutput, "", " ") PostProcessResponse(w, cdc, keysOutput, indent)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
} }
w.Write(output)
} }

View File

@ -30,11 +30,12 @@ func Commands() *cobra.Command {
} }
// resgister REST routes // resgister REST routes
func RegisterRoutes(r *mux.Router) { func RegisterRoutes(r *mux.Router, indent bool) {
r.HandleFunc("/keys", QueryKeysRequestHandler).Methods("GET") r.HandleFunc("/keys", QueryKeysRequestHandler(indent)).Methods("GET")
r.HandleFunc("/keys", AddNewKeyRequestHandler).Methods("POST") r.HandleFunc("/keys", AddNewKeyRequestHandler(indent)).Methods("POST")
r.HandleFunc("/keys/seed", SeedRequestHandler).Methods("GET") r.HandleFunc("/keys/seed", SeedRequestHandler).Methods("GET")
r.HandleFunc("/keys/{name}", GetKeyRequestHandler).Methods("GET") r.HandleFunc("/keys/{name}/recover", RecoverRequestHandler(indent)).Methods("POST")
r.HandleFunc("/keys/{name}", GetKeyRequestHandler(indent)).Methods("GET")
r.HandleFunc("/keys/{name}", UpdateKeyRequestHandler).Methods("PUT") r.HandleFunc("/keys/{name}", UpdateKeyRequestHandler).Methods("PUT")
r.HandleFunc("/keys/{name}", DeleteKeyRequestHandler).Methods("DELETE") r.HandleFunc("/keys/{name}", DeleteKeyRequestHandler).Methods("DELETE")
} }

View File

@ -1,7 +1,6 @@
package keys package keys
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
@ -91,7 +90,8 @@ func getBechKeyOut(bechPrefix string) (bechKeyOutFn, error) {
// REST // REST
// get key REST handler // get key REST handler
func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) { func GetKeyRequestHandler(indent bool) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
name := vars["name"] name := vars["name"]
bechPrefix := r.URL.Query().Get(FlagBechPrefix) bechPrefix := r.URL.Query().Get(FlagBechPrefix)
@ -102,7 +102,7 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
bechKeyOut, err := getBechKeyOut(bechPrefix) bechKeyOut, err := getBechKeyOut(bechPrefix)
if err != nil { if err != nil {
w.WriteHeader(400) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
@ -111,24 +111,18 @@ func GetKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
// TODO: check for the error if key actually does not exist, instead of // TODO: check for the error if key actually does not exist, instead of
// assuming this as the reason // assuming this as the reason
if err != nil { if err != nil {
w.WriteHeader(404) w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
keyOutput, err := bechKeyOut(info) keyOutput, err := bechKeyOut(info)
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
output, err := json.MarshalIndent(keyOutput, "", " ") PostProcessResponse(w, cdc, keyOutput, indent)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
} }
w.Write(output)
} }

View File

@ -69,14 +69,14 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body) decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&m) err := decoder.Decode(&m)
if err != nil { if err != nil {
w.WriteHeader(400) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
kb, err = GetKeyBase() kb, err = GetKeyBase()
if err != nil { if err != nil {
w.WriteHeader(500) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
@ -86,10 +86,10 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
// TODO check if account exists and if password is correct // TODO check if account exists and if password is correct
err = kb.Update(name, m.OldPassword, getNewpass) err = kb.Update(name, m.OldPassword, getNewpass)
if err != nil { if err != nil {
w.WriteHeader(401) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error())) w.Write([]byte(err.Error()))
return return
} }
w.WriteHeader(200) w.WriteHeader(http.StatusOK)
} }

View File

@ -13,6 +13,8 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"net/http"
"github.com/cosmos/cosmos-sdk/codec"
) )
// KeyDBName is the directory under root where we store the keys // KeyDBName is the directory under root where we store the keys
@ -231,3 +233,26 @@ func printPubKey(info keys.Info, bechKeyOut bechKeyOutFn) {
fmt.Println(ko.PubKey) fmt.Println(ko.PubKey)
} }
// PostProcessResponse performs post process for rest response
func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response interface{}, indent bool) {
var output []byte
switch response.(type) {
default:
var err error
if indent {
output, err = cdc.MarshalJSONIndent(response, "", " ")
} else {
output, err = cdc.MarshalJSON(response)
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}
case []byte:
output = response.([]byte)
}
w.Header().Set("Content-Type", "application/json")
w.Write(output)
}

View File

@ -54,9 +54,13 @@ func TestKeys(t *testing.T) {
match := reg.MatchString(seed) match := reg.MatchString(seed)
require.True(t, match, "Returned seed has wrong format", seed) require.True(t, match, "Returned seed has wrong format", seed)
// recover key
recoverName := "test_recovername"
recoverPassword := "1234567890"
doRecoverKey(t, port, recoverName, recoverPassword, seed)
newName := "test_newname" newName := "test_newname"
newPassword := "0987654321" newPassword := "0987654321"
// add key // add key
jsonStr := []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed":"%s"}`, newName, newPassword, seed)) jsonStr := []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed":"%s"}`, newName, newPassword, seed))
res, body = Request(t, port, "POST", "/keys", jsonStr) res, body = Request(t, port, "POST", "/keys", jsonStr)
@ -78,7 +82,7 @@ func TestKeys(t *testing.T) {
// existing keys // existing keys
res, body = Request(t, port, "GET", "/keys", nil) res, body = Request(t, port, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body) require.Equal(t, http.StatusOK, res.StatusCode, body)
var m [2]keys.KeyOutput var m [3]keys.KeyOutput
err = cdc.UnmarshalJSON([]byte(body), &m) err = cdc.UnmarshalJSON([]byte(body), &m)
require.Nil(t, err) require.Nil(t, err)
@ -243,7 +247,7 @@ func TestCoinSend(t *testing.T) {
someFakeAddr := sdk.AccAddress(bz) someFakeAddr := sdk.AccAddress(bz)
// query empty // query empty
res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", someFakeAddr), nil) res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", someFakeAddr), nil)
require.Equal(t, http.StatusNoContent, res.StatusCode, body) require.Equal(t, http.StatusNoContent, res.StatusCode, body)
acc := getAccount(t, port, addr) acc := getAccount(t, port, addr)
@ -802,7 +806,7 @@ func TestProposalsQuery(t *testing.T) {
//_____________________________________________________________________________ //_____________________________________________________________________________
// get the account to get the sequence // get the account to get the sequence
func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account { func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account {
res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", addr), nil) res, body := Request(t, port, "GET", fmt.Sprintf("/auth/accounts/%s", addr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body) require.Equal(t, http.StatusOK, res.StatusCode, body)
var acc auth.Account var acc auth.Account
err := cdc.UnmarshalJSON([]byte(body), &acc) err := cdc.UnmarshalJSON([]byte(body), &acc)
@ -856,6 +860,20 @@ func doSendWithGas(t *testing.T, port, seed, name, password string, addr sdk.Acc
return return
} }
func doRecoverKey(t *testing.T, port, recoverName, recoverPassword, seed string) {
jsonStr := []byte(fmt.Sprintf(`{"password":"%s", "seed":"%s"}`, recoverPassword, seed))
res, body := Request(t, port, "POST", fmt.Sprintf("/keys/%s/recover", recoverName), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var resp keys.KeyOutput
err := codec.Cdc.UnmarshalJSON([]byte(body), &resp)
require.Nil(t, err, body)
addr1Bech32 := resp.Address
_, err = sdk.AccAddressFromBech32(addr1Bech32)
require.NoError(t, err, "Failed to return a correct bech32 address")
}
func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) { func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
res, body, receiveAddr := doSendWithGas(t, port, seed, name, password, addr, "", 0, "") res, body, receiveAddr := doSendWithGas(t, port, seed, name, password, addr, "", 0, "")
require.Equal(t, http.StatusOK, res.StatusCode, body) require.Equal(t, http.StatusOK, res.StatusCode, body)

View File

@ -145,7 +145,7 @@ func createHandler(cdc *codec.Codec) *mux.Router {
r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET") r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET")
r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET") r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET")
keys.RegisterRoutes(r) keys.RegisterRoutes(r, cliCtx.Indent)
rpc.RegisterRoutes(cliCtx, r) rpc.RegisterRoutes(cliCtx, r)
tx.RegisterRoutes(cliCtx, r, cdc) tx.RegisterRoutes(cliCtx, r, cdc)
auth.RegisterRoutes(cliCtx, r, cdc, "acc") auth.RegisterRoutes(cliCtx, r, cdc, "acc")

View File

@ -346,6 +346,184 @@ paths:
$ref: "#/definitions/BroadcastTxCommitResult" $ref: "#/definitions/BroadcastTxCommitResult"
400: 400:
description: The Tx was malformated description: The Tx was malformated
/keys:
get:
summary: List of accounts stored locally
tags:
- ICS1
produces:
- application/json
responses:
200:
description: Array of accounts
schema:
type: array
items:
$ref: '#/definitions/Account'
post:
summary: Create a new account locally
tags:
- ICS1
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: account
description: The account to create
schema:
type: object
required:
- name
- password
- seed
properties:
name:
type: string
password:
type: string
seed:
type: string
responses:
200:
description: Returns account information of the created key
schema:
$ref: "#/definitions/Account"
/keys/seed:
get:
summary: Create a new seed to create a new account with
tags:
- ICS1
responses:
200:
description: 16 word Seed
schema:
type: string
/keys/{name}/recover:
post:
summary: Recover a account from a seed
tags:
- ICS1
consumes:
- application/json
produces:
- application/json
parameters:
- in: path
name: name
description: Account name
required: true
type: string
- in: body
name: pwdAndSeed
description: Provide password and seed to recover a key
schema:
type: object
required:
- password
- seed
properties:
password:
type: string
seed:
type: string
responses:
200:
description: Returns account information of the recovered key
schema:
$ref: "#/definitions/Account"
/keys/{name}:
parameters:
- in: path
name: name
description: Account name
required: true
type: string
get:
summary: Get a certain locally stored account
tags:
- ICS1
produces:
- application/json
responses:
200:
description: Locally stored account
schema:
$ref: "#/definitions/Account"
404:
description: Account is not available
put:
summary: Update the password for this account in the KMS
tags:
- ICS1
consumes:
- application/json
parameters:
- in: body
name: account
description: The new and old password
schema:
type: object
required:
- new_password
- old_password
properties:
new_password:
type: string
old_password:
type: string
responses:
200:
description: Updated password
401:
description: Password is wrong
404:
description: Account is not available
delete:
summary: Remove an account
tags:
- ICS1
consumes:
- application/json
parameters:
- in: body
name: account
description: The password of the account to remove from the KMS
schema:
type: object
required:
- password
properties:
password:
type: string
responses:
200:
description: Removed account
401:
description: Password is wrong
404:
description: Account is not available
/auth/accounts/{address}:
get:
summary: Get the account information on blockchain
tags:
- ICS1
produces:
- application/json
parameters:
- in: path
name: address
description: Account address
required: true
type: string
responses:
200:
description: Account information on the blockchain
schema:
$ref: "#/definitions/AccountQueryResponse"
404:
description: Account is not available
definitions: definitions:
CheckTxResult: CheckTxResult:
@ -561,7 +739,35 @@ definitions:
address: address:
$ref: "#/definitions/Address" $ref: "#/definitions/Address"
pub_key: pub_key:
$ref: "#/definitions/PubKey" type: string
example: "cosmospub1addwnpepqfgv3pakxazq2fgs8tmmhmzsrs94fptl7kyztyxprjpf0mkus3h7cxqe70s"
type:
type: string
example: local
seed:
type: string
AccountInfo:
type: object
properties:
account_number:
type: string
address:
type: string
coins:
type: array
items:
$ref: "#/definitions/Coin"
public_key:
type: string
sequence:
type: string
AccountQueryResponse:
type: object
properties:
type:
type: string
value:
$ref: "#/definitions/AccountInfo"
BlockID: BlockID:
type: object type: object
properties: properties:

View File

@ -138,11 +138,17 @@ func runPubKeyCmd(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
consenusPub, err := sdk.Bech32ifyConsPub(pubKey)
if err != nil {
return err
}
fmt.Println("Address:", pubKey.Address()) fmt.Println("Address:", pubKey.Address())
fmt.Printf("Hex: %X\n", pubkeyBytes) fmt.Printf("Hex: %X\n", pubkeyBytes)
fmt.Println("JSON (base64):", string(pubKeyJSONBytes)) fmt.Println("JSON (base64):", string(pubKeyJSONBytes))
fmt.Println("Bech32 Acc:", accPub) fmt.Println("Bech32 Acc:", accPub)
fmt.Println("Bech32 Val:", valPub) fmt.Println("Bech32 Validator Operator:", valPub)
fmt.Println("Bech32 Validator Consensus:", consenusPub)
return nil return nil
} }

View File

@ -17,7 +17,7 @@ import (
// register REST routes // register REST routes
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) { func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) {
r.HandleFunc( r.HandleFunc(
"/accounts/{address}", "/auth/accounts/{address}",
QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), cliCtx), QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), cliCtx),
).Methods("GET") ).Methods("GET")
r.HandleFunc( r.HandleFunc(
@ -36,7 +36,6 @@ func QueryAccountRequestHandlerFn(
decoder auth.AccountDecoder, cliCtx context.CLIContext, decoder auth.AccountDecoder, cliCtx context.CLIContext,
) http.HandlerFunc { ) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
vars := mux.Vars(r) vars := mux.Vars(r)
bech32addr := vars["address"] bech32addr := vars["address"]