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
159 lines
5.0 KiB
Go
159 lines
5.0 KiB
Go
package rest
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
|
|
"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"
|
|
authclient "github.com/cosmos/cosmos-sdk/x/auth/client"
|
|
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
)
|
|
|
|
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
|
r.HandleFunc(
|
|
"/staking/delegators/{delegatorAddr}/delegations",
|
|
postDelegationsHandlerFn(cliCtx),
|
|
).Methods("POST")
|
|
r.HandleFunc(
|
|
"/staking/delegators/{delegatorAddr}/unbonding_delegations",
|
|
postUnbondingDelegationsHandlerFn(cliCtx),
|
|
).Methods("POST")
|
|
r.HandleFunc(
|
|
"/staking/delegators/{delegatorAddr}/redelegations",
|
|
postRedelegationsHandlerFn(cliCtx),
|
|
).Methods("POST")
|
|
}
|
|
|
|
type (
|
|
// DelegateRequest defines the properties of a delegation request's body.
|
|
DelegateRequest struct {
|
|
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address" yaml:"delegator_address"` // in bech32
|
|
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"` // in bech32
|
|
Amount sdk.Coin `json:"amount" yaml:"amount"`
|
|
}
|
|
|
|
// RedelegateRequest defines the properties of a redelegate request's body.
|
|
RedelegateRequest struct {
|
|
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address" yaml:"delegator_address"` // in bech32
|
|
ValidatorSrcAddress sdk.ValAddress `json:"validator_src_address" yaml:"validator_src_address"` // in bech32
|
|
ValidatorDstAddress sdk.ValAddress `json:"validator_dst_address" yaml:"validator_dst_address"` // in bech32
|
|
Amount sdk.Coin `json:"amount" yaml:"amount"`
|
|
}
|
|
|
|
// UndelegateRequest defines the properties of a undelegate request's body.
|
|
UndelegateRequest struct {
|
|
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
|
|
DelegatorAddress sdk.AccAddress `json:"delegator_address" yaml:"delegator_address"` // in bech32
|
|
ValidatorAddress sdk.ValAddress `json:"validator_address" yaml:"validator_address"` // in bech32
|
|
Amount sdk.Coin `json:"amount" yaml:"amount"`
|
|
}
|
|
)
|
|
|
|
func postDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var req DelegateRequest
|
|
|
|
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
|
|
return
|
|
}
|
|
|
|
req.BaseReq = req.BaseReq.Sanitize()
|
|
if !req.BaseReq.ValidateBasic(w) {
|
|
return
|
|
}
|
|
|
|
msg := types.NewMsgDelegate(req.DelegatorAddress, req.ValidatorAddress, req.Amount)
|
|
if err := msg.ValidateBasic(); err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
if !bytes.Equal(fromAddr, req.DelegatorAddress) {
|
|
rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address")
|
|
return
|
|
}
|
|
|
|
authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg})
|
|
}
|
|
}
|
|
|
|
func postRedelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var req RedelegateRequest
|
|
|
|
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
|
|
return
|
|
}
|
|
|
|
req.BaseReq = req.BaseReq.Sanitize()
|
|
if !req.BaseReq.ValidateBasic(w) {
|
|
return
|
|
}
|
|
|
|
msg := types.NewMsgBeginRedelegate(req.DelegatorAddress, req.ValidatorSrcAddress, req.ValidatorDstAddress, req.Amount)
|
|
if err := msg.ValidateBasic(); err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
if !bytes.Equal(fromAddr, req.DelegatorAddress) {
|
|
rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address")
|
|
return
|
|
}
|
|
|
|
authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg})
|
|
}
|
|
}
|
|
|
|
func postUnbondingDelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var req UndelegateRequest
|
|
|
|
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) {
|
|
return
|
|
}
|
|
|
|
req.BaseReq = req.BaseReq.Sanitize()
|
|
if !req.BaseReq.ValidateBasic(w) {
|
|
return
|
|
}
|
|
|
|
msg := types.NewMsgUndelegate(req.DelegatorAddress, req.ValidatorAddress, req.Amount)
|
|
if err := msg.ValidateBasic(); err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
fromAddr, err := sdk.AccAddressFromBech32(req.BaseReq.From)
|
|
if err != nil {
|
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
if !bytes.Equal(fromAddr, req.DelegatorAddress) {
|
|
rest.WriteErrorResponse(w, http.StatusUnauthorized, "must use own delegator address")
|
|
return
|
|
}
|
|
|
|
authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg})
|
|
}
|
|
}
|