From 7ce44d6c63312cf9a33c0a68287e5180fd1c6e71 Mon Sep 17 00:00:00 2001 From: Maksym Hrynenko Date: Wed, 19 Jun 2024 12:15:22 +0300 Subject: [PATCH] add: token details endpoint --- .../spec/components/schemas/TokenDetails.yaml | 31 +++++++++++++ docs/spec/paths/token@details.yaml | 21 +++++++++ .../service/api/handlers/get_token_details.go | 42 ++++++++++++++++++ internal/service/api/models/token.go | 17 ++++++++ internal/service/router.go | 1 + resources/model_token_details.go | 43 +++++++++++++++++++ resources/model_token_details_attributes.go | 16 +++++++ 7 files changed, 171 insertions(+) create mode 100644 docs/spec/components/schemas/TokenDetails.yaml create mode 100644 docs/spec/paths/token@details.yaml create mode 100644 internal/service/api/handlers/get_token_details.go create mode 100644 resources/model_token_details.go create mode 100644 resources/model_token_details_attributes.go diff --git a/docs/spec/components/schemas/TokenDetails.yaml b/docs/spec/components/schemas/TokenDetails.yaml new file mode 100644 index 0000000..7297d49 --- /dev/null +++ b/docs/spec/components/schemas/TokenDetails.yaml @@ -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" diff --git a/docs/spec/paths/token@details.yaml b/docs/spec/paths/token@details.yaml new file mode 100644 index 0000000..295b199 --- /dev/null +++ b/docs/spec/paths/token@details.yaml @@ -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' diff --git a/internal/service/api/handlers/get_token_details.go b/internal/service/api/handlers/get_token_details.go new file mode 100644 index 0000000..ba5847b --- /dev/null +++ b/internal/service/api/handlers/get_token_details.go @@ -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, + )) +} diff --git a/internal/service/api/models/token.go b/internal/service/api/models/token.go index d40a632..d3c4ef0 100644 --- a/internal/service/api/models/token.go +++ b/internal/service/api/models/token.go @@ -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, + }, + }, + } +} diff --git a/internal/service/router.go b/internal/service/router.go index eec9519..d6784e6 100644 --- a/internal/service/router.go +++ b/internal/service/router.go @@ -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) }) }) diff --git a/resources/model_token_details.go b/resources/model_token_details.go new file mode 100644 index 0000000..10c3a78 --- /dev/null +++ b/resources/model_token_details.go @@ -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 +} diff --git a/resources/model_token_details_attributes.go b/resources/model_token_details_attributes.go new file mode 100644 index 0000000..dfde25c --- /dev/null +++ b/resources/model_token_details_attributes.go @@ -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"` +}