Packages named utils, common, or misc provide clients with no sense of what the package contains. This makes it harder for clients to use the package and makes it harder for maintainers to keep the package focused. Over time, they accumulate dependencies that can make compilation significantly and unnecessarily slower, especially in large programs. And since such package names are generic, they are more likely to collide with other packages imported by client code, forcing clients to invent names to distinguish them. cit. https://blog.golang.org/package-names
141 lines
3.8 KiB
Go
141 lines
3.8 KiB
Go
package rest
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"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"
|
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
genutilrest "github.com/cosmos/cosmos-sdk/x/genutil/client/rest"
|
|
)
|
|
|
|
// query accountREST Handler
|
|
func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
bech32addr := vars["address"]
|
|
|
|
addr, err := sdk.AccAddressFromBech32(bech32addr)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
accGetter := types.NewAccountRetriever(cliCtx)
|
|
|
|
account, height, err := accGetter.GetAccountWithHeight(addr)
|
|
if err != nil {
|
|
// TODO: Handle more appropriately based on the error type.
|
|
// Ref: https://github.com/cosmos/cosmos-sdk/issues/4923
|
|
if err := accGetter.EnsureExists(addr); err != nil {
|
|
cliCtx = cliCtx.WithHeight(height)
|
|
rest.PostProcessResponse(w, cliCtx, types.BaseAccount{})
|
|
return
|
|
}
|
|
|
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
cliCtx = cliCtx.WithHeight(height)
|
|
rest.PostProcessResponse(w, cliCtx, account)
|
|
}
|
|
}
|
|
|
|
// QueryTxsHandlerFn implements a REST handler that searches for transactions.
|
|
// Genesis transactions are returned if the height parameter is set to zero,
|
|
// otherwise the transactions are searched for by events.
|
|
func QueryTxsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
err := r.ParseForm()
|
|
if err != nil {
|
|
rest.WriteErrorResponse(
|
|
w, http.StatusBadRequest,
|
|
fmt.Sprintf("failed to parse query parameters: %s", err),
|
|
)
|
|
return
|
|
}
|
|
|
|
// if the height query param is set to zero, query for genesis transactions
|
|
heightStr := r.FormValue("height")
|
|
if heightStr != "" {
|
|
if height, err := strconv.ParseInt(heightStr, 10, 64); err == nil && height == 0 {
|
|
genutilrest.QueryGenesisTxs(cliCtx, w)
|
|
return
|
|
}
|
|
}
|
|
|
|
var (
|
|
events []string
|
|
txs []sdk.TxResponse
|
|
page, limit int
|
|
)
|
|
|
|
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if len(r.Form) == 0 {
|
|
rest.PostProcessResponseBare(w, cliCtx, txs)
|
|
return
|
|
}
|
|
|
|
events, page, limit, err = rest.ParseHTTPArgs(r)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
searchResult, err := client.QueryTxsByEvents(cliCtx, events, page, limit)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
rest.PostProcessResponseBare(w, cliCtx, searchResult)
|
|
}
|
|
}
|
|
|
|
// QueryTxRequestHandlerFn implements a REST handler that queries a transaction
|
|
// by hash in a committed block.
|
|
func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
hashHexStr := vars["hash"]
|
|
|
|
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
output, err := client.QueryTx(cliCtx, hashHexStr)
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), hashHexStr) {
|
|
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
|
|
return
|
|
}
|
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
if output.Empty() {
|
|
rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr))
|
|
}
|
|
|
|
rest.PostProcessResponseBare(w, cliCtx, output)
|
|
}
|
|
}
|