Skip to content

Commit

Permalink
Feature: token details endpoint (#8)
Browse files Browse the repository at this point in the history
* add: token image config

* add: token details endpoint
  • Loading branch information
mhrynenko authored Jun 19, 2024
1 parent 02bee16 commit 05695bd
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 0 deletions.
1 change: 1 addition & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ routing:
airdrop:
amount: amount # amount in natural numbers (1, 2, 10 etc.) decimals part is taken directly from the contract
token_address: erc20_token_address
token_image: image_url # token image URL to display in FE

broadcaster:
rpc: evm_rpc_url
Expand Down
31 changes: 31 additions & 0 deletions docs/spec/components/schemas/TokenDetails.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
allOf:
- $ref: '#/components/schemas/TokenKey'
- type: object
required:
- attributes
properties:
attributes:
type: object
required:
- name
- symbol
- decimals
- image
properties:
name:
type: string
description: ERC20 token name
example: "USD Dollar"
symbol:
type: string
description: ERC20 token symbol
example: "USDD"
decimals:
type: integer
format: uint8
description: ERC20 token decimals
example: 12
image:
type: string
description: ERC20 token symbol image
example: "https://image_link/usdd.png"
21 changes: 21 additions & 0 deletions docs/spec/paths/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
get:
tags:
- Tokens
summary: Get details
description: Get service token's details
operationId: GetDetails
responses:
200:
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/TokenDetails'
400:
$ref: '#/components/responses/invalidParameter'
500:
$ref: '#/components/responses/internalError'
2 changes: 2 additions & 0 deletions internal/config/airdrop.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"math/big"
"net/url"

"github.com/ethereum/go-ethereum/common"
"gitlab.com/distributed_lab/figure/v3"
Expand All @@ -20,6 +21,7 @@ type AirdropConfiger interface {
type AirdropConfig struct {
Amount *big.Int `fig:"amount,required"`
TokenAddress common.Address `fig:"token_address,required"`
TokenImage *url.URL `fig:"token_image,required"`
}

type airdrop struct {
Expand Down
42 changes: 42 additions & 0 deletions internal/service/api/handlers/get_token_details.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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"
"gitlab.com/distributed_lab/ape"
"gitlab.com/distributed_lab/ape/problems"
)

func GetTokenDetails(w http.ResponseWriter, r *http.Request) {
name, err := api.ERC20Permit(r).Name(&bind.CallOpts{})
if err != nil {
api.Log(r).WithError(err).Error("failed to get token name")
ape.RenderErr(w, problems.InternalError())
return
}

symbol, err := api.ERC20Permit(r).Symbol(&bind.CallOpts{})
if err != nil {
api.Log(r).WithError(err).Error("failed to get token symbol")
ape.RenderErr(w, problems.InternalError())
return
}

decimals, err := api.ERC20Permit(r).Decimals(&bind.CallOpts{})
if err != nil {
api.Log(r).WithError(err).Error("failed to get token decimals")
ape.RenderErr(w, problems.InternalError())
return
}

ape.Render(w, models.NewTokenDetailsResponse(
api.AirdropConfig(r).TokenAddress.String(),
name,
symbol,
api.AirdropConfig(r).TokenImage.String(),
decimals,
))
}
17 changes: 17 additions & 0 deletions internal/service/api/models/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,20 @@ func NewBalanceResponse(addr string, amount *big.Int) resources.BalanceResponse
},
}
}

func NewTokenDetailsResponse(addr, name, symbol, image string, decimals uint8) resources.TokenDetailsResponse {
return resources.TokenDetailsResponse{
Data: resources.TokenDetails{
Key: resources.Key{
ID: addr,
Type: resources.TOKEN,
},
Attributes: resources.TokenDetailsAttributes{
Name: name,
Symbol: symbol,
Decimals: decimals,
Image: image,
},
},
}
}
1 change: 1 addition & 0 deletions internal/service/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func Run(ctx context.Context, cfg *config.Config) {

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

Expand Down
43 changes: 43 additions & 0 deletions resources/model_token_details.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 TokenDetails struct {
Key
Attributes TokenDetailsAttributes `json:"attributes"`
}
type TokenDetailsResponse struct {
Data TokenDetails `json:"data"`
Included Included `json:"included"`
}

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

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

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

// MustTokenDetails - returns TokenDetails 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) MustTokenDetails(key Key) *TokenDetails {
var tokenDetails TokenDetails
if c.tryFindEntry(key, &tokenDetails) {
return &tokenDetails
}
return nil
}
16 changes: 16 additions & 0 deletions resources/model_token_details_attributes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* GENERATED. Do not modify. Your changes might be overwritten!
*/

package resources

type TokenDetailsAttributes struct {
// ERC20 token decimals
Decimals uint8 `json:"decimals"`
// ERC20 token symbol image
Image string `json:"image"`
// ERC20 token name
Name string `json:"name"`
// ERC20 token symbol
Symbol string `json:"symbol"`
}

0 comments on commit 05695bd

Please sign in to comment.