package rest import ( "fmt" "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" gcutils "github.com/cosmos/cosmos-sdk/x/gov/client/utils" "github.com/cosmos/cosmos-sdk/x/gov/types" ) func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router, phs []ProposalRESTHandler) { propSubRtr := r.PathPrefix("/gov/proposals").Subrouter() for _, ph := range phs { propSubRtr.HandleFunc(fmt.Sprintf("/%s", ph.SubRoute), ph.Handler).Methods("POST") } r.HandleFunc("/gov/proposals", postProposalHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/deposits", RestProposalID), depositHandlerFn(cliCtx)).Methods("POST") r.HandleFunc(fmt.Sprintf("/gov/proposals/{%s}/votes", RestProposalID), voteHandlerFn(cliCtx)).Methods("POST") } func postProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req PostProposalReq if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return } req.BaseReq = req.BaseReq.Sanitize() if !req.BaseReq.ValidateBasic(w) { return } proposalType := gcutils.NormalizeProposalType(req.ProposalType) content := types.ContentFromProposalType(req.Title, req.Description, proposalType) msg := types.NewMsgSubmitProposal(content, req.InitialDeposit, req.Proposer) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } func depositHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) strProposalID := vars[RestProposalID] if len(strProposalID) == 0 { rest.WriteErrorResponse(w, http.StatusBadRequest, "proposalId required but not specified") return } proposalID, ok := rest.ParseUint64OrReturnBadRequest(w, strProposalID) if !ok { return } var req DepositReq if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return } req.BaseReq = req.BaseReq.Sanitize() if !req.BaseReq.ValidateBasic(w) { return } // create the message msg := types.NewMsgDeposit(req.Depositor, proposalID, req.Amount) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } } func voteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) strProposalID := vars[RestProposalID] if len(strProposalID) == 0 { rest.WriteErrorResponse(w, http.StatusBadRequest, "proposalId required but not specified") return } proposalID, ok := rest.ParseUint64OrReturnBadRequest(w, strProposalID) if !ok { return } var req VoteReq if !rest.ReadRESTReq(w, r, cliCtx.Codec, &req) { return } req.BaseReq = req.BaseReq.Sanitize() if !req.BaseReq.ValidateBasic(w) { return } voteOption, err := types.VoteOptionFromString(gcutils.NormalizeVoteOption(req.Option)) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } // create the message msg := types.NewMsgVote(req.Voter, proposalID, voteOption) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return } authclient.WriteGenerateStdTxResponse(w, cliCtx, req.BaseReq, []sdk.Msg{msg}) } }