mirror of
https://github.com/grassrootseconomics/cic-custodial.git
synced 2024-11-21 13:56:47 +01:00
snapshot: 12-ebening
This commit is contained in:
parent
4f7909e4ee
commit
f2ba079232
@ -1,9 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/VictoriaMetrics/metrics"
|
||||
"github.com/go-playground/validator"
|
||||
"github.com/grassrootseconomics/cic-custodial/internal/api"
|
||||
"github.com/hibiken/asynq"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
@ -14,6 +18,27 @@ func initApiServer(custodialContainer *custodial) *echo.Echo {
|
||||
server.HideBanner = true
|
||||
server.HidePort = true
|
||||
|
||||
server.HTTPErrorHandler = func(err error, c echo.Context) {
|
||||
// Handle asynq duplication errors across all api handlers.
|
||||
if errors.Is(err, asynq.ErrTaskIDConflict) {
|
||||
c.JSON(http.StatusForbidden, api.ErrResp{
|
||||
Ok: false,
|
||||
Code: api.DUPLICATE_ERROR,
|
||||
Message: "Request with duplicate tracking id submitted.",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Log internal server error for further investigation.
|
||||
lo.Error("api:", "path", c.Path(), "err", err)
|
||||
|
||||
c.JSON(http.StatusInternalServerError, api.ErrResp{
|
||||
Ok: false,
|
||||
Code: api.INTERNAL_ERROR,
|
||||
Message: "Internal server error.",
|
||||
})
|
||||
}
|
||||
|
||||
if ko.Bool("service.metrics") {
|
||||
server.GET("/metrics", func(c echo.Context) error {
|
||||
metrics.WritePrometheus(c.Response(), true)
|
||||
|
10
config.toml
10
config.toml
@ -9,8 +9,8 @@ metrics = true
|
||||
[system]
|
||||
# The giftable token is a training voucher
|
||||
# Every new user is given 5 DGFT
|
||||
gas_faucet = "0x6dE38F79Cf455339e8141D15E208ba09eea634e1"
|
||||
giftable_token_address = "0x4091fc149522d5FE31d0970687078B1aE0625892"
|
||||
gas_faucet = "0xA8b3Ffc715e85792FB361BDee9357B38D5A4a6cF"
|
||||
giftable_token_address = "0xdD4F5ea484F6b16f031eF7B98F3810365493BC20"
|
||||
giftable_token_value = 5000000
|
||||
gas_refill_threshold = 100000000000000000
|
||||
gas_refill_value = 100000000000000000
|
||||
@ -18,12 +18,12 @@ gas_refill_value = 100000000000000000
|
||||
giftable_gas_value = 2000000000000000000
|
||||
# System private key
|
||||
# Should always be toped up
|
||||
private_key = "d87f322629cf071ccd3ddf17ab5e1abf098a25c4c5d791d7535d265379b2ae37"
|
||||
private_key = "bfa7222a7bea3bde312434abe819b14cf3bc8703ceaabb98a9e3a97ceb0b79fd"
|
||||
lock_prefix = "lock:"
|
||||
public_key = "0xe5ab7A5af1f28aA8E9658AC33a6ebF2a8641d948"
|
||||
public_key = "0x08eb3a90128D5874da54cf654fCfA88cEd1bb047"
|
||||
token_decimals = 6
|
||||
token_transfer_gas_limit = 200000
|
||||
account_index = "0x70138F458Fa56C034acb19E38d082843327F18A4"
|
||||
account_index = "0xdb2550ac5E52A54B6189FFAf17ECfF33AE190db9"
|
||||
|
||||
[chain]
|
||||
rpc_endpoint = "http://192.168.0.101:8545"
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/grassrootseconomics/cic-custodial/internal/keystore"
|
||||
"github.com/grassrootseconomics/cic-custodial/internal/tasker"
|
||||
"github.com/grassrootseconomics/cic-custodial/internal/tasker/task"
|
||||
@ -13,76 +14,50 @@ import (
|
||||
|
||||
// CreateAccountHandler route.
|
||||
// POST: /api/account/create
|
||||
// JSON Body:
|
||||
// trackingId -> Unique string
|
||||
// Returns the public key.
|
||||
func CreateAccountHandler(
|
||||
keystore keystore.Keystore,
|
||||
taskerClient *tasker.TaskerClient,
|
||||
) func(echo.Context) error {
|
||||
return func(c echo.Context) error {
|
||||
var accountRequest struct {
|
||||
TrackingId string `json:"trackingId" validate:"required"`
|
||||
}
|
||||
|
||||
if err := c.Bind(&accountRequest); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
}
|
||||
|
||||
if err := c.Validate(accountRequest); err != nil {
|
||||
return err
|
||||
}
|
||||
trackingId := uuid.NewString()
|
||||
|
||||
generatedKeyPair, err := keypair.Generate()
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := keystore.WriteKeyPair(c.Request().Context(), generatedKeyPair)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
taskPayload, err := json.Marshal(task.AccountPayload{
|
||||
PublicKey: generatedKeyPair.Public,
|
||||
TrackingId: accountRequest.TrackingId,
|
||||
TrackingId: trackingId,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = taskerClient.CreateTask(
|
||||
tasker.PrepareAccountTask,
|
||||
tasker.DefaultPriority,
|
||||
&tasker.Task{
|
||||
Id: accountRequest.TrackingId,
|
||||
Id: trackingId,
|
||||
Payload: taskPayload,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, okResp{
|
||||
return c.JSON(http.StatusOK, OkResp{
|
||||
Ok: true,
|
||||
Result: H{
|
||||
"publicKey": generatedKeyPair.Public,
|
||||
"custodialId": id,
|
||||
"trackingId": trackingId,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/grassrootseconomics/cic-custodial/internal/tasker"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
@ -22,8 +23,9 @@ func SignTransferHandler(
|
||||
taskerClient *tasker.TaskerClient,
|
||||
) func(echo.Context) error {
|
||||
return func(c echo.Context) error {
|
||||
trackingId := uuid.NewString()
|
||||
|
||||
var transferRequest struct {
|
||||
TrackingId string `json:"trackingId" validate:"required"`
|
||||
From string `json:"from" validate:"required,eth_addr"`
|
||||
To string `json:"to" validate:"required,eth_addr"`
|
||||
VoucherAddress string `json:"voucherAddress" validate:"required,eth_addr"`
|
||||
@ -31,10 +33,7 @@ func SignTransferHandler(
|
||||
}
|
||||
|
||||
if err := c.Bind(&transferRequest); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.Validate(transferRequest); err != nil {
|
||||
@ -43,29 +42,26 @@ func SignTransferHandler(
|
||||
|
||||
taskPayload, err := json.Marshal(transferRequest)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = taskerClient.CreateTask(
|
||||
tasker.SignTransferTask,
|
||||
tasker.HighPriority,
|
||||
&tasker.Task{
|
||||
Id: transferRequest.TrackingId,
|
||||
Id: trackingId,
|
||||
Payload: taskPayload,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, errResp{
|
||||
Ok: false,
|
||||
Code: INTERNAL_ERROR,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, okResp{
|
||||
return c.JSON(http.StatusOK, OkResp{
|
||||
Ok: true,
|
||||
Result: H{
|
||||
"trackingId": trackingId,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -3,16 +3,18 @@ package api
|
||||
const (
|
||||
INTERNAL_ERROR = "ERR_INTERNAL"
|
||||
VALIDATION_ERROR = "ERR_VALIDATE"
|
||||
DUPLICATE_ERROR = "ERR_DUPLICATE"
|
||||
)
|
||||
|
||||
type H map[string]any
|
||||
|
||||
type okResp struct {
|
||||
type OkResp struct {
|
||||
Ok bool `json:"ok"`
|
||||
Result H `json:"result"`
|
||||
}
|
||||
|
||||
type errResp struct {
|
||||
Ok bool `json:"ok"`
|
||||
Code string `json:"errorCode"`
|
||||
type ErrResp struct {
|
||||
Ok bool `json:"ok"`
|
||||
Code string `json:"errorCode"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ type Validator struct {
|
||||
|
||||
func (v *Validator) Validate(i interface{}) error {
|
||||
if err := v.ValidatorProvider.Struct(i); err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, errResp{
|
||||
return echo.NewHTTPError(http.StatusBadRequest, ErrResp{
|
||||
Ok: false,
|
||||
Code: VALIDATION_ERROR,
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user