Merge PR #2215: Add swagger-ui for gaiacli lite-server
This commit is contained in:
committed by
Christopher Goes
parent
b4e8fe5e94
commit
9f67e8af20
@@ -69,6 +69,22 @@ func (ctx CLIContext) BroadcastTxAndAwaitCommit(tx []byte) (*ctypes.ResultBroadc
|
||||
return res, err
|
||||
}
|
||||
|
||||
// BroadcastTxSync broadcasts transaction bytes to a Tendermint node
|
||||
// synchronously.
|
||||
func (ctx CLIContext) BroadcastTxSync(tx []byte) (*ctypes.ResultBroadcastTx, error) {
|
||||
node, err := ctx.GetNode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := node.BroadcastTxSync(tx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// BroadcastTxAsync broadcasts transaction bytes to a Tendermint node
|
||||
// asynchronously.
|
||||
func (ctx CLIContext) BroadcastTxAsync(tx []byte) (*ctypes.ResultBroadcastTx, error) {
|
||||
|
||||
@@ -50,6 +50,7 @@ type CLIContext struct {
|
||||
GenerateOnly bool
|
||||
fromAddress types.AccAddress
|
||||
fromName string
|
||||
Indent bool
|
||||
}
|
||||
|
||||
// NewCLIContext returns a new initialized CLIContext with parameters from the
|
||||
@@ -87,6 +88,7 @@ func NewCLIContext() CLIContext {
|
||||
GenerateOnly: viper.GetBool(client.FlagGenerateOnly),
|
||||
fromAddress: fromAddress,
|
||||
fromName: fromName,
|
||||
Indent: viper.GetBool(client.FlagIndentResponse),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-18
@@ -17,24 +17,25 @@ const (
|
||||
DefaultGasLimit = 200000
|
||||
GasFlagSimulate = "simulate"
|
||||
|
||||
FlagUseLedger = "ledger"
|
||||
FlagChainID = "chain-id"
|
||||
FlagNode = "node"
|
||||
FlagHeight = "height"
|
||||
FlagGas = "gas"
|
||||
FlagGasAdjustment = "gas-adjustment"
|
||||
FlagTrustNode = "trust-node"
|
||||
FlagFrom = "from"
|
||||
FlagName = "name"
|
||||
FlagAccountNumber = "account-number"
|
||||
FlagSequence = "sequence"
|
||||
FlagMemo = "memo"
|
||||
FlagFee = "fee"
|
||||
FlagAsync = "async"
|
||||
FlagJson = "json"
|
||||
FlagPrintResponse = "print-response"
|
||||
FlagDryRun = "dry-run"
|
||||
FlagGenerateOnly = "generate-only"
|
||||
FlagUseLedger = "ledger"
|
||||
FlagChainID = "chain-id"
|
||||
FlagNode = "node"
|
||||
FlagHeight = "height"
|
||||
FlagGas = "gas"
|
||||
FlagGasAdjustment = "gas-adjustment"
|
||||
FlagTrustNode = "trust-node"
|
||||
FlagFrom = "from"
|
||||
FlagName = "name"
|
||||
FlagAccountNumber = "account-number"
|
||||
FlagSequence = "sequence"
|
||||
FlagMemo = "memo"
|
||||
FlagFee = "fee"
|
||||
FlagAsync = "async"
|
||||
FlagJson = "json"
|
||||
FlagPrintResponse = "print-response"
|
||||
FlagDryRun = "dry-run"
|
||||
FlagGenerateOnly = "generate-only"
|
||||
FlagIndentResponse = "indent"
|
||||
)
|
||||
|
||||
// LineBreak can be included in a command list to provide a blank line
|
||||
@@ -47,6 +48,7 @@ var (
|
||||
// GetCommands adds common flags to query commands
|
||||
func GetCommands(cmds ...*cobra.Command) []*cobra.Command {
|
||||
for _, c := range cmds {
|
||||
c.Flags().Bool(FlagIndentResponse, false, "Add indent to JSON response")
|
||||
c.Flags().Bool(FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
|
||||
c.Flags().Bool(FlagUseLedger, false, "Use a connected Ledger device")
|
||||
c.Flags().String(FlagChainID, "", "Chain ID of tendermint node")
|
||||
@@ -63,6 +65,7 @@ func GetCommands(cmds ...*cobra.Command) []*cobra.Command {
|
||||
// PostCommands adds common flags for commands to post tx
|
||||
func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
|
||||
for _, c := range cmds {
|
||||
c.Flags().Bool(FlagIndentResponse, false, "Add indent to JSON response")
|
||||
c.Flags().String(FlagFrom, "", "Name or address of private key with which to sign")
|
||||
c.Flags().Int64(FlagAccountNumber, 0, "AccountNumber number to sign the tx")
|
||||
c.Flags().Int64(FlagSequence, 0, "Sequence number to sign the tx")
|
||||
|
||||
@@ -372,8 +372,9 @@ func TestCoinSendGenerateSignAndBroadcast(t *testing.T) {
|
||||
|
||||
// broadcast tx
|
||||
broadcastPayload := struct {
|
||||
Tx auth.StdTx `json:"tx"`
|
||||
}{Tx: signedMsg}
|
||||
Tx auth.StdTx `json:"tx"`
|
||||
Return string `json:"return"`
|
||||
}{Tx: signedMsg, Return: "block"}
|
||||
json, err = cdc.MarshalJSON(broadcastPayload)
|
||||
require.Nil(t, err)
|
||||
res, body = Request(t, port, "POST", "/tx/broadcast", json)
|
||||
@@ -851,7 +852,7 @@ func doSendWithGas(t *testing.T, port, seed, name, password string, addr sdk.Acc
|
||||
}
|
||||
}`, coinbz, gasStr, gasAdjustmentStr, name, password, chainID, accnum, sequence))
|
||||
|
||||
res, body = Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send%v", receiveAddr, queryStr), jsonStr)
|
||||
res, body = Request(t, port, "POST", fmt.Sprintf("/bank/accounts/%s/transfers%v", receiveAddr, queryStr), jsonStr)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+13
-1
@@ -18,6 +18,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"
|
||||
@@ -46,6 +47,7 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
listenAddr := viper.GetString(flagListenAddr)
|
||||
handler := createHandler(cdc)
|
||||
registerSwaggerUI(handler)
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
||||
maxOpen := viper.GetInt(flagMaxOpenConnections)
|
||||
sslHosts := viper.GetString(flagSSLHosts)
|
||||
@@ -121,6 +123,7 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||
cmd.Flags().String(client.FlagNode, "tcp://localhost:26657", "Address of the node to connect to")
|
||||
cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections")
|
||||
cmd.Flags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)")
|
||||
cmd.Flags().Bool(client.FlagIndentResponse, false, "Add indent to JSON response")
|
||||
viper.BindPFlag(client.FlagTrustNode, cmd.Flags().Lookup(client.FlagTrustNode))
|
||||
viper.BindPFlag(client.FlagChainID, cmd.Flags().Lookup(client.FlagChainID))
|
||||
viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode))
|
||||
@@ -128,7 +131,7 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createHandler(cdc *codec.Codec) http.Handler {
|
||||
func createHandler(cdc *codec.Codec) *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
|
||||
kb, err := keys.GetKeyBase() //XXX
|
||||
@@ -154,6 +157,15 @@ func createHandler(cdc *codec.Codec) http.Handler {
|
||||
return r
|
||||
}
|
||||
|
||||
func registerSwaggerUI(r *mux.Router) {
|
||||
statikFS, err := fs.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
staticServer := http.FileServer(statikFS)
|
||||
r.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", staticServer))
|
||||
}
|
||||
|
||||
func validateCertKeyFiles(certFile, keyFile string) error {
|
||||
if keyFile == "" {
|
||||
return errors.New("a key file is required")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
package statik
|
||||
|
||||
//This just for fixing the error in importing empty github.com/cosmos/cosmos-sdk/client/lcd/statik
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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.yaml",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -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>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,704 @@
|
||||
---
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: 1.1.0
|
||||
title: Gaia-Lite (former LCD) to interface with Cosmos BaseServer via REST
|
||||
description: Specification for Gaia-lite provided by `gaiacli rest-server`
|
||||
tags:
|
||||
- name: ICS0
|
||||
description: Tendermint APIs, such as query blocks, transactions and validatorset
|
||||
- name: ICS20
|
||||
description: Create and sign a send tx
|
||||
- name: version
|
||||
description: Information about the app version
|
||||
schemes:
|
||||
- https
|
||||
securityDefinitions:
|
||||
kms:
|
||||
type: basic
|
||||
paths:
|
||||
/version:
|
||||
get:
|
||||
summary: Version of Gaia-lite
|
||||
tags:
|
||||
- version
|
||||
description: Get the version of gaia-lite running locally to compare against expected
|
||||
responses:
|
||||
200:
|
||||
description: Plaintext version i.e. "v0.5.0"
|
||||
/node_version:
|
||||
get:
|
||||
summary: Version of the connected node
|
||||
tags:
|
||||
- ICS0
|
||||
description: Get the version of the SDK running on the connected node to compare against expected
|
||||
responses:
|
||||
200:
|
||||
description: Plaintext version i.e. "v0.5.0"
|
||||
/node_info:
|
||||
get:
|
||||
description: Information about the connected node
|
||||
summary: The properties of the connected node
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
200:
|
||||
description: Node status
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
moniker:
|
||||
type: string
|
||||
example: validator-name
|
||||
network:
|
||||
type: string
|
||||
example: gaia-2
|
||||
channels:
|
||||
type: string
|
||||
listen_addr:
|
||||
type: string
|
||||
example: 192.168.56.1:26656
|
||||
version:
|
||||
description: Tendermint version
|
||||
type: string
|
||||
example: 0.15.0
|
||||
other:
|
||||
description: more information on versions
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/syncing:
|
||||
get:
|
||||
summary: Syncing state of node
|
||||
tags:
|
||||
- ICS0
|
||||
description: Get if the node is currently syning with other nodes
|
||||
responses:
|
||||
200:
|
||||
description: '"true" or "false"'
|
||||
/blocks/latest:
|
||||
get:
|
||||
summary: Get the latest block
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
200:
|
||||
description: The latest block
|
||||
schema:
|
||||
$ref: "#/definitions/QueryBlock"
|
||||
/blocks/{height}:
|
||||
get:
|
||||
summary: Get a block at a certain height
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: height
|
||||
description: Block height
|
||||
required: true
|
||||
type: number
|
||||
responses:
|
||||
200:
|
||||
description: The block at a specific height
|
||||
schema:
|
||||
$ref: "#/definitions/QueryBlock"
|
||||
404:
|
||||
description: Block at height is not available
|
||||
/validatorsets/latest:
|
||||
get:
|
||||
summary: Get the latest validator set
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
200:
|
||||
description: The validator set at the latest block height
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
block_height:
|
||||
type: number
|
||||
validators:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Validator"
|
||||
/validatorsets/{height}:
|
||||
get:
|
||||
summary: Get a validator set a certain height
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: height
|
||||
description: Block height
|
||||
required: true
|
||||
type: number
|
||||
responses:
|
||||
200:
|
||||
description: The validator set at a specific block height
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
block_height:
|
||||
type: number
|
||||
validators:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Validator"
|
||||
404:
|
||||
description: Block at height not available
|
||||
/txs/{hash}:
|
||||
get:
|
||||
summary: Get a Tx by hash
|
||||
tags:
|
||||
- ICS0
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: hash
|
||||
description: Tx hash
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: Tx with the provided hash
|
||||
schema:
|
||||
$ref: "#/definitions/TxQuery"
|
||||
404:
|
||||
description: Tx not available for provided hash
|
||||
/txs:
|
||||
get:
|
||||
tags:
|
||||
- ICS0
|
||||
summary: Search transactions
|
||||
description: Search transactions by tag
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: query
|
||||
name: tag
|
||||
type: string
|
||||
description: "transaction tag, for instance: sender_bech32=`'cosmos1g9ahr6xhht5rmqven628nklxluzyv8z9jqjcmc'`"
|
||||
required: true
|
||||
- in: query
|
||||
name: page
|
||||
description: Pagination page
|
||||
type: integer
|
||||
- in: query
|
||||
name: size
|
||||
description: Pagination size
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: All Tx matching the provided tags
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/TxQuery"
|
||||
404:
|
||||
description: Pagination is out of bounds
|
||||
post:
|
||||
tags:
|
||||
- ICS0
|
||||
summary: broadcast Tx
|
||||
description: broadcast tx with tendermint rpc
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: body
|
||||
name: txBroadcast
|
||||
description: Build a StdTx transaction and serilize it to a byte array with amino, then the `"tx"` field in the post body will be the base64 encoding of the byte array. The supported return types includes `"block"`(return after tx commit), `"sync"`(return afer CheckTx) and `"async"`(return right away).
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/TendertmintTx"
|
||||
responses:
|
||||
200:
|
||||
description: Broadcast tx result
|
||||
schema:
|
||||
$ref: "#/definitions/BroadcastTxCommitResult"
|
||||
/tx/sign:
|
||||
post:
|
||||
tags:
|
||||
- ICS20
|
||||
summary: Sign a Tx
|
||||
description: Sign a Tx providing locally stored account and according password
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: body
|
||||
name: sendToken
|
||||
description: sign tx
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/TxSign"
|
||||
responses:
|
||||
200:
|
||||
description: The signed Tx
|
||||
schema:
|
||||
$ref: "#/definitions/StdTx"
|
||||
401:
|
||||
description: Account name and/or password where wrong
|
||||
/tx/broadcast:
|
||||
post:
|
||||
tags:
|
||||
- ICS20
|
||||
summary: Send a signed Tx
|
||||
description: Send a signed Tx to a Gaiad full node
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: body
|
||||
name: txBroadcast
|
||||
description: broadcast tx
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/TxBroadcast"
|
||||
responses:
|
||||
202:
|
||||
description: Tx was send and will probably be added to the next block
|
||||
schema:
|
||||
$ref: "#/definitions/BroadcastTxCommitResult"
|
||||
400:
|
||||
description: The Tx was malformated
|
||||
/bank/balances/{address}:
|
||||
get:
|
||||
summary: Get the account balances
|
||||
tags:
|
||||
- ICS20
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: path
|
||||
name: address
|
||||
description: Account address in bech32 format
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: Account balances
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
204:
|
||||
description: There is no data for the requested account. This is not a 404 as the account might exist, just does not hold data.
|
||||
/bank/accounts/{address}/transfers:
|
||||
post:
|
||||
summary: Send coins (build -> sign -> send)
|
||||
description: Send coins (build -> sign -> send)
|
||||
tags:
|
||||
- ICS20
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- in: query
|
||||
name: simulate
|
||||
description: if true, ignore the gas field and perform a simulation of a transaction, but don't broadcast it
|
||||
required: false
|
||||
type: boolean
|
||||
- in: query
|
||||
name: generate_only
|
||||
description: if true, build an unsigned transaction and write it back
|
||||
required: false
|
||||
type: boolean
|
||||
- in: path
|
||||
name: address
|
||||
description: Account address in bech32 format
|
||||
required: true
|
||||
type: string
|
||||
- in: body
|
||||
name: account
|
||||
description: The password of the account to remove from the KMS
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
base_req:
|
||||
$ref: "#/definitions/BaseReq"
|
||||
amount:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
responses:
|
||||
202:
|
||||
description: Tx was send and will probably be added to the next block
|
||||
schema:
|
||||
$ref: "#/definitions/BroadcastTxCommitResult"
|
||||
400:
|
||||
description: The Tx was malformated
|
||||
|
||||
definitions:
|
||||
CheckTxResult:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
data:
|
||||
type: string
|
||||
gas_used:
|
||||
type: integer
|
||||
gas_wanted:
|
||||
type: integer
|
||||
info:
|
||||
type: string
|
||||
log:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/definitions/KVPair"
|
||||
example:
|
||||
code: 0
|
||||
data: data
|
||||
log: log
|
||||
gas_used: 5000
|
||||
gas_wanted: 10000
|
||||
info: info
|
||||
tags:
|
||||
- ''
|
||||
- ''
|
||||
DeliverTxResult:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
data:
|
||||
type: string
|
||||
gas_used:
|
||||
type: integer
|
||||
gas_wanted:
|
||||
type: integer
|
||||
info:
|
||||
type: string
|
||||
log:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
"$ref": "#/definitions/KVPair"
|
||||
example:
|
||||
code: 5
|
||||
data: data
|
||||
log: log
|
||||
gas_used: 5000
|
||||
gas_wanted: 10000
|
||||
info: info
|
||||
tags:
|
||||
- ''
|
||||
- ''
|
||||
BroadcastTxCommitResult:
|
||||
type: object
|
||||
properties:
|
||||
check_tx:
|
||||
$ref: "#/definitions/CheckTxResult"
|
||||
deliver_tx:
|
||||
$ref: "#/definitions/DeliverTxResult"
|
||||
hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
height:
|
||||
type: integer
|
||||
KVPair:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
Fee:
|
||||
type: object
|
||||
properties:
|
||||
gas:
|
||||
type: string
|
||||
amount:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Coin"
|
||||
Msg:
|
||||
type: string
|
||||
Address:
|
||||
type: string
|
||||
description: bech32 encoded addres
|
||||
example: cosmoszgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
ValidatorAddress:
|
||||
type: string
|
||||
description: bech32 encoded addres
|
||||
example: cosmosvaloper:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
PubKey:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
example: "tendermint/PubKeySecp256k1"
|
||||
value:
|
||||
type: string
|
||||
example: "Avz04VhtKJh8ACCVzlI8aTosGy0ikFXKIVHQ3jKMrosH"
|
||||
ValidatorPubKey:
|
||||
type: string
|
||||
description: bech32 encoded public key
|
||||
example: cosmosvalconspub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq
|
||||
Coin:
|
||||
type: object
|
||||
properties:
|
||||
denom:
|
||||
type: string
|
||||
example: steak
|
||||
amount:
|
||||
type: string
|
||||
example: "50"
|
||||
Hash:
|
||||
type: string
|
||||
example: EE5F3404034C524501629B56E0DDC38FAD651F04
|
||||
Result:
|
||||
type: object
|
||||
properties:
|
||||
log:
|
||||
type: string
|
||||
gas_wanted:
|
||||
type: string
|
||||
example: "0"
|
||||
gas_used:
|
||||
type: string
|
||||
example: "0"
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/KVPair"
|
||||
TxQuery:
|
||||
type: object
|
||||
properties:
|
||||
hash:
|
||||
type: string
|
||||
height:
|
||||
type: number
|
||||
tx:
|
||||
$ref: "#/definitions/StdTx"
|
||||
result:
|
||||
$ref: "#/definitions/Result"
|
||||
TendertmintTx:
|
||||
type: object
|
||||
properties:
|
||||
tx:
|
||||
type: string
|
||||
return:
|
||||
type: string
|
||||
example: block
|
||||
TxBroadcast:
|
||||
type: object
|
||||
properties:
|
||||
tx:
|
||||
$ref: "#/definitions/StdTx"
|
||||
TxSign:
|
||||
type: object
|
||||
properties:
|
||||
tx:
|
||||
$ref: "#/definitions/StdTx"
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
chain_id:
|
||||
type: string
|
||||
account_number:
|
||||
type: string
|
||||
example: "0"
|
||||
sequence:
|
||||
type: string
|
||||
example: "0"
|
||||
append_sig:
|
||||
type: boolean
|
||||
example: true
|
||||
StdTx:
|
||||
type: object
|
||||
properties:
|
||||
msg:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/Msg"
|
||||
fee:
|
||||
$ref: "#/definitions/Fee"
|
||||
memo:
|
||||
type: string
|
||||
signature:
|
||||
type: object
|
||||
properties:
|
||||
signature:
|
||||
type: string
|
||||
example: MEUCIQD02fsDPra8MtbRsyB1w7bqTM55Wu138zQbFcWx4+CFyAIge5WNPfKIuvzBZ69MyqHsqD8S1IwiEp+iUb6VSdtlpgY=
|
||||
pub_key:
|
||||
$ref: "#/definitions/PubKey"
|
||||
account_number:
|
||||
type: string
|
||||
example: "0"
|
||||
sequence:
|
||||
type: string
|
||||
example: "0"
|
||||
Account:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: Main Account
|
||||
address:
|
||||
$ref: "#/definitions/Address"
|
||||
pub_key:
|
||||
$ref: "#/definitions/PubKey"
|
||||
BlockID:
|
||||
type: object
|
||||
properties:
|
||||
hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
parts:
|
||||
type: object
|
||||
properties:
|
||||
total:
|
||||
type: number
|
||||
example: 0
|
||||
hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
BlockHeader:
|
||||
type: object
|
||||
properties:
|
||||
chain_id:
|
||||
type: string
|
||||
example: gaia-2
|
||||
height:
|
||||
type: number
|
||||
example: 1
|
||||
time:
|
||||
type: string
|
||||
example: '2017-12-30T05:53:09.287+01:00'
|
||||
num_txs:
|
||||
type: number
|
||||
example: 0
|
||||
last_block_id:
|
||||
$ref: "#/definitions/BlockID"
|
||||
total_txs:
|
||||
type: number
|
||||
example: 35
|
||||
last_commit_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
data_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
validators_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
consensus_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
app_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
last_results_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
evidence_hash:
|
||||
$ref: "#/definitions/Hash"
|
||||
Block:
|
||||
type: object
|
||||
properties:
|
||||
header:
|
||||
$ref: "#/definitions/BlockHeader"
|
||||
txs:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
evidence:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
last_commit:
|
||||
type: object
|
||||
properties:
|
||||
block_id:
|
||||
$ref: "#/definitions/BlockID"
|
||||
precommits:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
validator_address:
|
||||
type: string
|
||||
validator_index:
|
||||
type: string
|
||||
example: "0"
|
||||
height:
|
||||
type: string
|
||||
example: "0"
|
||||
round:
|
||||
type: string
|
||||
example: "0"
|
||||
timestamp:
|
||||
type: string
|
||||
example: '2017-12-30T05:53:09.287+01:00'
|
||||
type:
|
||||
type: number
|
||||
example: 2
|
||||
block_id:
|
||||
$ref: "#/definitions/BlockID"
|
||||
signature:
|
||||
type: string
|
||||
example: '7uTC74QlknqYWEwg7Vn6M8Om7FuZ0EO4bjvuj6rwH1mTUJrRuMMZvAAqT9VjNgP0RA/TDp6u/92AqrZfXJSpBQ=='
|
||||
BlockMeta:
|
||||
type: object
|
||||
properties:
|
||||
header:
|
||||
$ref: "#/definitions/BlockHeader"
|
||||
block_id:
|
||||
$ref: "#/definitions/BlockID"
|
||||
QueryBlock:
|
||||
type: object
|
||||
properties:
|
||||
block_meta:
|
||||
$ref: "#/definitions/BlockMeta"
|
||||
block:
|
||||
$ref: "#/definitions/Block"
|
||||
BaseReq:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
chain_id:
|
||||
type: string
|
||||
account_number:
|
||||
type: string
|
||||
example: "0"
|
||||
sequence:
|
||||
type: string
|
||||
example: "0"
|
||||
gas:
|
||||
type: string
|
||||
example: "200000"
|
||||
gas_adjustment:
|
||||
type: string
|
||||
example: "1.2"
|
||||
Validator:
|
||||
type: object
|
||||
properties:
|
||||
address:
|
||||
$ref: '#/definitions/ValidatorAddress'
|
||||
pub_key:
|
||||
$ref: "#/definitions/ValidatorPubKey"
|
||||
power:
|
||||
type: number
|
||||
example: 1000
|
||||
accum:
|
||||
type: number
|
||||
example: 1000
|
||||
+6
-8
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
@@ -62,13 +63,10 @@ func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move maarshalling into cmd/rest functions
|
||||
// output, err := tmcodec.MarshalJSON(res)
|
||||
output, err := cdc.MarshalJSON(res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if cliCtx.Indent {
|
||||
return cdc.MarshalJSONIndent(res, "", " ")
|
||||
}
|
||||
return output, nil
|
||||
return cdc.MarshalJSON(res)
|
||||
}
|
||||
|
||||
// get the current blockchain height
|
||||
@@ -133,7 +131,7 @@ func BlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, output, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +150,6 @@ func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, output, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-11
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/spf13/viper"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
@@ -22,6 +23,7 @@ func statusCommand() *cobra.Command {
|
||||
|
||||
cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:26657", "Node to connect to")
|
||||
viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode))
|
||||
cmd.Flags().Bool(client.FlagIndentResponse, false, "Add indent to JSON response")
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -38,13 +40,20 @@ func getNodeStatus(cliCtx context.CLIContext) (*ctypes.ResultStatus, error) {
|
||||
// CMD
|
||||
|
||||
func printNodeStatus(cmd *cobra.Command, args []string) error {
|
||||
status, err := getNodeStatus(context.NewCLIContext())
|
||||
// No need to verify proof in getting node status
|
||||
viper.Set(client.FlagTrustNode, true)
|
||||
cliCtx := context.NewCLIContext()
|
||||
status, err := getNodeStatus(cliCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(status)
|
||||
// output, err := cdc.MarshalJSONIndent(res, " ", "")
|
||||
var output []byte
|
||||
if cliCtx.Indent {
|
||||
output, err = cdc.MarshalJSONIndent(status, "", " ")
|
||||
} else {
|
||||
output, err = cdc.MarshalJSON(status)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,14 +75,7 @@ func NodeInfoRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
|
||||
nodeInfo := status.NodeInfo
|
||||
output, err := cdc.MarshalJSON(nodeInfo)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, nodeInfo, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/spf13/viper"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
)
|
||||
|
||||
// TODO these next two functions feel kinda hacky based on their placement
|
||||
@@ -98,12 +99,11 @@ func getValidators(cliCtx context.CLIContext, height *int64) ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(outputValidatorsRes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if cliCtx.Indent {
|
||||
return cdc.MarshalJSONIndent(outputValidatorsRes, "", " ")
|
||||
}
|
||||
return cdc.MarshalJSON(outputValidatorsRes)
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// CMD
|
||||
@@ -158,8 +158,7 @@ func ValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, output, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +178,6 @@ func LatestValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerF
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, output, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
+41
-18
@@ -1,37 +1,60 @@
|
||||
package tx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// Tx Broadcast Body
|
||||
type BroadcastTxBody struct {
|
||||
TxBytes string `json:"tx"`
|
||||
const (
|
||||
// Returns with the response from CheckTx.
|
||||
flagSync = "sync"
|
||||
// Returns right away, with no response
|
||||
flagAsync = "async"
|
||||
// Only returns error if mempool.BroadcastTx errs (ie. problem with the app) or if we timeout waiting for tx to commit.
|
||||
flagBlock = "block"
|
||||
)
|
||||
|
||||
// BroadcastBody Tx Broadcast Body
|
||||
type BroadcastBody struct {
|
||||
TxBytes []byte `json:"tx"`
|
||||
Return string `json:"return"`
|
||||
}
|
||||
|
||||
// BroadcastTx REST Handler
|
||||
func BroadcastTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
// BroadcastTxRequest REST Handler
|
||||
// nolint: gocyclo
|
||||
func BroadcastTxRequest(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var m BroadcastTxBody
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&m)
|
||||
var m BroadcastBody
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := cliCtx.BroadcastTxAndAwaitCommit([]byte(m.TxBytes))
|
||||
err = cdc.UnmarshalJSON(body, &m)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
w.Write([]byte(string(res.Height)))
|
||||
var res interface{}
|
||||
switch m.Return {
|
||||
case flagBlock:
|
||||
res, err = cliCtx.BroadcastTx(m.TxBytes)
|
||||
case flagSync:
|
||||
res, err = cliCtx.BroadcastTxSync(m.TxBytes)
|
||||
case flagAsync:
|
||||
res, err = cliCtx.BroadcastTxAsync(m.TxBytes)
|
||||
default:
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, "unsupported return type. supported types: block, sync, async")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
utils.PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
@@ -78,7 +79,10 @@ func queryTx(cdc *codec.Codec, cliCtx context.CLIContext, hashHexStr string) ([]
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return codec.MarshalJSONIndent(cdc, info)
|
||||
if cliCtx.Indent {
|
||||
return cdc.MarshalJSONIndent(info, "", " ")
|
||||
}
|
||||
return cdc.MarshalJSON(info)
|
||||
}
|
||||
|
||||
// ValidateTxResult performs transaction verification
|
||||
@@ -142,7 +146,6 @@ func QueryTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.H
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, output, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -20,6 +20,5 @@ func AddCommands(cmd *cobra.Command, cdc *codec.Codec) {
|
||||
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) {
|
||||
r.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cdc, cliCtx)).Methods("GET")
|
||||
r.HandleFunc("/txs", SearchTxRequestHandlerFn(cliCtx, cdc)).Methods("GET")
|
||||
// r.HandleFunc("/txs/sign", SignTxRequstHandler).Methods("POST")
|
||||
// r.HandleFunc("/txs/broadcast", BroadcastTxRequestHandler).Methods("POST")
|
||||
r.HandleFunc("/txs", BroadcastTxRequest(cliCtx, cdc)).Methods("POST")
|
||||
}
|
||||
|
||||
+9
-9
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
|
||||
@@ -51,7 +52,13 @@ $ gaiacli tendermint txs --tag test1,test2 --any
|
||||
return err
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(txs)
|
||||
var output []byte
|
||||
if cliCtx.Indent {
|
||||
output, err = cdc.MarshalJSONIndent(txs, "", " ")
|
||||
} else {
|
||||
output, err = cdc.MarshalJSON(txs)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -174,13 +181,6 @@ func SearchTxRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.
|
||||
return
|
||||
}
|
||||
|
||||
output, err := cdc.MarshalJSON(txs)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
utils.PostProcessResponse(w, cdc, txs, cliCtx.Indent)
|
||||
}
|
||||
}
|
||||
|
||||
+24
-7
@@ -1,5 +1,6 @@
|
||||
package utils
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -8,11 +9,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
client "github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
)
|
||||
|
||||
@@ -240,11 +241,27 @@ func CompleteAndBroadcastTxREST(w http.ResponseWriter, r *http.Request, cliCtx c
|
||||
return
|
||||
}
|
||||
|
||||
output, err := codec.MarshalJSONIndent(cdc, res)
|
||||
if err != nil {
|
||||
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
PostProcessResponse(w, cdc, res, cliCtx.Indent)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
case []byte:
|
||||
output = response.([]byte)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(output)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user