Merge PR #2215: Add swagger-ui for gaiacli lite-server

This commit is contained in:
HaoyangLiu
2018-10-04 13:00:24 +02:00
committed by Christopher Goes
parent b4e8fe5e94
commit 9f67e8af20
46 changed files with 81580 additions and 1050 deletions
+4 -3
View File
@@ -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
View File
@@ -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")
+3
View File
@@ -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

+60
View 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.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
+1
View File
@@ -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
+704
View File
@@ -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