[API] Add appId parameter to GET /api/v1/vaas (#114)

Add the `appId` query parameter to `GET /api/v1/vaas`.
This commit is contained in:
agodnic 2023-02-01 09:59:51 -03:00 committed by GitHub
parent 7a62307899
commit cd976bac96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 326 additions and 72 deletions

View File

@ -943,13 +943,25 @@ const docTemplate = `{
"description": "Transaction hash of the VAA",
"name": "txHash",
"in": "query"
},
{
"type": "boolean",
"description": "include the parsed contents of the VAA, if available",
"name": "parsedPayload",
"in": "query"
},
{
"type": "string",
"description": "filter by application ID",
"name": "appId",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
"$ref": "#/definitions/response.Response-array_vaa_VaaWithPayload"
}
},
"400": {
@ -1141,13 +1153,19 @@ const docTemplate = `{
"name": "hash",
"in": "path",
"required": true
},
{
"type": "boolean",
"description": "include the parsed contents of the VAA, if available",
"name": "parsedPayload",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
"$ref": "#/definitions/response.Response-array_vaa_VaaWithPayload"
}
},
"400": {
@ -1470,6 +1488,20 @@ const docTemplate = `{
}
},
"definitions": {
"github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet": {
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": {
"type": "string"
}
},
"index": {
"type": "integer"
}
}
},
"governor.AvailableNotionalItemResponse": {
"type": "object",
"properties": {
@ -1835,25 +1867,11 @@ const docTemplate = `{
}
}
},
"guardian.GuardianSet": {
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": {
"type": "string"
}
},
"index": {
"type": "integer"
}
}
},
"guardian.GuardianSetResponse": {
"type": "object",
"properties": {
"guardianSet": {
"$ref": "#/definitions/guardian.GuardianSet"
"$ref": "#/definitions/github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet"
}
}
},
@ -2121,6 +2139,20 @@ const docTemplate = `{
}
}
},
"response.Response-array_vaa_VaaWithPayload": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/vaa.VaaWithPayload"
}
},
"pagination": {
"$ref": "#/definitions/response.ResponsePagination"
}
}
},
"response.Response-governor_GovConfig": {
"type": "object",
"properties": {
@ -2273,6 +2305,48 @@ const docTemplate = `{
"type": "integer"
}
}
},
"vaa.VaaWithPayload": {
"type": "object",
"properties": {
"appId": {
"type": "string"
},
"emitterAddr": {
"type": "string"
},
"emitterChain": {
"$ref": "#/definitions/vaa.ChainID"
},
"guardianSetIndex": {
"type": "integer"
},
"id": {
"type": "string"
},
"indexedAt": {
"type": "string"
},
"payload": {
"type": "object",
"additionalProperties": true
},
"timestamp": {
"type": "string"
},
"updatedAt": {
"type": "string"
},
"vaa": {
"type": "array",
"items": {
"type": "integer"
}
},
"version": {
"type": "integer"
}
}
}
}
}`

View File

@ -936,13 +936,25 @@
"description": "Transaction hash of the VAA",
"name": "txHash",
"in": "query"
},
{
"type": "boolean",
"description": "include the parsed contents of the VAA, if available",
"name": "parsedPayload",
"in": "query"
},
{
"type": "string",
"description": "filter by application ID",
"name": "appId",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
"$ref": "#/definitions/response.Response-array_vaa_VaaWithPayload"
}
},
"400": {
@ -1134,13 +1146,19 @@
"name": "hash",
"in": "path",
"required": true
},
{
"type": "boolean",
"description": "include the parsed contents of the VAA, if available",
"name": "parsedPayload",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/response.Response-array_vaa_VaaDoc"
"$ref": "#/definitions/response.Response-array_vaa_VaaWithPayload"
}
},
"400": {
@ -1463,6 +1481,20 @@
}
},
"definitions": {
"github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet": {
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": {
"type": "string"
}
},
"index": {
"type": "integer"
}
}
},
"governor.AvailableNotionalItemResponse": {
"type": "object",
"properties": {
@ -1828,25 +1860,11 @@
}
}
},
"guardian.GuardianSet": {
"type": "object",
"properties": {
"addresses": {
"type": "array",
"items": {
"type": "string"
}
},
"index": {
"type": "integer"
}
}
},
"guardian.GuardianSetResponse": {
"type": "object",
"properties": {
"guardianSet": {
"$ref": "#/definitions/guardian.GuardianSet"
"$ref": "#/definitions/github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet"
}
}
},
@ -2114,6 +2132,20 @@
}
}
},
"response.Response-array_vaa_VaaWithPayload": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/vaa.VaaWithPayload"
}
},
"pagination": {
"$ref": "#/definitions/response.ResponsePagination"
}
}
},
"response.Response-governor_GovConfig": {
"type": "object",
"properties": {
@ -2266,6 +2298,48 @@
"type": "integer"
}
}
},
"vaa.VaaWithPayload": {
"type": "object",
"properties": {
"appId": {
"type": "string"
},
"emitterAddr": {
"type": "string"
},
"emitterChain": {
"$ref": "#/definitions/vaa.ChainID"
},
"guardianSetIndex": {
"type": "integer"
},
"id": {
"type": "string"
},
"indexedAt": {
"type": "string"
},
"payload": {
"type": "object",
"additionalProperties": true
},
"timestamp": {
"type": "string"
},
"updatedAt": {
"type": "string"
},
"vaa": {
"type": "array",
"items": {
"type": "integer"
}
},
"version": {
"type": "integer"
}
}
}
}
}

View File

@ -1,5 +1,14 @@
basePath: /v1
definitions:
github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet:
properties:
addresses:
items:
type: string
type: array
index:
type: integer
type: object
governor.AvailableNotionalItemResponse:
properties:
bigTransactionSize:
@ -237,19 +246,10 @@ definitions:
price:
type: number
type: object
guardian.GuardianSet:
properties:
addresses:
items:
type: string
type: array
index:
type: integer
type: object
guardian.GuardianSetResponse:
properties:
guardianSet:
$ref: '#/definitions/guardian.GuardianSet'
$ref: '#/definitions/github_com_wormhole-foundation_wormhole-explorer_api_routes_guardian_guardian.GuardianSet'
type: object
heartbeats.HeartbeatNetworkResponse:
properties:
@ -422,6 +422,15 @@ definitions:
pagination:
$ref: '#/definitions/response.ResponsePagination'
type: object
response.Response-array_vaa_VaaWithPayload:
properties:
data:
items:
$ref: '#/definitions/vaa.VaaWithPayload'
type: array
pagination:
$ref: '#/definitions/response.ResponsePagination'
type: object
response.Response-governor_GovConfig:
properties:
data:
@ -540,6 +549,34 @@ definitions:
count:
type: integer
type: object
vaa.VaaWithPayload:
properties:
appId:
type: string
emitterAddr:
type: string
emitterChain:
$ref: '#/definitions/vaa.ChainID'
guardianSetIndex:
type: integer
id:
type: string
indexedAt:
type: string
payload:
additionalProperties: true
type: object
timestamp:
type: string
updatedAt:
type: string
vaa:
items:
type: integer
type: array
version:
type: integer
type: object
info:
contact:
email: info@wormhole.com
@ -1159,11 +1196,19 @@ paths:
in: query
name: txHash
type: string
- description: include the parsed contents of the VAA, if available
in: query
name: parsedPayload
type: boolean
- description: filter by application ID
in: query
name: appId
type: string
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response-array_vaa_VaaDoc'
$ref: '#/definitions/response.Response-array_vaa_VaaWithPayload'
"400":
description: Bad Request
"500":
@ -1277,11 +1322,15 @@ paths:
name: hash
required: true
type: string
- description: include the parsed contents of the VAA, if available
in: query
name: parsedPayload
type: boolean
responses:
"200":
description: OK
schema:
$ref: '#/definitions/response.Response-array_vaa_VaaDoc'
$ref: '#/definitions/response.Response-array_vaa_VaaWithPayload'
"400":
description: Bad Request
"500":

View File

@ -63,5 +63,6 @@ type VaaWithPayload struct {
Timestamp *time.Time `bson:"timestamp" json:"timestamp"`
UpdatedAt *time.Time `bson:"updatedAt" json:"updatedAt"`
IndexedAt *time.Time `bson:"indexedAt" json:"indexedAt"`
AppId string `bson:"appId" json:"appId,omitempty"`
Payload map[string]interface{} `bson:"payload" json:"payload,omitempty"`
}

View File

@ -137,12 +137,18 @@ func (r *Repository) FindVaasWithPayload(
// add parsed payload fields
pipeline = append(pipeline, bson.D{
{"$addFields", bson.D{
{"payload", bson.M{
"$arrayElemAt": []interface{}{"$payload.result", 0},
}},
{"payload", bson.M{"$arrayElemAt": []interface{}{"$payload.result", 0}}},
{"appId", bson.M{"$arrayElemAt": []interface{}{"$payload.appId", 0}}},
}},
})
// filter by appId
if q.appId != "" {
pipeline = append(pipeline, bson.D{
{"$match", bson.D{bson.E{"appId", q.appId}}},
})
}
// limit size of results
pipeline = append(pipeline, bson.D{
{"$limit", q.Pagination.PageSize},
@ -214,6 +220,7 @@ type VaaQuery struct {
emitter string
sequence string
txHash string
appId string
}
// Query create a new VaaQuery with default pagination vaues.
@ -252,6 +259,11 @@ func (q *VaaQuery) SetTxHash(txHash string) *VaaQuery {
return q
}
func (q *VaaQuery) SetAppId(appId string) *VaaQuery {
q.appId = appId
return q
}
func (q *VaaQuery) toBSON() *bson.D {
r := bson.D{}
if q.chainId > 0 {

View File

@ -21,29 +21,40 @@ type Service struct {
logger *zap.Logger
}
// NewService create a new Service.
// NewService creates a new VAA Service.
func NewService(r *Repository, getCacheFunc cache.CacheGetFunc, logger *zap.Logger) *Service {
return &Service{repo: r, getCacheFunc: getCacheFunc, logger: logger.With(zap.String("module", "VaaService"))}
}
// FindAll get all the the vaa.
// FindAllParams passes input data to the function `FindAll`.
type FindAllParams struct {
Pagination *pagination.Pagination
TxHash *vaa.Address
IncludeParsedPayload bool
AppId string
}
// FindAll returns all VAAs.
func (s *Service) FindAll(
ctx context.Context,
p *pagination.Pagination,
txHash *vaa.Address,
includeParsedPayload bool,
params *FindAllParams,
) (*response.Response[[]*VaaWithPayload], error) {
if p == nil {
p = pagination.FirstPage()
query := Query()
if params.Pagination != nil {
query.SetPagination(params.Pagination)
}
query := Query().SetPagination(p)
if txHash != nil {
query = query.SetTxHash(txHash.String())
if params.TxHash != nil {
query.SetTxHash(params.TxHash.String())
}
if includeParsedPayload {
if params.AppId != "" {
query.SetAppId(params.AppId)
}
if params.IncludeParsedPayload {
vaas, err := s.repo.FindVaasWithPayload(ctx, query)
if err != nil {
return nil, err
@ -102,7 +113,7 @@ func (s *Service) FindById(
chain vaa.ChainID,
emitter vaa.Address,
seq string,
payload bool,
includeParsedPayload bool,
) (*response.Response[*VaaWithPayload], error) {
// check vaa sequence indexed
@ -111,7 +122,7 @@ func (s *Service) FindById(
return nil, errs.ErrNotFound
}
if payload {
if includeParsedPayload {
vaaWithPayload, err := s.findByIdWithPayload(ctx, chain, emitter, seq)
resp := response.Response[*VaaWithPayload]{Data: vaaWithPayload}
return &resp, err

View File

@ -138,3 +138,7 @@ func ExtractParsedPayload(c *fiber.Ctx, l *zap.Logger) (bool, error) {
}
return parsedPayload, nil
}
func ExtractAppId(c *fiber.Ctx, l *zap.Logger) string {
return c.Query("appId")
}

View File

@ -34,6 +34,7 @@ func NewController(serv *vaa.Service, logger *zap.Logger) *Controller {
// @Failure 500
// @Router /v1/signed_vaa/{chain_id}/{emitter}/{seq} [get]
func (c *Controller) FindSignedVAAByID(ctx *fiber.Ctx) error {
chainID, emitter, seq, err := middleware.ExtractVAAParams(ctx, c.logger)
if err != nil {
return err
@ -45,7 +46,14 @@ func (c *Controller) FindSignedVAAByID(ctx *fiber.Ctx) error {
// return response.NewApiError(ctx, fiber.StatusBadRequest, response.InvalidParam,
// "not supported for PythNet", nil)
//}
vaa, err := c.srv.FindById(ctx.Context(), chainID, *emitter, strconv.FormatUint(seq, 10), false)
vaa, err := c.srv.FindById(
ctx.Context(),
chainID,
*emitter,
strconv.FormatUint(seq, 10),
false, /*includeParsedPayload*/
)
if err != nil {
return err
}

View File

@ -7,6 +7,7 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/wormhole-foundation/wormhole-explorer/api/handlers/vaa"
"github.com/wormhole-foundation/wormhole-explorer/api/middleware"
_ "github.com/wormhole-foundation/wormhole-explorer/api/response" // required by swaggo
"go.uber.org/zap"
)
@ -29,13 +30,15 @@ func NewController(serv *vaa.Service, logger *zap.Logger) *Controller {
// @Param pageSize query integer false "Number of elements per page."
// @Param sortOrder query string false "Sort results in ascending or descending order." Enums(ASC, DESC)
// @Param txHash query string false "Transaction hash of the VAA"
// @Success 200 {object} response.Response[[]VaaDoc]
// @Param parsedPayload query bool false "include the parsed contents of the VAA, if available"
// @Param appId query string false "filter by application ID"
// @Success 200 {object} response.Response[[]vaa.VaaWithPayload]
// @Failure 400
// @Failure 500
// @Router /api/v1/vaas/ [get]
func (c *Controller) FindAll(ctx *fiber.Ctx) error {
p := middleware.GetPaginationFromContext(ctx)
pagination := middleware.GetPaginationFromContext(ctx)
txHash, err := middleware.GetTxHash(ctx, c.logger)
if err != nil {
@ -47,7 +50,18 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
return err
}
vaas, err := c.srv.FindAll(ctx.Context(), p, txHash, includeParsedPayload)
appId := middleware.ExtractAppId(ctx, c.logger)
if appId != "" {
includeParsedPayload = true
}
p := vaa.FindAllParams{
Pagination: pagination,
TxHash: txHash,
IncludeParsedPayload: includeParsedPayload,
AppId: appId,
}
vaas, err := c.srv.FindAll(ctx.Context(), &p)
if err != nil {
return err
}
@ -62,7 +76,7 @@ func (c *Controller) FindAll(ctx *fiber.Ctx) error {
// @Param page query integer false "Page number."
// @Param pageSize query integer false "Number of elements per page."
// @Param sortOrder query string false "Sort results in ascending or descending order." Enums(ASC, DESC)
// @Success 200 {object} response.Response[[]VaaDoc]
// @Success 200 {object} response.Response[[]vaa.VaaDoc]
// @Failure 400
// @Failure 500
// @Router /api/v1/vaas/{chain_id} [get]
@ -88,7 +102,7 @@ func (c *Controller) FindByChain(ctx *fiber.Ctx) error {
// @Param page query integer false "Page number."
// @Param pageSize query integer false "Number of elements per page."
// @Param sortOrder query string false "Sort results in ascending or descending order." Enums(ASC, DESC)
// @Success 200 {object} response.Response[[]VaaDoc]
// @Success 200 {object} response.Response[[]vaa.VaaDoc]
// @Failure 400
// @Failure 500
// @Router /api/v1/vaas/{chain_id}/{emitter} [get]
@ -114,7 +128,8 @@ func (c *Controller) FindByEmitter(ctx *fiber.Ctx) error {
// @Param seq path integer true "sequence of the VAA"
// @Param signer path string true "Signer address"
// @Param hash path string true "VAA hash"
// @Success 200 {object} response.Response[[]VaaDoc]
// @Param parsedPayload query bool false "include the parsed contents of the VAA, if available"
// @Success 200 {object} response.Response[[]vaa.VaaWithPayload]
// @Failure 400
// @Failure 500
// @Router /api/v1/vaas/{chain_id}/{emitter}/{seq}/{signer}/{hash} [get]
@ -147,7 +162,7 @@ func (c *Controller) FindById(ctx *fiber.Ctx) error {
// @Description Returns the total number of VAAs emitted for each blockchain.
// @Tags Wormscan
// @ID get-vaa-counts
// @Success 200 {object} response.Response[[]VaaStats]
// @Success 200 {object} response.Response[[]vaa.VaaStats]
// @Failure 400
// @Failure 500
// @Router /api/v1/vaas/vaa-counts [get]

View File

@ -62,8 +62,14 @@ func (h *Handler) GetSignedVAA(ctx context.Context, request *publicrpcv1.GetSign
sequence := strconv.FormatUint(request.MessageId.Sequence, 10)
// get vaa by Id.
vaa, err := h.vaaSrv.FindById(ctx, chainID, addr, sequence, false)
// get VAA by Id.
vaa, err := h.vaaSrv.FindById(
ctx,
chainID,
addr,
sequence,
false, /*includeParsedPayload*/
)
if err != nil {
if errors.Is(err, errs.ErrNotFound) {
return nil, status.Error(codes.NotFound, "requested VAA not found in store")