[R4R] Minor rest fixes (#355)

* feat: add swagger

* add version info for mainnet

* feat: update swagger

* fix: type in get params path

* feat: example for creating cdp

* feat: example broadcast signed tx

* feat: examples for depositing to cdp

* added README with example cdp create rest-server request (#358)

* fix: make link-check happy

Co-authored-by: Denali Marsh <denalimarsh@gmail.com>
This commit is contained in:
Kevin Davis 2020-01-31 17:31:22 -05:00 committed by GitHub
parent bdff81b2a2
commit cd754a25d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3048 additions and 2 deletions

View File

@ -101,7 +101,7 @@ clean:
# This tool checks local markdown links as well.
# Set to exclude riot links as they trigger false positives
link-check:
@go run github.com/raviqqe/liche -r . --exclude ^https://riot.im/app
@go run github.com/raviqqe/liche -r . --exclude "^http://127.*|^https://riot.im/app*"
########################################
### Testing

View File

@ -25,12 +25,17 @@
Reference implementation of Kava, a blockchain for cross-chain DeFi. Built using the [comsos-sdk](https://github.com/cosmos/cosmos-sdk).
## Quick Start
```sh
make install
```
## Mainnet
Note, the current reccomended version of the software for mainnet is v0.3.1.
To join the latest testnet, head over to the [testnet repo](https://github.com/Kava-Labs/kava-testnets).
## License

40
contrib/README.md Normal file
View File

@ -0,0 +1,40 @@
# Contrib
## Requests
### Create CDP example request
First, query account information for the signing account. Note the 'accountnumber' and 'sequence' fields, we'll need them later in order to send our request:
```bash
kvcli q auth account $(kvcli keys show accB -a)
```
If testing locally, start the Kava rest server:
```bash
kvcli rest-server
```
Format the base request in create-cdp.json. You'll need to update the 'from', 'chain-id', 'account_number', 'sequence', and 'gas' as appropriate. Then, populate the CDP creation request's params 'owner', 'collateral', and 'principal'. An example formatted base request can be found in `example-create-cdp.json`.
Now we'll create an unsigned request, sign it, and broadcast it to the Kava blockchain via the rest server.
Note that if you're using the mainnet or testnet, the host IP address will need to be updated to point at an active rest server.
```bash
# Create an unsigned request
curl -H "Content-Type: application/json" -X PUT -d @./contrib/requests/create-cdp.json http://127.0.0.1:1317/cdp | jq > ./contrib/requests/create-cdp-unsigned.json
# Sign the request
kvcli tx sign ./contrib/requests/create-cdp-unsigned.json --from accB --offline --chain-id testing --sequence 1 --account-number 2 > ./contrib/requests/broadcast-create-cdp.json
# Broadcast the request
kvcli tx broadcast ./contrib/requests/broadcast-create-cdp.json
```
Congratulations, you've just created a CDP on Kava using the rest server!
## Governance proposals
Example governance proposals are located in `/proposal_examples`.

View File

@ -0,0 +1 @@
{"type":"cosmos-sdk/StdTx","value":{"msg":[{"type":"cdp/MsgCreateCDP","value":{"sender":"kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03","collateral":[{"denom":"xrp","amount":"110000000"}],"principal":[{"denom":"usdx","amount":"10000000"}]}}],"fee":{"amount":[],"gas":"500000"},"signatures":[{"pub_key":{"type":"tendermint/PubKeySecp256k1","value":"AxYhgA8CL/ZmTZCQDS2dGcccu+dv7zOBT0Wz0+grIufW"},"signature":"KMGQekAgj9qSqnu38swM/jTnIkrSskL4m9L3QQlBIbVZdzDQVh9Rkb0UL7TPeXTaswlSTiwFic3hvZZOcjM4SA=="}],"memo":""}}

View File

@ -0,0 +1,34 @@
{
"tx": {
"msg": [
{
"type": "cdp/MsgDeposit",
"value": {
"depositor": "kava1rjnv8ns2wvz9calje5pmcnpxm055pegprywvjj",
"owner": "kava1mzqz3jfs9nzfp6v7qp647rv0afxlu2csl0txmq",
"collateral": [
{
"denom": "xrp",
"amount": "110000000"
}
]
}
}
],
"fee": {
"amount": [],
"gas": "500000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "A2SB6wV+X9cVl6URZ28mmfxNQwFJD1u3oo5G332jMa2L"
},
"signature": "mJCjAhEVS/2KCvmGpcnvmeHCBo/UEu3/SbdhoyWkp8sDOLe5FO6016HyjUMJ2jJh80aSBJpPFQyyh2gOFQluXw=="
}
],
"memo": ""
},
"mode": "sync"
}

View File

@ -0,0 +1,31 @@
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [
{
"type": "cdp/MsgCreateCDP",
"value": {
"sender": "kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03",
"collateral": [
{
"denom": "xrp",
"amount": "110000000"
}
],
"principal": [
{
"denom": "usdx",
"amount": "10000000"
}
]
}
}
],
"fee": {
"amount": [],
"gas": "500000"
},
"signatures": null,
"memo": ""
}
}

View File

@ -0,0 +1,25 @@
{
"base_req": {
"from": "kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03",
"memo": "",
"chain_id": "testing",
"account_number": "2",
"sequence": "0",
"gas": "500000",
"gas_adjustment": "1.0",
"simulate": false
},
"owner": "kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03",
"collateral": [
{
"denom": "xrp",
"amount": "110000000"
}
],
"principal": [
{
"denom": "usdx",
"amount": "10000000"
}
]
}

View File

@ -0,0 +1,20 @@
{
"base_req": {
"from": "kava1rjnv8ns2wvz9calje5pmcnpxm055pegprywvjj",
"memo": "",
"chain_id": "kava-internal",
"account_number": "12",
"sequence": "0",
"gas": "500000",
"gas_adjustment": "1.0",
"simulate": false
},
"owner": "kava1mzqz3jfs9nzfp6v7qp647rv0afxlu2csl0txmq",
"depositor": "kava1rjnv8ns2wvz9calje5pmcnpxm055pegprywvjj",
"collateral": [
{
"denom": "xrp",
"amount": "110000000"
}
]
}

View File

@ -0,0 +1,25 @@
{
"base_req": {
"from": "kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03",
"memo": "",
"chain_id": "testing",
"account_number": "2",
"sequence": "0",
"gas": "500000",
"gas_adjustment": "1.0",
"simulate": false
},
"owner": "kava12jk3szk45afmvjc3xc6kvj4e40tuy2m8ckgs03",
"collateral": [
{
"denom": "xrp",
"amount": "110000000"
}
],
"principal": [
{
"denom": "usdx",
"amount": "10000000"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

60
swagger-ui/index.html Normal file
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() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "./swagger.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
// End Swagger UI call region
window.ui = ui
}
</script>
</body>
</html>

View File

@ -0,0 +1,68 @@
<!doctype html>
<html lang="en-US">
<title>Swagger UI: OAuth2 Redirect</title>
<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 one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

9
swagger-ui/swagger-ui.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2564
swagger-ui/swagger.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/cdp/{%s}", types.RestCollateralDenom), queryCdpsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/cdp/{%s}/ratio/{%s}", types.RestCollateralDenom, types.RestRatio), queryCdpsByRatioHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/cdp/deposits/{%s}/{%s}", types.RestOwner, types.RestCollateralDenom), queryCdpDepositsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/cdps/params", getParamsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc("/cdp/params", getParamsHandlerFn(cliCtx)).Methods("GET")
}
func queryCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {