Add swagger-ui to gaiacli rest-server
This commit is contained in:
parent
d214952450
commit
79c0bc40c8
9
Gopkg.lock
generated
9
Gopkg.lock
generated
@ -304,6 +304,14 @@
|
||||
pruneopts = "UT"
|
||||
revision = "05ee40e3a273f7245e8777337fc7b46e533a9a92"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ea0700160aca4ef099f4e06686a665a87691f4248dddd40796925eda2e46bd64"
|
||||
name = "github.com/rakyll/statik"
|
||||
packages = ["fs"]
|
||||
pruneopts = "UT"
|
||||
revision = "aa8a7b1baecd0f31a436bf7956fcdcc609a83035"
|
||||
version = "v0.1.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:c4556a44e350b50a490544d9b06e9fba9c286c21d6c0e47f54f3a9214597298c"
|
||||
name = "github.com/rcrowley/go-metrics"
|
||||
@ -638,6 +646,7 @@
|
||||
"github.com/gorilla/mux",
|
||||
"github.com/mattn/go-isatty",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/rakyll/statik/fs",
|
||||
"github.com/spf13/cobra",
|
||||
"github.com/spf13/pflag",
|
||||
"github.com/spf13/viper",
|
||||
|
||||
@ -67,6 +67,10 @@
|
||||
name = "github.com/zondax/ledger-goclient"
|
||||
revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/rakyll/statik"
|
||||
version = "=v0.1.4"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
@ -259,3 +259,55 @@ func SeedRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
seed := getSeed(algo)
|
||||
w.Write([]byte(seed))
|
||||
}
|
||||
|
||||
// RecoverKeyBody is recover key request REST body
|
||||
type RecoverKeyBody struct {
|
||||
Password string `json:"password"`
|
||||
Seed string `json:"seed"`
|
||||
}
|
||||
|
||||
// RecoverResuestHandler is the handler of creating seed in swagger rest server
|
||||
func RecoverResuestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["name"]
|
||||
var m RecoverKeyBody
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&m)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
kb, err := GetKeyBase()
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
info, err := kb.CreateKey(name, m.Seed, m.Password)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
keyOutput, err := Bech32KeyOutput(info)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
bz, err := cdc.MarshalJSON(keyOutput)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(bz)
|
||||
}
|
||||
@ -33,7 +33,8 @@ func Commands() *cobra.Command {
|
||||
func RegisterRoutes(r *mux.Router) {
|
||||
r.HandleFunc("/keys", QueryKeysRequestHandler).Methods("GET")
|
||||
r.HandleFunc("/keys", AddNewKeyRequestHandler).Methods("POST")
|
||||
r.HandleFunc("/keys/seed", SeedRequestHandler).Methods("GET")
|
||||
r.HandleFunc("/keys/{name}/recover", RecoverResuestHandler).Methods("POST")
|
||||
r.HandleFunc("/keys/{name}/sign", SignResuest).Methods("POST")
|
||||
r.HandleFunc("/keys/{name}", GetKeyRequestHandler).Methods("GET")
|
||||
r.HandleFunc("/keys/{name}", UpdateKeyRequestHandler).Methods("PUT")
|
||||
r.HandleFunc("/keys/{name}", DeleteKeyRequestHandler).Methods("DELETE")
|
||||
|
||||
90
client/keys/sign.go
Normal file
90
client/keys/sign.go
Normal file
@ -0,0 +1,90 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
const (
|
||||
flagFrom = "from"
|
||||
flagPassword = "password"
|
||||
flagTx = "tx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
keySignCmd.Flags().String(flagFrom, "", "Name of private key with which to sign")
|
||||
keySignCmd.Flags().String(flagPassword, "", "Password of private key")
|
||||
keySignCmd.Flags().String(flagTx, "", "Base64 encoded tx data for sign")
|
||||
}
|
||||
|
||||
var keySignCmd = &cobra.Command{
|
||||
Use: "sign",
|
||||
Short: "Sign user specified data",
|
||||
Long: `Sign user data with specified key and password`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
name := viper.GetString(flagFrom)
|
||||
password := viper.GetString(flagPassword)
|
||||
tx := viper.GetString(flagTx)
|
||||
|
||||
decodedTx, err := base64.StdEncoding.DecodeString(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kb, err := GetKeyBase()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sig, _, err := kb.Sign(name, password, decodedTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encoded := base64.StdEncoding.EncodeToString(sig)
|
||||
fmt.Println(string(encoded))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
type keySignBody struct {
|
||||
Tx []byte `json:"tx_bytes"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// SignResuest is the handler of creating seed in swagger rest server
|
||||
func SignResuest(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["name"]
|
||||
var m keySignBody
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&m)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
kb, err := GetKeyBase()
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
sig, _, err := kb.Sign(name, m.Password, m.Tx)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
encoded := base64.StdEncoding.EncodeToString(sig)
|
||||
|
||||
w.Write([]byte(encoded))
|
||||
}
|
||||
@ -42,9 +42,12 @@ func TestKeys(t *testing.T) {
|
||||
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
|
||||
defer cleanup()
|
||||
|
||||
// get seed
|
||||
// TODO Do we really need this endpoint?
|
||||
res, body := Request(t, port, "GET", "/keys/seed", nil)
|
||||
// recover key
|
||||
recoverKeyURL := fmt.Sprintf("/keys/%s/recover", "test_recover")
|
||||
seedRecover := "divorce meat banana embody near until uncover wait uniform capital crawl test praise cloud foil monster garbage hedgehog wrong skate there bonus box odor"
|
||||
passwordRecover := "1234567890"
|
||||
jsonStrRecover := []byte(fmt.Sprintf(`{"seed":"%s", "password":"%s"}`, seedRecover, passwordRecover))
|
||||
res, body := Request(t, port, "POST", recoverKeyURL, jsonStrRecover)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
reg, err := regexp.Compile(`([a-z]+ ){12}`)
|
||||
require.Nil(t, err)
|
||||
@ -75,7 +78,7 @@ func TestKeys(t *testing.T) {
|
||||
// existing keys
|
||||
res, body = Request(t, port, "GET", "/keys", nil)
|
||||
require.Equal(t, http.StatusOK, res.StatusCode, body)
|
||||
var m [2]keys.KeyOutput
|
||||
var m [3]keys.KeyOutput
|
||||
err = cdc.UnmarshalJSON([]byte(body), &m)
|
||||
require.Nil(t, err)
|
||||
|
||||
@ -235,7 +238,7 @@ func TestCoinSend(t *testing.T) {
|
||||
someFakeAddr := sdk.AccAddress(bz)
|
||||
|
||||
// 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)
|
||||
|
||||
acc := getAccount(t, port, addr)
|
||||
@ -723,7 +726,7 @@ func TestProposalsQuery(t *testing.T) {
|
||||
//_____________________________________________________________________________
|
||||
// get the account to get the sequence
|
||||
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)
|
||||
var acc auth.Account
|
||||
err := cdc.UnmarshalJSON([]byte(body), &acc)
|
||||
@ -771,7 +774,7 @@ func doSendWithGas(t *testing.T, port, seed, name, password string, addr sdk.Acc
|
||||
"chain_id":"%s"
|
||||
}`, gasStr, gasAdjustmentStr, name, password, accnum, sequence, coinbz, chainID))
|
||||
|
||||
res, body = Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send%v", receiveAddr, queryStr), jsonStr)
|
||||
res, body = Request(t, port, "POST", fmt.Sprintf("/bank/%s/transfers%v", receiveAddr, queryStr), jsonStr)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import (
|
||||
slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest"
|
||||
stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/rakyll/statik/fs"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
@ -37,12 +38,20 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command {
|
||||
Short: "Start LCD (light-client daemon), a local REST server",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
listenAddr := viper.GetString(flagListenAddr)
|
||||
handler := createHandler(cdc)
|
||||
router := createHandler(cdc)
|
||||
|
||||
statikFS, err := fs.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
staticServer := http.FileServer(statikFS)
|
||||
router.PathPrefix("/swaggerui/").Handler(http.StripPrefix("/swaggerui/", staticServer))
|
||||
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
||||
maxOpen := viper.GetInt(flagMaxOpenConnections)
|
||||
|
||||
listener, err := tmserver.StartHTTPServer(
|
||||
listenAddr, handler, logger,
|
||||
listenAddr, router, logger,
|
||||
tmserver.Config{MaxOpenConnections: maxOpen},
|
||||
)
|
||||
if err != nil {
|
||||
@ -71,7 +80,7 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createHandler(cdc *wire.Codec) http.Handler {
|
||||
func createHandler(cdc *wire.Codec) *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
|
||||
kb, err := keys.GetKeyBase() //XXX
|
||||
|
||||
12
client/lcd/statik/statik.go
Normal file
12
client/lcd/statik/statik.go
Normal file
File diff suppressed because one or more lines are too long
BIN
client/lcd/swaggerui/favicon-16x16.png
Normal file
BIN
client/lcd/swaggerui/favicon-16x16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
BIN
client/lcd/swaggerui/favicon-32x32.png
Normal file
BIN
client/lcd/swaggerui/favicon-32x32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
60
client/lcd/swaggerui/index.html
Normal file
60
client/lcd/swaggerui/index.html
Normal file
@ -0,0 +1,60 @@
|
||||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="swagger-ui.css" >
|
||||
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html
|
||||
{
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after
|
||||
{
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
margin:0;
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="swagger-ui-bundle.js"> </script>
|
||||
<script src="swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "./swagger.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
67
client/lcd/swaggerui/oauth2-redirect.html
Normal file
67
client/lcd/swaggerui/oauth2-redirect.html
Normal file
@ -0,0 +1,67 @@
|
||||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
93
client/lcd/swaggerui/swagger-ui-bundle.js
Normal file
93
client/lcd/swaggerui/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
1
client/lcd/swaggerui/swagger-ui-bundle.js.map
Normal file
1
client/lcd/swaggerui/swagger-ui-bundle.js.map
Normal file
File diff suppressed because one or more lines are too long
14
client/lcd/swaggerui/swagger-ui-standalone-preset.js
Normal file
14
client/lcd/swaggerui/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
1
client/lcd/swaggerui/swagger-ui-standalone-preset.js.map
Normal file
1
client/lcd/swaggerui/swagger-ui-standalone-preset.js.map
Normal file
File diff suppressed because one or more lines are too long
3
client/lcd/swaggerui/swagger-ui.css
Normal file
3
client/lcd/swaggerui/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
1
client/lcd/swaggerui/swagger-ui.css.map
Normal file
1
client/lcd/swaggerui/swagger-ui.css.map
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||
9
client/lcd/swaggerui/swagger-ui.js
Normal file
9
client/lcd/swaggerui/swagger-ui.js
Normal file
File diff suppressed because one or more lines are too long
1
client/lcd/swaggerui/swagger-ui.js.map
Normal file
1
client/lcd/swaggerui/swagger-ui.js.map
Normal file
File diff suppressed because one or more lines are too long
2074
client/lcd/swaggerui/swagger.json
Normal file
2074
client/lcd/swaggerui/swagger.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@ import (
|
||||
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
|
||||
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
|
||||
|
||||
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
)
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/client/lcd"
|
||||
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
// register REST routes
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, storeName string) {
|
||||
r.HandleFunc(
|
||||
"/accounts/{address}",
|
||||
"/auth/accounts/{address}",
|
||||
QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), cliCtx),
|
||||
).Methods("GET")
|
||||
}
|
||||
|
||||
68
x/bank/client/rest/query.go
Normal file
68
x/bank/client/rest/query.go
Normal file
@ -0,0 +1,68 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// register REST routes
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, storeName string) {
|
||||
r.HandleFunc(
|
||||
"/bank/balances/{address}",
|
||||
QueryAccountRequestHandlerFn(storeName, cdc, authcmd.GetAccountDecoder(cdc), cliCtx),
|
||||
).Methods("GET")
|
||||
}
|
||||
|
||||
// query balances Handler
|
||||
func QueryAccountRequestHandlerFn(
|
||||
storeName string, cdc *wire.Codec,
|
||||
decoder auth.AccountDecoder, cliCtx context.CLIContext,
|
||||
) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
bech32addr := vars["address"]
|
||||
|
||||
addr, err := sdk.AccAddressFromBech32(bech32addr)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.QueryStore(auth.AddressStoreKey(addr), storeName)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("couldn'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
|
||||
}
|
||||
|
||||
// decode the value
|
||||
account, err := decoder(res)
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("couldn't parse query result. Result: %s. Error: %s", res, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// print out whole account
|
||||
output, err := cdc.MarshalJSON(account.GetCoins())
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("couldn't marshall query result. Error: %s", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
||||
14
x/bank/client/rest/rest.go
Normal file
14
x/bank/client/rest/rest.go
Normal file
@ -0,0 +1,14 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// RegisterRoutes registers bank-related REST handlers to a router
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
registerQueryRoutes(cliCtx, r, cdc, "acc")
|
||||
RegisterSendTxRoutes(cliCtx, r, cdc, kb)
|
||||
}
|
||||
@ -18,8 +18,8 @@ import (
|
||||
)
|
||||
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, cliCtx)).Methods("POST")
|
||||
func RegisterSendTxRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/bank/{address}/transfers", SendRequestHandlerFn(cdc, kb, cliCtx)).Methods("POST")
|
||||
}
|
||||
|
||||
type sendBody struct {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user