R4R: update pricefeed module rest endpoints (#359)

* query get price implemented - /pricefeed/price/xrp:usd

* query rawprices implemented - /pricefeed/rawprices/xrp:usd

* refactored to QueryWithMarketIDParams, added rest logic for QueryOracles

* new query get oracles implemented for cli and rest - /pricefeed/oracles/xrp:usd

* tx postprice implemented - /pricefeed/postprice/{MsgPostPrice}

* updated contrib with post-price examples and added to README

* added cliCtx.WithHeight(height) and removed import comment
This commit is contained in:
Denali Marsh 2020-02-02 08:06:33 -08:00 committed by GitHub
parent 183acfef62
commit 4599caca07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 317 additions and 68 deletions

View File

@ -1,11 +1,11 @@
# Contrib
## Requests
## Rest server 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:
### Setup
Before making a request, 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)
@ -17,17 +17,18 @@ If testing locally, start the Kava rest server:
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.
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 instead of http://127.0.0.1.
### Create CDP example request
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 request can be found in `example-create-cdp.json`.
```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
kvcli tx sign ./contrib/requests/create-cdp-unsigned.json --from accB --offline --chain-id testing --sequence 1 --account-number 2 | jq > ./contrib/requests/broadcast-create-cdp.json
# Broadcast the request
kvcli tx broadcast ./contrib/requests/broadcast-create-cdp.json
@ -35,6 +36,26 @@ If testing locally, start the Kava rest server:
Congratulations, you've just created a CDP on Kava using the rest server!
### Post market price example request
Note that only market oracles can post prices, other senders will have their transactions rejected by Kava.
Format the base request in post-price.json. You'll need to update the 'from', 'chain-id', 'account_number', 'sequence', and 'gas' as appropriate. Then, populate the post price request's params 'from', 'market_id', 'price', and 'expiry'. An example formatted request can be found in `example-post-price.json`.
```bash
# Create an unsigned request
curl -H "Content-Type: application/json" -X PUT -d @./contrib/requests/post-price.json http://127.0.0.1:1317/pricefeed/postprice | jq > ./contrib/requests/post-price-unsigned.json
# Sign the request
kvcli tx sign ./contrib/requests/post-price-unsigned.json --from validator --offline --chain-id testing --sequence 96 --account-number 0 | jq > ./contrib/requests/broadcast-post-price.json
# Broadcast the request
kvcli tx broadcast ./contrib/requests/broadcast-post-price.json
```
Congratulations, you've just posted a current market price on Kava using the rest server!
## Governance proposals
Example governance proposals are located in `/proposal_examples`.

View File

@ -1 +1,39 @@
{"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":""}}
{
"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,30 @@
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [
{
"type": "pricefeed/MsgPostPrice",
"value": {
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"market_id": "xrp:usd",
"price": "0.290000000000000000",
"expiry": "2100-03-29T10:40:00Z"
}
}
],
"fee": {
"amount": [],
"gas": "500000"
},
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": "Az740XKIPCJtnZLmJfktTfhsEStEJE3n2iRVyJ3wko43"
},
"signature": "1CMkPnD0UYSpIgPTIGUjroM/16DizLgrR+NSNlsjNs1b5cvD2j3VMfYM0nyBa4IC305RkBOUdthTPc6RPZWDGg=="
}
],
"memo": ""
}
}

View File

@ -0,0 +1,16 @@
{
"base_req": {
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"memo": "",
"chain_id": "testing",
"account_number": "0",
"sequence": "96",
"gas": "500000",
"gas_adjustment": "1.0",
"simulate": false
},
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"market_id": "xrp:usd",
"price": "0.29",
"expiry": "4110000000"
}

View File

@ -0,0 +1,22 @@
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [
{
"type": "pricefeed/MsgPostPrice",
"value": {
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"market_id": "xrp:usd",
"price": "0.290000000000000000",
"expiry": "2100-03-29T10:40:00Z"
}
}
],
"fee": {
"amount": [],
"gas": "500000"
},
"signatures": null,
"memo": ""
}
}

View File

@ -0,0 +1,16 @@
{
"base_req": {
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"memo": "",
"chain_id": "testing",
"account_number": "0",
"sequence": "96",
"gas": "500000",
"gas_adjustment": "1.0",
"simulate": false
},
"from": "kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw",
"market_id": "xrp:usd",
"price": "0.29",
"expiry": "4110000000"
}

View File

@ -36,7 +36,7 @@ const (
MarketPrefix = types.MarketPrefix
OraclePrefix = types.OraclePrefix
TypeMsgPostPrice = types.TypeMsgPostPrice
QueryCurrentPrice = types.QueryCurrentPrice
QueryPrice = types.QueryPrice
QueryRawPrices = types.QueryRawPrices
QueryMarkets = types.QueryMarkets
)
@ -65,14 +65,14 @@ var (
)
type (
GenesisState = types.GenesisState
Market = types.Market
Markets = types.Markets
CurrentPrice = types.CurrentPrice
PostedPrice = types.PostedPrice
SortDecs = types.SortDecs
MsgPostPrice = types.MsgPostPrice
Params = types.Params
QueryPricesParams = types.QueryPricesParams
Keeper = keeper.Keeper
GenesisState = types.GenesisState
Market = types.Market
Markets = types.Markets
CurrentPrice = types.CurrentPrice
PostedPrice = types.PostedPrice
SortDecs = types.SortDecs
MsgPostPrice = types.MsgPostPrice
Params = types.Params
QueryWithMarketIDParams = types.QueryWithMarketIDParams
Keeper = keeper.Keeper
)

View File

@ -6,6 +6,7 @@ import (
"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"
"github.com/kava-labs/kava/x/pricefeed/types"
"github.com/spf13/cobra"
)
@ -22,8 +23,9 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
}
pricefeedQueryCmd.AddCommand(client.GetCommands(
GetCmdCurrentPrice(queryRoute, cdc),
GetCmdPrice(queryRoute, cdc),
GetCmdRawPrices(queryRoute, cdc),
GetCmdOracles(queryRoute, cdc),
GetCmdMarkets(queryRoute, cdc),
GetCmdQueryParams(queryRoute, cdc),
)...)
@ -31,8 +33,37 @@ func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
return pricefeedQueryCmd
}
// GetCmdCurrentPrice queries the current price of an asset
func GetCmdCurrentPrice(queryRoute string, cdc *codec.Codec) *cobra.Command {
// GetCmdOracles queries the oracle set of an asset
func GetCmdOracles(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "oracles [marketID]",
Short: "get the oracle set for a market",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
marketID := args[0]
bz, err := cdc.MarshalJSON(types.QueryWithMarketIDParams{
MarketID: marketID,
})
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryOracles)
res, _, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}
var oracles []sdk.AccAddress
cdc.MustUnmarshalJSON(res, &oracles)
return cliCtx.PrintOutput(oracles)
},
}
}
// GetCmdPrice queries the current price of an asset
func GetCmdPrice(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "price [marketID]",
Short: "get the current price for the input market",
@ -41,13 +72,13 @@ func GetCmdCurrentPrice(queryRoute string, cdc *codec.Codec) *cobra.Command {
cliCtx := context.NewCLIContext().WithCodec(cdc)
marketID := args[0]
bz, err := cdc.MarshalJSON(types.QueryPricesParams{
bz, err := cdc.MarshalJSON(types.QueryWithMarketIDParams{
MarketID: marketID,
})
if err != nil {
return err
}
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryCurrentPrice)
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryPrice)
res, _, err := cliCtx.QueryWithData(route, bz)
if err != nil {
@ -70,7 +101,7 @@ func GetCmdRawPrices(queryRoute string, cdc *codec.Codec) *cobra.Command {
cliCtx := context.NewCLIContext().WithCodec(cdc)
marketID := args[0]
bz, err := cdc.MarshalJSON(types.QueryPricesParams{
bz, err := cdc.MarshalJSON(types.QueryWithMarketIDParams{
MarketID: marketID,
})
if err != nil {

View File

@ -14,59 +14,104 @@ import (
// define routes that get registered by the main application
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/%s/rawprices/{%s}", types.ModuleName, restName), queryRawPricesHandler(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/currentprice/{%s}", types.ModuleName, restName), queryCurrentPriceHandler(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/markets", types.ModuleName), queryMarketsHandler(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/params", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/parameters", types.ModuleName), queryParamsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/markets", types.ModuleName), queryMarketsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/oracles/{%s}", types.ModuleName, RestMarketID), queryOraclesHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/rawprices/{%s}", types.ModuleName, RestMarketID), queryRawPricesHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/%s/price/{%s}", types.ModuleName, RestMarketID), queryPriceHandlerFn(cliCtx)).Methods("GET")
}
func queryRawPricesHandler(cliCtx context.CLIContext) http.HandlerFunc {
func queryRawPricesHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
paramType := vars[restName]
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/rawprices/%s", paramType), nil)
paramMarketID := vars[RestMarketID]
queryRawPricesParams := types.NewQueryWithMarketIDParams(paramMarketID)
bz, err := cliCtx.Codec.MarshalJSON(queryRawPricesParams)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryRawPrices), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryCurrentPriceHandler(cliCtx context.CLIContext) http.HandlerFunc {
func queryPriceHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
paramType := vars[restName]
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/price/%s", paramType), nil)
paramMarketID := vars[RestMarketID]
queryPriceParams := types.NewQueryWithMarketIDParams(paramMarketID)
bz, err := cliCtx.Codec.MarshalJSON(queryPriceParams)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryPrice), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryMarketsHandler(cliCtx context.CLIContext) http.HandlerFunc {
func queryMarketsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/markets/"), nil)
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryMarkets), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryOraclesHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
paramMarketID := vars[RestMarketID]
queryOraclesParams := types.NewQueryWithMarketIDParams(paramMarketID)
bz, err := cliCtx.Codec.MarshalJSON(queryOraclesParams)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryOracles), bz)
if err != nil {
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}
func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Get the params
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/pricefeed/%s", types.QueryGetParams), nil)
cliCtx = cliCtx.WithHeight(height)
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetParams), nil)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
// Return the params
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, res)
}
}

View File

@ -7,10 +7,11 @@ import (
)
const (
restName = "marketID"
RestMarketID = "market_id"
)
type postPriceReq struct {
// PostPriceReq defines the properties of a PostPrice request's body.
type PostPriceReq struct {
BaseReq rest.BaseReq `json:"base_req"`
MarketID string `json:"market_id"`
Price string `json:"price"`

View File

@ -5,23 +5,23 @@ import (
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/gorilla/mux"
"github.com/kava-labs/kava/x/pricefeed/types"
tmtime "github.com/tendermint/tendermint/types/time"
)
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
r.HandleFunc(fmt.Sprintf("/%s/rawprices", types.ModuleName), postPriceHandler(cliCtx)).Methods("PUT")
r.HandleFunc(fmt.Sprintf("/%s/postprice", types.ModuleName), postPriceHandlerFn(cliCtx)).Methods("PUT")
}
func postPriceHandler(cliCtx context.CLIContext) http.HandlerFunc {
func postPriceHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req postPriceReq
var req PostPriceReq
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request")
@ -62,5 +62,4 @@ func postPriceHandler(cliCtx context.CLIContext) http.HandlerFunc {
utils.WriteGenerateStdTxResponse(w, cliCtx, baseReq, []sdk.Msg{msg})
}
}
}

View File

@ -15,10 +15,12 @@ import (
func NewQuerier(keeper Keeper) sdk.Querier {
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
switch path[0] {
case types.QueryCurrentPrice:
return queryCurrentPrice(ctx, req, keeper)
case types.QueryPrice:
return queryPrice(ctx, req, keeper)
case types.QueryRawPrices:
return queryRawPrices(ctx, req, keeper)
case types.QueryOracles:
return queryOracles(ctx, req, keeper)
case types.QueryMarkets:
return queryMarkets(ctx, req, keeper)
case types.QueryGetParams:
@ -30,8 +32,8 @@ func NewQuerier(keeper Keeper) sdk.Querier {
}
func queryCurrentPrice(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, sdkErr sdk.Error) {
var requestParams types.QueryPricesParams
func queryPrice(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, sdkErr sdk.Error) {
var requestParams types.QueryWithMarketIDParams
err := keeper.cdc.UnmarshalJSON(req.Data, &requestParams)
if err != nil {
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
@ -53,7 +55,7 @@ func queryCurrentPrice(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (r
}
func queryRawPrices(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, sdkErr sdk.Error) {
var requestParams types.QueryPricesParams
var requestParams types.QueryWithMarketIDParams
err := keeper.cdc.UnmarshalJSON(req.Data, &requestParams)
if err != nil {
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
@ -72,6 +74,26 @@ func queryRawPrices(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res
return bz, nil
}
func queryOracles(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, sdkErr sdk.Error) {
var requestParams types.QueryWithMarketIDParams
err := keeper.cdc.UnmarshalJSON(req.Data, &requestParams)
if err != nil {
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
}
oracles, err := keeper.GetOracles(ctx, requestParams.MarketID)
if err != nil {
return []byte{}, sdk.ErrUnknownRequest("market not found")
}
bz, err := codec.MarshalJSONIndent(keeper.cdc, oracles)
if err != nil {
panic("could not marshal result to JSON")
}
return bz, nil
}
func queryMarkets(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []byte, sdkErr sdk.Error) {
markets := keeper.GetMarkets(ctx)
@ -83,9 +105,8 @@ func queryMarkets(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) (res []
return bz, nil
}
// query params in the auction store
// query params in the pricefeed store
func queryGetParams(ctx sdk.Context, req abci.RequestQuery, keeper Keeper) ([]byte, sdk.Error) {
// Get params
params := keeper.GetParams(ctx)
// Encode results

View File

@ -5,17 +5,26 @@ package types
// assets Returns []Assets in the pricefeed system
const (
// QueryCurrentPrice command for current price queries
QueryCurrentPrice = "price"
// QueryRawPrices command for raw price queries
QueryRawPrices = "rawprices"
// QueryGetParams command for params query
QueryGetParams = "parameters"
// QueryMarkets command for assets query
QueryMarkets = "markets"
// QueryGetParams command for params query
QueryGetParams = "params"
// QueryOracles command for oracles query
QueryOracles = "oracles"
// QueryRawPrices command for raw price queries
QueryRawPrices = "rawprices"
// QueryPrice command for price queries
QueryPrice = "price"
)
// QueryPricesParams fields for querying prices
type QueryPricesParams struct {
// QueryWithMarketIDParams fields for querying information from a specific market
type QueryWithMarketIDParams struct {
MarketID string
}
// NewQueryWithMarketIDParams creates a new instance of QueryWithMarketIDParams
func NewQueryWithMarketIDParams(marketID string) QueryWithMarketIDParams {
return QueryWithMarketIDParams{
MarketID: marketID,
}
}