Adds circulating supply endpoint / service / controller (#1771)

* Adds circulating supply endpoint / service / controller

* modify supply endpoint to response in json format, add docs

---------

Co-authored-by: Agustin Pazos <agpazos85@gmail.com>
This commit is contained in:
Gabriel Zimmermann 2024-10-07 16:30:45 -03:00 committed by GitHub
parent 7206d079e3
commit 02e3561226
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 1944 additions and 4 deletions

View File

@ -825,7 +825,7 @@ const docTemplate = `{
},
"/api/v1/native-token-transfer/top-holder": {
"get": {
"description": "Returns a list of volume of the Native Token Transfer for holder.",
"description": "Returns a list of volume and chain of the Native Token Transfer for top holders.",
"tags": [
"wormholescan"
],
@ -1398,6 +1398,23 @@ const docTemplate = `{
}
}
},
"/api/v1/supply": {
"get": {
"description": "Get W token circulation supply.",
"tags": [
"wormholescan"
],
"operationId": "supply",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/supply.CirculatingSupplyResponse"
}
}
}
}
},
"/api/v1/token/:chain_id/:token_address": {
"get": {
"description": "Returns a token symbol, coingecko id and address by chain and token address.",
@ -1557,6 +1574,23 @@ const docTemplate = `{
}
}
},
"/api/v1/total-supply": {
"get": {
"description": "Get W token total supply.",
"tags": [
"wormholescan"
],
"operationId": "total-supply",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/supply.TotalSupplyResponse"
}
}
}
}
},
"/api/v1/transactions/": {
"get": {
"description": "Returns transactions. Output is paginated.",
@ -3264,6 +3298,9 @@ const docTemplate = `{
"error": {
"type": "string"
},
"last_24_hour_volume": {
"type": "number"
},
"last_day_diff_percentage": {
"type": "string"
},
@ -3784,6 +3821,22 @@ const docTemplate = `{
}
}
},
"supply.CirculatingSupplyResponse": {
"type": "object",
"properties": {
"circulating_supply": {
"type": "string"
}
}
},
"supply.TotalSupplyResponse": {
"type": "object",
"properties": {
"total_supply": {
"type": "string"
}
}
},
"transactions.AssetWithVolume": {
"type": "object",
"properties": {
@ -4140,6 +4193,8 @@ const docTemplate = `{
37,
38,
39,
40,
43,
3104,
4000,
4001,
@ -4195,6 +4250,8 @@ const docTemplate = `{
"ChainIDXLayer",
"ChainIDLinea",
"ChainIDBerachain",
"ChainIDSeiEVM",
"ChainIDSnaxchain",
"ChainIDWormchain",
"ChainIDCosmoshub",
"ChainIDEvmos",

View File

@ -818,7 +818,7 @@
},
"/api/v1/native-token-transfer/top-holder": {
"get": {
"description": "Returns a list of volume of the Native Token Transfer for holder.",
"description": "Returns a list of volume and chain of the Native Token Transfer for top holders.",
"tags": [
"wormholescan"
],
@ -1391,6 +1391,23 @@
}
}
},
"/api/v1/supply": {
"get": {
"description": "Get W token circulation supply.",
"tags": [
"wormholescan"
],
"operationId": "supply",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/supply.CirculatingSupplyResponse"
}
}
}
}
},
"/api/v1/token/:chain_id/:token_address": {
"get": {
"description": "Returns a token symbol, coingecko id and address by chain and token address.",
@ -1550,6 +1567,23 @@
}
}
},
"/api/v1/total-supply": {
"get": {
"description": "Get W token total supply.",
"tags": [
"wormholescan"
],
"operationId": "total-supply",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/supply.TotalSupplyResponse"
}
}
}
}
},
"/api/v1/transactions/": {
"get": {
"description": "Returns transactions. Output is paginated.",
@ -3257,6 +3291,9 @@
"error": {
"type": "string"
},
"last_24_hour_volume": {
"type": "number"
},
"last_day_diff_percentage": {
"type": "string"
},
@ -3777,6 +3814,22 @@
}
}
},
"supply.CirculatingSupplyResponse": {
"type": "object",
"properties": {
"circulating_supply": {
"type": "string"
}
}
},
"supply.TotalSupplyResponse": {
"type": "object",
"properties": {
"total_supply": {
"type": "string"
}
}
},
"transactions.AssetWithVolume": {
"type": "object",
"properties": {
@ -4133,6 +4186,8 @@
37,
38,
39,
40,
43,
3104,
4000,
4001,
@ -4188,6 +4243,8 @@
"ChainIDXLayer",
"ChainIDLinea",
"ChainIDBerachain",
"ChainIDSeiEVM",
"ChainIDSnaxchain",
"ChainIDWormchain",
"ChainIDCosmoshub",
"ChainIDEvmos",

View File

@ -551,6 +551,8 @@ definitions:
properties:
error:
type: string
last_24_hour_volume:
type: number
last_day_diff_percentage:
type: string
last_day_messages:
@ -887,6 +889,16 @@ definitions:
volume:
type: number
type: object
supply.CirculatingSupplyResponse:
properties:
circulating_supply:
type: string
type: object
supply.TotalSupplyResponse:
properties:
total_supply:
type: string
type: object
transactions.AssetWithVolume:
properties:
emitterChain:
@ -1142,6 +1154,8 @@ definitions:
- 37
- 38
- 39
- 40
- 43
- 3104
- 4000
- 4001
@ -1197,6 +1211,8 @@ definitions:
- ChainIDXLayer
- ChainIDLinea
- ChainIDBerachain
- ChainIDSeiEVM
- ChainIDSnaxchain
- ChainIDWormchain
- ChainIDCosmoshub
- ChainIDEvmos
@ -1820,7 +1836,8 @@ paths:
- wormholescan
/api/v1/native-token-transfer/top-holder:
get:
description: Returns a list of volume of the Native Token Transfer for holder.
description: Returns a list of volume and chain of the Native Token Transfer
for top holders.
operationId: /api/v1/native-token-transfer/top-holder
parameters:
- description: Symbol of the token. Currently only supports W.
@ -2210,6 +2227,17 @@ paths:
description: Internal Server Error
tags:
- wormholescan
/api/v1/supply:
get:
description: Get W token circulation supply.
operationId: supply
responses:
"200":
description: OK
schema:
$ref: '#/definitions/supply.CirculatingSupplyResponse'
tags:
- wormholescan
/api/v1/token/:chain_id/:token_address:
get:
description: Returns a token symbol, coingecko id and address by chain and token
@ -2321,6 +2349,17 @@ paths:
description: Internal Server Error
tags:
- wormholescan
/api/v1/total-supply:
get:
description: Get W token total supply.
operationId: total-supply
responses:
"200":
description: OK
schema:
$ref: '#/definitions/supply.TotalSupplyResponse'
tags:
- wormholescan
/api/v1/transactions/:
get:
description: Returns transactions. Output is paginated.

View File

@ -0,0 +1,43 @@
package supply
import (
"context"
"time"
"go.uber.org/zap"
)
type Service struct {
logger *zap.Logger
}
func NewService(logger *zap.Logger) *Service {
return &Service{
logger: logger.With(zap.String("module", "SupplyService")),
}
}
func (s *Service) getCirculatingSupplyForDate(_ context.Context, date time.Time) Supply {
firstUnlock := Supplies[0]
lastUnlock := Supplies[len(Supplies)-1]
daysDifference := int(date.Sub(firstUnlock.Day).Hours() / 24) // Calculate the difference in days
if daysDifference < 0 {
// If the date is before the initial date, return 0
return Supply{}
} else if daysDifference >= len(Supplies) {
// If the date is beyond the last date, return the last unlock
return lastUnlock
}
// Return the unlocked amount for the calculated index
return Supplies[daysDifference]
}
func (s *Service) GetCurrentCirculatingSupply(ctx context.Context) Supply {
return s.getCirculatingSupplyForDate(ctx, time.Now())
}
func (s *Service) GetTotalSupply(_ context.Context) int {
return TotalSupply
}

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/protocols"
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/supply"
frs "github.com/XLabs/fiber-redis-storage"
"github.com/ansrivas/fiberprometheus/v2"
@ -218,6 +219,7 @@ func main() {
statsService := stats.NewService(statsRepo, statsAddressRepo, statsHolderRepo, cache, expirationTime, metrics, rootLogger)
protocolsService := protocols.NewService(cfg.Protocols, protocolsRepo, rootLogger, cache, cfg.Cache.ProtocolsStatsKey, cfg.Cache.ProtocolsStatsExpiration, metrics, tvl)
guardianService := guardianHandlers.NewService(guardianSetRepository, cfg.P2pNetwork, cache, metrics, rootLogger)
supplyService := supply.NewService(rootLogger)
// Set up a custom error handler
response.SetEnableStackTrace(*cfg)
@ -258,7 +260,7 @@ func main() {
notSupportedByEnv := middleware.NotSupportedByTestnetEnv(cfg.P2pNetwork)
// Set up route handlers
app.Get("/swagger.json", GetSwagger)
wormscan.RegisterRoutes(notSupportedByEnv, app, rootLogger, addressService, vaaService, obsService, governorService, infrastructureService, transactionsService, relaysService, operationsService, statsService, protocolsService)
wormscan.RegisterRoutes(notSupportedByEnv, app, rootLogger, addressService, vaaService, obsService, governorService, infrastructureService, transactionsService, relaysService, operationsService, statsService, protocolsService, supplyService)
guardian.RegisterRoutes(cfg, app, rootLogger, vaaService, governorService, heartbeatsService, guardianService)
// Set up gRPC handlers

View File

@ -14,6 +14,7 @@ import (
protocolssvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/protocols"
relayssvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/relays"
statssvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/stats"
supplySvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/supply"
trxsvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/transactions"
vaasvc "github.com/wormhole-foundation/wormhole-explorer/api/handlers/vaa"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/address"
@ -24,6 +25,7 @@ import (
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/protocols"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/relays"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/stats"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/supply"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/transactions"
"github.com/wormhole-foundation/wormhole-explorer/api/routes/wormscan/vaa"
@ -46,6 +48,7 @@ func RegisterRoutes(
operationsService *opsvc.Service,
statsService *statssvc.Service,
protocolsService *protocolssvc.Service,
supplyService *supplySvc.Service,
) {
// Set up controllers
@ -59,6 +62,7 @@ func RegisterRoutes(
opsCtrl := operations.NewController(operationsService, rootLogger)
statsCtrl := stats.NewController(statsService, rootLogger)
contributorsCtrl := protocols.NewController(rootLogger, protocolsService)
supplyCtrl := supply.NewController(supplyService, rootLogger)
// Set up route handlers
api := app.Group("/api/v1")
@ -82,6 +86,10 @@ func RegisterRoutes(
api.Get("/ready", infrastructureCtrl.ReadyCheck)
api.Get("/version", infrastructureCtrl.Version)
// Circulating Supply
api.Get("/supply", supplyCtrl.GetCirculatingSupply)
api.Get("/total-supply", supplyCtrl.GetTotalSupply)
// accounts resource
api.Get("/address/:id", addressCtrl.FindById)

View File

@ -0,0 +1,55 @@
package supply
import (
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/supply"
"go.uber.org/zap"
)
// Controller definition.
type Controller struct {
srv *supply.Service
logger *zap.Logger
}
// NewController create a new controler.
func NewController(serv *supply.Service, logger *zap.Logger) *Controller {
return &Controller{srv: serv, logger: logger.With(zap.String("module", "CirculatingSupplyService"))}
}
type CirculatingSupplyResponse struct {
CirculatingSupply string `json:"circulating_supply"`
}
// GetCirculatingSupply godoc
// @Description Get W token circulation supply.
// @Tags wormholescan
// @ID supply
// @Success 200 {object} CirculatingSupplyResponse
// @Router /api/v1/supply [get]
func (c *Controller) GetCirculatingSupply(ctx *fiber.Ctx) error {
supply := c.srv.GetCurrentCirculatingSupply(ctx.Context())
return ctx.JSON(CirculatingSupplyResponse{
CirculatingSupply: strconv.Itoa(supply.Unlocked),
})
}
type TotalSupplyResponse struct {
TotalSupply string `json:"total_supply"`
}
// GetTotalSupply godoc
// @Description Get W token total supply.
// @Tags wormholescan
// @ID total-supply
// @Success 200 {object} TotalSupplyResponse
// @Router /api/v1/total-supply [get]
func (c *Controller) GetTotalSupply(ctx *fiber.Ctx) error {
supply := c.srv.GetTotalSupply(ctx.Context())
return ctx.JSON(TotalSupplyResponse{
TotalSupply: strconv.Itoa(supply),
})
}