diff --git a/client/context/broadcast.go b/client/context/broadcast.go index 4e295777c..a957521c2 100644 --- a/client/context/broadcast.go +++ b/client/context/broadcast.go @@ -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) { diff --git a/client/lcd/swagger-ui/index.html b/client/lcd/swagger-ui/index.html index b7cb77fdb..0c4855763 100644 --- a/client/lcd/swagger-ui/index.html +++ b/client/lcd/swagger-ui/index.html @@ -40,7 +40,7 @@ // Build a system const ui = SwaggerUIBundle({ - url: "./swagger.json", + url: "./swagger.yaml", dom_id: '#swagger-ui', deepLinking: true, presets: [ diff --git a/client/lcd/swagger-ui/swagger.json b/client/lcd/swagger-ui/swagger.json deleted file mode 100644 index ddf67256c..000000000 --- a/client/lcd/swagger-ui/swagger.json +++ /dev/null @@ -1,916 +0,0 @@ -{ - "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": "keys", - "description": "Key management to add or view local private keys" - }, - { - "name": "send", - "description": "Create and sign a send tx" - }, - { - "name": "stake", - "description": "Stake module API for staking and validation" - }, - { - "name": "account", - "description": "Query account balance" - }, - { - "name": "query", - "description": "Information about blocks and txs" - }, - { - "name": "validator set", - "description": "Check the state of the validator set" - }, - { - "name": "node", - "description": "Information of the connected node" - }, - { - "name": "version", - "description": "Information about the app version" - } - ], - "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": [ - "node" - ], - "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": [ - "node" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "Node status", - "schema": { - "type": "object", - "properties": { - "pub_key": { - "$ref": "#/definitions/PubKey" - }, - "moniker": { - "type": "string", - "example": "159.89.198.221" - }, - "network": { - "type": "string", - "example": "gaia-2" - }, - "remote_addr": { - "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": [ - "node" - ], - "description": "Get if the node is currently syning with other nodes", - "responses": { - "200": { - "description": "\"true\" or \"false\"" - } - } - } - }, - "/keys": { - "get": { - "summary": "List of accounts stored locally", - "tags": [ - "keys" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "Array of accounts", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Account" - } - } - } - } - }, - "post": { - "summary": "Create a new account locally", - "tags": [ - "keys" - ], - "consumes": [ - "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 address of the account created" - } - } - } - }, - "/keys/seed": { - "get": { - "summary": "Create a new seed to create a new account with", - "tags": [ - "keys" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "16 word Seed", - "schema": { - "type": "string" - } - } - } - } - }, - "/keys/{name}": { - "parameters": [ - { - "in": "path", - "name": "name", - "description": "Account name", - "required": true, - "type": "string" - } - ], - "get": { - "summary": "Get a certain locally stored account", - "tags": [ - "keys" - ], - "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": [ - "keys" - ], - "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": [ - "keys" - ], - "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" - } - } - } - }, - "/accounts/{address}": { - "parameters": [ - { - "in": "path", - "name": "address", - "description": "Account address in bech32 format", - "required": true, - "type": "string" - } - ], - "get": { - "summary": "Get the account balances", - "tags": [ - "account" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "Account balances", - "schema": { - "$ref": "#/definitions/Balance" - } - }, - "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." - } - } - } - }, - "/accounts/{address}/send": { - "parameters": [ - { - "in": "path", - "name": "address", - "description": "Account address in bech32 format", - "required": true, - "type": "string" - } - ], - "post": { - "summary": "Send coins (build -> sign -> send)", - "tags": [ - "send" - ], - "security": [ - { - "kms": [ - - ] - } - ], - "consumes": [ - "application/json" - ], - "parameters": [ - { - "in": "body", - "name": "account", - "description": "The password of the account to remove from the KMS", - "schema": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "password": { - "type": "string" - }, - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coins" - } - }, - "chain_id": { - "type": "string" - }, - "squence": { - "type": "number" - } - } - } - } - ], - "responses": { - "202": { - "description": "Tx was send and will probably be added to the next block" - }, - "400": { - "description": "The Tx was malformated" - } - } - } - }, - "/blocks/latest": { - "get": { - "summary": "Get the latest block", - "tags": [ - "query" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "The latest block", - "schema": { - "$ref": "#/definitions/Block" - } - } - } - } - }, - "/blocks/{height}": { - "parameters": [ - { - "in": "path", - "name": "height", - "description": "Block height", - "required": true, - "type": "number" - } - ], - "get": { - "summary": "Get a block at a certain height", - "tags": [ - "query" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "The block at a specific height", - "schema": { - "$ref": "#/definitions/Block" - } - }, - "404": { - "description": "Block at height is not available" - } - } - } - }, - "/validatorsets/latest": { - "get": { - "summary": "Get the latest validator set", - "tags": [ - "validator set" - ], - "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}": { - "parameters": [ - { - "in": "path", - "name": "height", - "description": "Block height", - "required": true, - "type": "number" - } - ], - "get": { - "summary": "Get a validator set a certain height", - "tags": [ - "validator set" - ], - "produces": [ - "application/json" - ], - "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}": { - "parameters": [ - { - "in": "path", - "name": "hash", - "description": "Tx hash", - "required": true, - "type": "string" - } - ], - "get": { - "summary": "Get a Tx by hash", - "tags": [ - "query" - ], - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "Tx with the provided hash", - "schema": { - "$ref": "#/definitions/Tx" - } - }, - "404": { - "description": "Tx not available for provided hash" - } - } - } - } - }, - "definitions": { - "Address": { - "type": "string", - "description": "bech32 encoded addres", - "example": "cosmos:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq" - }, - "ValidatorAddress": { - "type": "string", - "description": "bech32 encoded addres", - "example": "cosmosvaloper:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq" - }, - "PubKey": { - "type": "string", - "description": "bech32 encoded public key", - "example": "cosmospub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq" - }, - "ValidatorPubKey": { - "type": "string", - "description": "bech32 encoded public key", - "example": "cosmosvalconspub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq" - }, - "Coins": { - "type": "object", - "properties": { - "denom": { - "type": "string", - "example": "steak" - }, - "amount": { - "type": "number", - "example": 50 - } - } - }, - "Hash": { - "type": "string", - "example": "EE5F3404034C524501629B56E0DDC38FAD651F04" - }, - "Tx": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "stake/delegate" - ] - }, - "data": { - "type": "object" - } - } - }, - "TxChain": { - "type": "object", - "properties": { - "type": { - "type": "string", - "default": "chain/tx" - }, - "data": { - "type": "object", - "properties": { - "chain_id": { - "type": "string", - "example": "gaia-2" - }, - "expires_at": { - "type": "number", - "example": 0 - }, - "tx": { - "type": "object", - "properties": { - "type": { - "type": "string", - "default": "nonce" - }, - "data": { - "type": "object", - "properties": { - "sequence": { - "type": "number", - "example": 0 - }, - "signers": { - "type": "array", - "items": { - "type": "object", - "properties": { - "chain": { - "type": "string", - "example": "" - }, - "app": { - "type": "string", - "default": "sigs" - }, - "addr": { - "$ref": "#/definitions/Address" - } - } - } - }, - "tx": { - "$ref": "#/definitions/Tx" - } - } - } - } - } - } - } - } - }, - "TxBuild": { - "type": "object", - "properties": { - "type": { - "type": "string", - "default": "sigs/one" - }, - "data": { - "type": "object", - "properties": { - "tx": { - "$ref": "#/definitions/Tx" - }, - "signature": { - "type": "object", - "properties": { - "Sig": { - "type": "string", - "default": "" - }, - "Pubkey": { - "type": "string", - "default": "" - } - } - } - } - } - } - }, - "TxSigned": { - "type": "object", - "properties": { - "type": { - "type": "string", - "default": "sigs/one" - }, - "data": { - "type": "object", - "properties": { - "tx": { - "$ref": "#/definitions/Tx" - }, - "signature": { - "type": "object", - "properties": { - "Sig": { - "type": "string", - "example": "81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958" - }, - "Pubkey": { - "$ref": "#/definitions/PubKey" - } - } - } - } - } - } - }, - "Account": { - "type": "object", - "properties": { - "name": { - "type": "string", - "example": "Main Account" - }, - "address": { - "$ref": "#/definitions/Address" - }, - "pub_key": { - "$ref": "#/definitions/PubKey" - } - } - }, - "Balance": { - "type": "object", - "properties": { - "height": { - "type": "number", - "example": 123456 - }, - "coins": { - "type": "array", - "items": { - "$ref": "#/definitions/Coins" - } - }, - "credit": { - "type": "array", - "items": { - "type": "object" - } - } - } - }, - "BlockID": { - "type": "object", - "properties": { - "hash": { - "$ref": "#/definitions/Hash" - }, - "parts": { - "type": "object", - "properties": { - "total": { - "type": "number", - "example": 0 - }, - "hash": { - "$ref": "#/definitions/Hash" - } - } - } - } - }, - "Block": { - "type": "object", - "properties": { - "header": { - "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" - } - } - }, - "txs": { - "type": "array", - "items": { - "$ref": "#/definitions/Tx" - } - }, - "evidence": { - "type": "array", - "items": { - "type": "object" - } - }, - "last_commit": { - "type": "object", - "properties": { - "blockID": { - "$ref": "#/definitions/BlockID" - }, - "precommits": { - "type": "array", - "items": { - "type": "object" - } - } - } - } - } - }, - "Validator": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/ValidatorAddress" - }, - "pub_key": { - "$ref": "#/definitions/ValidatorPubKey" - }, - "power": { - "type": "number", - "example": 1000 - }, - "accum": { - "type": "number", - "example": 1000 - } - } - } - }, - "schemes": [ - "https" - ] -} \ No newline at end of file diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml new file mode 100644 index 000000000..e37372874 --- /dev/null +++ b/client/lcd/swagger-ui/swagger.yaml @@ -0,0 +1,550 @@ +--- +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 +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: + pub_key: + $ref: '#/definitions/PubKey' + moniker: + type: string + example: 159.89.198.221 + network: + type: string + example: gaia-2 + remote_addr: + 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/Block" + /blocks/{height}: + parameters: + - in: path + name: height + description: Block height + required: true + type: number + get: + summary: Get a block at a certain height + tags: + - ICS0 + produces: + - application/json + responses: + 200: + description: The block at a specific height + schema: + $ref: "#/definitions/Block" + 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}: + parameters: + - in: path + name: height + description: Block height + required: true + type: number + get: + summary: Get a validator set a certain height + tags: + - ICS0 + produces: + - application/json + 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}: + parameters: + - in: path + name: hash + description: Tx hash + required: true + type: string + get: + summary: Get a Tx by hash + tags: + - ICS0 + produces: + - application/json + responses: + 200: + description: Tx with the provided hash + schema: + $ref: "#/definitions/Tx" + 404: + description: Tx not available for provided hash + /txs/search: + parameters: + - in: query + name: tag + schema: + type: string + example: "coin.sender=EE5F3404034C524501629B56E0DDC38FAD651F04" + required: true + - in: query + name: page + description: Pagination page + schema: + type: number + default: 0 + - in: query + name: size + description: Pagination size + schema: + type: number + default: 50 + get: + tags: + - ICS0 + summary: Query Tx + responses: + 200: + description: All Tx matching the provided tags + content: + application/json: + schema: + type: array + items: + $ref: "#/definitions/Tx" + 404: + description: Pagination is out of bounds + /txs: + post: + tags: + - ICS0 + summary: broadcast Tx + responses: + 200: + description: Broadcast tx result + content: + application/json: + schema: + type: array + items: + $ref: "#/definitions/Tx" + /txs/sign: + post: + tags: + - ICS20 + summary: Sign a Tx + description: Sign a Tx providing locally stored account and according password + security: + - sign: [] + requestBody: + content: + application/json: + schema: + $ref: "#/definitions/TxBuild" + responses: + 200: + description: The signed Tx + content: + application/json: + schema: + $ref: "#/definitions/TxSigned" + 401: + description: Account name and/or password where wrong + /txs/broadcast: + post: + tags: + - ICS20 + summary: Send signed Tx + requestBody: + content: + application/json: + schema: + $ref: "#/definitions/TxSigned" + responses: + 202: + description: Tx was send and will probably be added to the next block + 400: + description: The Tx was malformated + /bank/balances/{address}: + parameters: + - in: path + name: address + description: Account address in bech32 format + required: true + type: string + get: + summary: Get the account balances + tags: + - ICS20 + produces: + - application/json + responses: + 200: + description: Account balances + schema: + $ref: "#/definitions/Balance" + 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: + parameters: + - in: path + name: address + description: Account address in bech32 format + required: true + type: string + post: + summary: Send coins (build -> sign -> send) + tags: + - ICS20 + security: + - kms: [] + consumes: + - application/json + parameters: + - in: body + name: account + description: The password of the account to remove from the KMS + schema: + type: object + properties: + name: + type: string + password: + type: string + amount: + type: array + items: + $ref: "#/definitions/Coins" + chain_id: + type: string + squence: + type: number + responses: + 202: + description: Tx was send and will probably be added to the next block + 400: + description: The Tx was malformated + +definitions: + Address: + type: string + description: bech32 encoded addres + example: cosmos:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorAddress: + type: string + description: bech32 encoded addres + example: cosmosvaloper:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + PubKey: + type: string + description: bech32 encoded public key + example: cosmospub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + ValidatorPubKey: + type: string + description: bech32 encoded public key + example: cosmosvalconspub:zgnkwr7eyyv643dllwfpdwensmgdtz89yu73zq + Coins: + type: object + properties: + denom: + type: string + example: steak + amount: + type: number + example: 50 + Hash: + type: string + example: EE5F3404034C524501629B56E0DDC38FAD651F04 + Tx: + type: object + properties: + type: + type: string + enum: + - stake/delegate + data: + type: object + TxChain: + type: object + properties: + type: + type: string + default: chain/tx + data: + type: object + properties: + chain_id: + type: string + example: gaia-2 + expires_at: + type: number + example: 0 + tx: + type: object + properties: + type: + type: string + default: nonce + data: + type: object + properties: + sequence: + type: number + example: 0 + signers: + type: array + items: + type: object + properties: + chain: + type: string + example: '' + app: + type: string + default: sigs + addr: + $ref: "#/definitions/Address" + tx: + $ref: "#/definitions/Tx" + TxBuild: + type: object + properties: + type: + type: string + default: sigs/one + data: + type: object + properties: + tx: + $ref: "#/definitions/Tx" + signature: + type: object + properties: + Sig: + type: string + default: '' + Pubkey: + type: string + default: '' + TxSigned: + type: object + properties: + type: + type: string + default: sigs/one + data: + type: object + properties: + tx: + $ref: "#/definitions/Tx" + signature: + type: object + properties: + Sig: + type: string + example: 81B11E717789600CC192B26F452A983DF13B985EE75ABD9DD9E68D7BA007A958 + Pubkey: + $ref: "#/definitions/PubKey" + Account: + type: object + properties: + name: + type: string + example: Main Account + address: + $ref: "#/definitions/Address" + pub_key: + $ref: "#/definitions/PubKey" + Balance: + type: object + properties: + height: + type: number + example: 123456 + coins: + type: array + items: + $ref: "#/definitions/Coins" + credit: + type: array + items: + type: object + BlockID: + type: object + properties: + hash: + $ref: "#/definitions/Hash" + parts: + type: object + properties: + total: + type: number + example: 0 + hash: + $ref: "#/definitions/Hash" + Block: + type: object + properties: + header: + 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" + txs: + type: array + items: + $ref: "#/definitions/Tx" + evidence: + type: array + items: + type: object + last_commit: + type: object + properties: + blockID: + $ref: "#/definitions/BlockID" + precommits: + type: array + items: + type: object + Validator: + type: object + properties: + address: + $ref: '#/definitions/ValidatorAddress' + pub_key: + $ref: "#/definitions/ValidatorPubKey" + power: + type: number + example: 1000 + accum: + type: number + example: 1000 +schemes: +- https diff --git a/client/tx/broadcast.go b/client/tx/broadcast.go index a49431825..34bcaa131 100644 --- a/client/tx/broadcast.go +++ b/client/tx/broadcast.go @@ -1,37 +1,84 @@ package tx import ( - "encoding/json" "net/http" "github.com/cosmos/cosmos-sdk/client/context" + "io/ioutil" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/client/utils" ) -// Tx Broadcast Body -type BroadcastTxBody struct { +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 string `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 + } + err = cdc.UnmarshalJSON(body, &m) + if err != nil { + utils.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + var output []byte + switch m.Return { + case flagBlock: + res, err := cliCtx.BroadcastTx([]byte(m.TxBytes)) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + output, err = cdc.MarshalJSON(res) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + case flagSync: + res, err := cliCtx.BroadcastTxSync([]byte(m.TxBytes)) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + output, err = cdc.MarshalJSON(res) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + case flagAsync: + res, err := cliCtx.BroadcastTxAsync([]byte(m.TxBytes)) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + output, err = cdc.MarshalJSON(res) + if err != nil { + utils.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + default: + utils.WriteErrorResponse(w, http.StatusInternalServerError, "unsupported return type. supported types: block, sync, async") return } - res, err := cliCtx.BroadcastTxAndAwaitCommit([]byte(m.TxBytes)) - if err != nil { - w.WriteHeader(500) - w.Write([]byte(err.Error())) - return - } - - w.Write([]byte(string(res.Height))) + w.Write(output) } } diff --git a/client/tx/root.go b/client/tx/root.go index 19376a25b..711c896e2 100644 --- a/client/tx/root.go +++ b/client/tx/root.go @@ -19,7 +19,7 @@ func AddCommands(cmd *cobra.Command, cdc *codec.Codec) { // register REST routes 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/search", 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") } diff --git a/docs/light/update_API_docs.md b/docs/light/update_API_docs.md index d9d51d007..f2ebeb1ed 100644 --- a/docs/light/update_API_docs.md +++ b/docs/light/update_API_docs.md @@ -9,9 +9,9 @@ Due to the rest handlers and related data structures are complicated and distrib make get_tools ``` 2. Edit API docs - 1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.json`. + 1. Directly Edit API docs manually: `client/lcd/swagger-ui/swagger.yaml`. 2. Edit API docs within [SwaggerHub](https://app.swaggerhub.com). Please refer to this [document](https://app.swaggerhub.com/help/index) for how to use the about website to edit API docs. -3. Download `swagger.json` and replace the old `swagger.json` under fold `client/lcd/swagger-ui`. +3. Download `swagger.yaml` and replace the old `swagger.yaml` under fold `client/lcd/swagger-ui`. 4. Compile gaiacli ``` make install