snapshot: 12-ebening

This commit is contained in:
Mohamed Sohail 2023-02-12 16:53:53 +03:00
parent 4f7909e4ee
commit f2ba079232
Signed by: kamikazechaser
GPG Key ID: 7DD45520C01CD85D
6 changed files with 58 additions and 60 deletions

View File

@ -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)

View File

@ -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"

View File

@ -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,
},
})
}

View File

@ -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,
},
})
}
}

View File

@ -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"`
}

View File

@ -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,
})