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:
parent
7206d079e3
commit
02e3561226
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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),
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue