Added POST /stake/bondunbond endpoint
This commit is contained in:
parent
efd1a3ac44
commit
ad3c63dded
|
@ -14,13 +14,12 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
// RegisterRoutes - Central function to define routes that get registered by the main application
|
||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/stake/{delegator}/bonding_status/{validator}", BondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
|
||||
func registerQueryRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/stake/{delegator}/bonding_status/{candidate}", bondingStatusHandlerFn("stake", cdc, kb, ctx)).Methods("GET")
|
||||
}
|
||||
|
||||
// BondingStatusHandlerFn - http request handler to query delegator bonding status
|
||||
func BondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
||||
func bondingStatusHandlerFn(storeName string, cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// read parameters
|
||||
vars := mux.Vars(r)
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/tendermint/go-crypto/keys"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
registerQueryRoutes(ctx, r, cdc, kb)
|
||||
registerTxRoutes(ctx, r, cdc, kb)
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/tendermint/go-crypto/keys"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
func registerTxRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) {
|
||||
r.HandleFunc("/stake/bondunbond", bondUnbondRequestHandlerFn(cdc, kb, ctx)).Methods("POST")
|
||||
}
|
||||
|
||||
type bond struct {
|
||||
Amount sdk.Coin `json:"amount"`
|
||||
Candidate sdk.Address `json:"candidate"`
|
||||
}
|
||||
|
||||
type unbond struct {
|
||||
Shares string `json:"shares"`
|
||||
Candidate sdk.Address `json:"candidate"`
|
||||
}
|
||||
|
||||
type bondUnbondBody struct {
|
||||
// fees is not used currently
|
||||
// Fees sdk.Coin `json="fees"`
|
||||
LocalAccountName string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
ChainID string `json:"chain_id"`
|
||||
Sequence int64 `json:"sequence"`
|
||||
Bond []bond `json:"bond"`
|
||||
Unbond []unbond `json:"unbond"`
|
||||
}
|
||||
|
||||
func bondUnbondRequestHandlerFn(cdc *wire.Codec, kb keys.Keybase, ctx context.CoreContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var m bondUnbondBody
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
info, err := kb.Get(m.LocalAccountName)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
// build messages
|
||||
messages := make([]sdk.Msg, 0, len(m.Bond)+len(m.Unbond))
|
||||
for _, bond := range m.Bond {
|
||||
msg := stake.NewMsgDelegate(info.Address(), bond.Candidate, bond.Amount)
|
||||
messages = append(messages, msg)
|
||||
}
|
||||
for _, unbond := range m.Unbond {
|
||||
msg := stake.NewMsgUnbond(info.Address(), unbond.Candidate, unbond.Shares)
|
||||
messages = append(messages, msg)
|
||||
}
|
||||
|
||||
// sign messages
|
||||
signedTxs := make([][]byte, 0, len(messages))
|
||||
for _, msg := range messages {
|
||||
// increment sequence for each message
|
||||
ctx = ctx.WithSequence(m.Sequence)
|
||||
m.Sequence++
|
||||
|
||||
txBytes, err := ctx.SignAndBuild(m.LocalAccountName, m.Password, msg, cdc)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
signedTxs = append(signedTxs, txBytes)
|
||||
}
|
||||
|
||||
// send
|
||||
// XXX the operation might not be atomic if a tx fails
|
||||
// should we have a sdk.MultiMsg type to make sending atomic?
|
||||
results := make([]*ctypes.ResultBroadcastTxCommit, 0, len(signedTxs))
|
||||
for _, txBytes := range signedTxs {
|
||||
res, err := ctx.BroadcastTx(txBytes)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
results = append(results, res)
|
||||
}
|
||||
|
||||
output, err := json.MarshalIndent(results, "", " ")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
w.Write(output)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue