diff --git a/app/app.go b/app/app.go index 5f55a80..9a3b4ab 100644 --- a/app/app.go +++ b/app/app.go @@ -106,6 +106,7 @@ import ( sequencermodule "github.com/warp-contracts/sequencer/x/sequencer" sequencermodulekeeper "github.com/warp-contracts/sequencer/x/sequencer/keeper" sequencermoduletypes "github.com/warp-contracts/sequencer/x/sequencer/types" + arweaveapi "github.com/warp-contracts/sequencer/x/sequencer/api" // this line is used by starport scaffolding # stargate/app/moduleImport appparams "github.com/warp-contracts/sequencer/app/params" @@ -841,6 +842,9 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig // register app's OpenAPI routes. docs.RegisterOpenAPIService(Name, apiSvr.Router) + + // Register the route for sending Arweave transactions as JSON + arweaveapi.RegisterArweaveAPIRoute(clientCtx, apiSvr.Router) } // RegisterTxService implements the Application.RegisterTxService method. diff --git a/x/sequencer/api/arweave.go b/x/sequencer/api/arweave.go new file mode 100644 index 0000000..ae1af14 --- /dev/null +++ b/x/sequencer/api/arweave.go @@ -0,0 +1,62 @@ +package api + +import ( + "encoding/json" + "net/http" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/gorilla/mux" + "github.com/warp-contracts/sequencer/x/sequencer/types" +) + +type arweaveHandler struct { + ctx client.Context +} + +// The endpoint that accepts the Arweave transaction in the form of JSON, +// wraps it with a Cosmos transaction and broadcasts it to the network. +func RegisterArweaveAPIRoute(clientCtx client.Context, router *mux.Router) { + router.Handle("/arweave", arweaveHandler{ctx: clientCtx}).Methods("POST") +} + +func (h arweaveHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // parse JSON + var msg types.MsgArweave + decoder := json.NewDecoder(r.Body) + decoder.DisallowUnknownFields() + err := decoder.Decode(&msg) + if err != nil { + badRequest(w, err.Error()) + return + } + + // wrap Arweave message with Cosmos transaction + txBytes, err := createTxWithArweaveMsg(h.ctx, msg) + if err != nil { + badRequest(w, err.Error()) + return + } + + // broadcast transaction + response, err := h.ctx.BroadcastTxSync(txBytes) + if err != nil { + badRequest(w, err.Error()) + return + } + if response.Code != 0 { + badRequest(w, response.RawLog) + return + } + + w.Write([]byte(response.TxHash)) +} + +func badRequest(w http.ResponseWriter, errorMessage string) { + http.Error(w, errorMessage, http.StatusBadRequest) +} + +func createTxWithArweaveMsg(ctx client.Context, msg types.MsgArweave) ([]byte, error) { + txBuilder := ctx.TxConfig.NewTxBuilder() + txBuilder.SetMsgs(&msg) + return ctx.TxConfig.TxEncoder()(txBuilder.GetTx()) +}