Skip to content

Commit

Permalink
Add: get balance request (#6)
Browse files Browse the repository at this point in the history
* docs: get balance request

* update: dependencies

* update: generated docs

* add: get user balance endpoint
  • Loading branch information
mhrynenko authored Jun 13, 2024
1 parent 25cecb6 commit d281fa2
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 0 deletions.
16 changes: 16 additions & 0 deletions docs/spec/components/schemas/Balance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
allOf:
- $ref: '#/components/schemas/TokenKey'
- type: object
required:
- attributes
properties:
attributes:
type: object
required:
- amount
properties:
amount:
type: integer
format: "*big.Int"
description: Amount of the tokens on the user address
example: "123"
10 changes: 10 additions & 0 deletions docs/spec/components/schemas/TokenKey.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type: object
required:
- id
- type
properties:
id:
type: string
type:
type: string
enum: [ token ]
28 changes: 28 additions & 0 deletions docs/spec/paths/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
get:
tags:
- Tokens
summary: Get Balance
description: Get token's balance by the given user address
operationId: GetBalance
parameters:
- in: query
name: address
required: true
schema:
type: string
format: common.Address
responses:
200:
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/Balance'
400:
$ref: '#/components/responses/invalidParameter'
500:
$ref: '#/components/responses/internalError'
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
gitlab.com/distributed_lab/figure v2.1.2+incompatible // indirect
gitlab.com/distributed_lab/lorem v0.2.1 // indirect
gitlab.com/distributed_lab/urlval v3.0.0+incompatible // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2298,6 +2298,8 @@ gitlab.com/distributed_lab/lorem v0.2.1 h1:A1QoiEDRN3vlPrwsXJmPlENanQwu3FxpDl5vE
gitlab.com/distributed_lab/lorem v0.2.1/go.mod h1:wkzrGoB1L/yUBu56SfoJ/vNiPqiHZcg75AnBkWNcjhQ=
gitlab.com/distributed_lab/running v1.6.0 h1:O2GQHgYkpNRDbobR11atOCH2rhS1okNKyadiAqi+kQI=
gitlab.com/distributed_lab/running v1.6.0/go.mod h1:4TnADX84dQjQMRHKIMPCVL0L97rD/Jxv0xDbrN6aKzk=
gitlab.com/distributed_lab/urlval v3.0.0+incompatible h1:OWU3CcZU+z0BVooufOSQFO9biDfsjM3e7YYauC278HU=
gitlab.com/distributed_lab/urlval v3.0.0+incompatible/go.mod h1:cKnUlnZCHUuke/l95YLvW5JoGC2yn53HVgF9rt1WiIg=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI=
Expand Down
30 changes: 30 additions & 0 deletions internal/service/api/handlers/get_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package handlers

import (
"net/http"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/rarimo/evm-airdrop-svc/internal/service/api"
"github.com/rarimo/evm-airdrop-svc/internal/service/api/models"
"github.com/rarimo/evm-airdrop-svc/internal/service/api/requests"
"gitlab.com/distributed_lab/ape"
"gitlab.com/distributed_lab/ape/problems"
)

func GetBalance(w http.ResponseWriter, r *http.Request) {
req, err := requests.NewGetBalanceRequest(r)
if err != nil {
api.Log(r).WithError(err).Error("failed to parse request")
ape.RenderErr(w, problems.BadRequest(err)...)
return
}

balance, err := api.ERC20Permit(r).BalanceOf(&bind.CallOpts{}, req.Address)
if err != nil {
api.Log(r).WithError(err).Error("failed to get user balance")
ape.RenderErr(w, problems.InternalError())
return
}

ape.Render(w, models.NewBalanceResponse(req.Address.String(), balance))
}
21 changes: 21 additions & 0 deletions internal/service/api/models/token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package models

import (
"math/big"

"github.com/rarimo/evm-airdrop-svc/resources"
)

func NewBalanceResponse(addr string, amount *big.Int) resources.BalanceResponse {
return resources.BalanceResponse{
Data: resources.Balance{
Key: resources.Key{
ID: addr,
Type: resources.TOKEN,
},
Attributes: resources.BalanceAttributes{
Amount: amount,
},
},
}
}
32 changes: 32 additions & 0 deletions internal/service/api/requests/get_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package requests

import (
"net/http"

"github.com/ethereum/go-ethereum/common"
validation "github.com/go-ozzo/ozzo-validation/v4"
"gitlab.com/distributed_lab/logan/v3/errors"
"gitlab.com/distributed_lab/urlval"
)

type GetUserBalanceRequest struct {
Address common.Address `url:"address"`
}

func NewGetBalanceRequest(r *http.Request) (GetUserBalanceRequest, error) {
var req GetUserBalanceRequest

if err := urlval.Decode(r.URL.Query(), &req); err != nil {
return req, validation.Errors{
"query": errors.Wrap(err, "failed to decode url"),
}.Filter()
}

return req, req.validate()
}

func (r *GetUserBalanceRequest) validate() error {
return validation.Errors{
"/address": validation.Validate(r.Address, validation.Required),
}.Filter()
}
4 changes: 4 additions & 0 deletions internal/service/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func Run(ctx context.Context, cfg *config.Config) {

r.Post("/permit-hash", handlers.BuildPermitHash)
})

r.Route("/token", func(r chi.Router) {
r.Get("/balance", handlers.GetBalance)
})
})

cfg.Log().Info("Service started")
Expand Down
43 changes: 43 additions & 0 deletions resources/model_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* GENERATED. Do not modify. Your changes might be overwritten!
*/

package resources

import "encoding/json"

type Balance struct {
Key
Attributes BalanceAttributes `json:"attributes"`
}
type BalanceResponse struct {
Data Balance `json:"data"`
Included Included `json:"included"`
}

type BalanceListResponse struct {
Data []Balance `json:"data"`
Included Included `json:"included"`
Links *Links `json:"links"`
Meta json.RawMessage `json:"meta,omitempty"`
}

func (r *BalanceListResponse) PutMeta(v interface{}) (err error) {
r.Meta, err = json.Marshal(v)
return err
}

func (r *BalanceListResponse) GetMeta(out interface{}) error {
return json.Unmarshal(r.Meta, out)
}

// MustBalance - returns Balance from include collection.
// if entry with specified key does not exist - returns nil
// if entry with specified key exists but type or ID mismatches - panics
func (c *Included) MustBalance(key Key) *Balance {
var balance Balance
if c.tryFindEntry(key, &balance) {
return &balance
}
return nil
}
12 changes: 12 additions & 0 deletions resources/model_balance_attributes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* GENERATED. Do not modify. Your changes might be overwritten!
*/

package resources

import "math/big"

type BalanceAttributes struct {
// Amount of the tokens on the user address
Amount *big.Int `json:"amount"`
}
1 change: 1 addition & 0 deletions resources/model_resource_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ type ResourceType string
const (
AIRDROP ResourceType = "airdrop"
CREATE_AIRDROP ResourceType = "create_airdrop"
TOKEN ResourceType = "token"
TRANSFER_ERC20 ResourceType = "transfer_erc20"
)

0 comments on commit d281fa2

Please sign in to comment.