wasmd/x/wasm/client/rest/tx.go

150 lines
3.8 KiB
Go

package rest
import (
"net/http"
"strconv"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/rest"
"github.com/gorilla/mux"
wasmUtils "github.com/CosmWasm/wasmd/x/wasm/client/utils"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
func registerTxRoutes(cliCtx client.Context, r *mux.Router) {
r.HandleFunc("/wasm/code", storeCodeHandlerFn(cliCtx)).Methods("POST")
r.HandleFunc("/wasm/code/{codeId}", instantiateContractHandlerFn(cliCtx)).Methods("POST")
r.HandleFunc("/wasm/contract/{contractAddr}", executeContractHandlerFn(cliCtx)).Methods("POST")
}
type storeCodeReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
WasmBytes []byte `json:"wasm_bytes"`
}
type instantiateContractReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
Label string `json:"label" yaml:"label"`
Deposit sdk.Coins `json:"deposit" yaml:"deposit"`
Admin string `json:"admin,omitempty" yaml:"admin"`
Msg []byte `json:"msg" yaml:"msg"`
}
type executeContractReq struct {
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
ExecMsg []byte `json:"exec_msg" yaml:"exec_msg"`
Amount sdk.Coins `json:"coins" yaml:"coins"`
}
func storeCodeHandlerFn(cliCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req storeCodeReq
if !rest.ReadRESTReq(w, r, cliCtx.LegacyAmino, &req) {
return
}
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
var err error
wasm := req.WasmBytes
// gzip the wasm file
if wasmUtils.IsWasm(wasm) {
wasm, err = wasmUtils.GzipIt(wasm)
if err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
} else if !wasmUtils.IsGzip(wasm) {
rest.WriteErrorResponse(w, http.StatusBadRequest, "Invalid input file, use wasm binary or zip")
return
}
// build and sign the transaction, then broadcast to Tendermint
msg := types.MsgStoreCode{
Sender: req.BaseReq.From,
WASMByteCode: wasm,
}
if err := msg.ValidateBasic(); err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
tx.WriteGeneratedTxResponse(cliCtx, w, req.BaseReq, &msg)
}
}
func instantiateContractHandlerFn(cliCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req instantiateContractReq
if !rest.ReadRESTReq(w, r, cliCtx.LegacyAmino, &req) {
return
}
vars := mux.Vars(r)
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
// get the id of the code to instantiate
codeID, err := strconv.ParseUint(vars["codeId"], 10, 64)
if err != nil {
return
}
msg := types.MsgInstantiateContract{
Sender: req.BaseReq.From,
CodeID: codeID,
Label: req.Label,
Funds: req.Deposit,
Msg: req.Msg,
Admin: req.Admin,
}
if err := msg.ValidateBasic(); err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
tx.WriteGeneratedTxResponse(cliCtx, w, req.BaseReq, &msg)
}
}
func executeContractHandlerFn(cliCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req executeContractReq
if !rest.ReadRESTReq(w, r, cliCtx.LegacyAmino, &req) {
return
}
vars := mux.Vars(r)
contractAddr := vars["contractAddr"]
req.BaseReq = req.BaseReq.Sanitize()
if !req.BaseReq.ValidateBasic(w) {
return
}
msg := types.MsgExecuteContract{
Sender: req.BaseReq.From,
Contract: contractAddr,
Msg: req.ExecMsg,
Funds: req.Amount,
}
if err := msg.ValidateBasic(); err != nil {
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
return
}
tx.WriteGeneratedTxResponse(cliCtx, w, req.BaseReq, &msg)
}
}