wormhole-explorer/api/handlers/governor/service.go

211 lines
7.7 KiB
Go

// Package governor handle the request of governor data from governor endpoint defined in the api.
package governor
import (
"context"
"fmt"
errs "github.com/wormhole-foundation/wormhole-explorer/api/internal/errors"
"github.com/wormhole-foundation/wormhole-explorer/api/internal/pagination"
"github.com/wormhole-foundation/wormhole-explorer/api/response"
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
"github.com/wormhole-foundation/wormhole-explorer/common/types"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
"go.uber.org/zap"
)
type Service struct {
repo *Repository
supportedChainIDs map[vaa.ChainID]string
logger *zap.Logger
}
// NewService create a new governor.Service.
func NewService(dao *Repository, logger *zap.Logger) *Service {
supportedChainIDs := domain.GetSupportedChainIDs()
return &Service{repo: dao, supportedChainIDs: supportedChainIDs, logger: logger.With(zap.String("module", "GovernorService"))}
}
// FindGovernorConfig get a list of governor configurations.
func (s *Service) FindGovernorConfig(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovConfig], error) {
if p == nil {
p = pagination.Default()
}
query := NewGovernorQuery().SetPagination(p)
govConfigs, err := s.repo.FindGovConfigurations(ctx, query)
res := response.Response[[]*GovConfig]{Data: govConfigs}
return &res, err
}
// FindGovernorConfigByGuardianAddress get a governor configuration by guardianAddress.
func (s *Service) FindGovernorConfigByGuardianAddress(
ctx context.Context,
guardianAddress *types.Address,
) ([]*GovConfig, error) {
p := pagination.
Default().
SetLimit(1)
query := NewGovernorQuery().
SetID(guardianAddress).
SetPagination(p)
govConfigs, err := s.repo.FindGovConfigurations(ctx, query)
return govConfigs, err
}
// FindGovernorStatus get a list of governor status.
func (s *Service) FindGovernorStatus(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovStatus], error) {
if p == nil {
p = pagination.Default()
}
query := NewGovernorQuery().SetPagination(p)
govStatus, err := s.repo.FindGovernorStatus(ctx, query)
res := response.Response[[]*GovStatus]{Data: govStatus}
return &res, err
}
// FindGovernorStatusByGuardianAddress get a governor status by guardianAddress.
func (s *Service) FindGovernorStatusByGuardianAddress(
ctx context.Context,
guardianAddress *types.Address,
p *pagination.Pagination,
) (*response.Response[*GovStatus], error) {
query := NewGovernorQuery().
SetID(guardianAddress).
SetPagination(p)
govStatus, err := s.repo.FindOneGovernorStatus(ctx, query)
res := response.Response[*GovStatus]{Data: govStatus}
return &res, err
}
// FindNotionalLimit get a notional limit for each chainID.
func (s *Service) FindNotionalLimit(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*NotionalLimit], error) {
if p == nil {
p = pagination.Default()
}
query := QueryNotionalLimit().SetPagination(p)
notionalLimit, err := s.repo.FindNotionalLimit(ctx, query)
res := response.Response[[]*NotionalLimit]{Data: notionalLimit}
return &res, err
}
// GetNotionalLimitByChainID get a notional limit by chainID.
func (s *Service) GetNotionalLimitByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*NotionalLimitDetail], error) {
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
notionalLimit, err := s.repo.GetNotionalLimitByChainID(ctx, query)
res := response.Response[[]*NotionalLimitDetail]{Data: notionalLimit}
return &res, err
}
// GetAvailableNotional get a available notional for each chainID.
func (s *Service) GetAvailableNotional(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*NotionalAvailable], error) {
if p == nil {
p = pagination.Default()
}
query := QueryNotionalLimit().SetPagination(p)
notionalAvailability, err := s.repo.GetAvailableNotional(ctx, query)
res := response.Response[[]*NotionalAvailable]{Data: notionalAvailability}
return &res, err
}
// GetAvailableNotionalByChainID get a available notional by chainID.
func (s *Service) GetAvailableNotionalByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*NotionalAvailableDetail], error) {
// check if chainID is valid
if _, ok := s.supportedChainIDs[chainID]; !ok {
return nil, errs.ErrNotFound
}
query := QueryNotionalLimit().SetPagination(p).SetChain(chainID)
notionaLAvailability, err := s.repo.GetAvailableNotionalByChainID(ctx, query)
res := response.Response[[]*NotionalAvailableDetail]{Data: notionaLAvailability}
return &res, err
}
// GetMaxNotionalAvailableByChainID get a maximun notional value by chainID.
func (s *Service) GetMaxNotionalAvailableByChainID(ctx context.Context, chainID vaa.ChainID) (*response.Response[*MaxNotionalAvailableRecord], error) {
// check if chainID is valid
if _, ok := s.supportedChainIDs[chainID]; !ok {
return nil, errs.ErrNotFound
}
query := QueryNotionalLimit().SetChain(chainID)
maxNotionaLAvailable, err := s.repo.GetMaxNotionalAvailableByChainID(ctx, query)
res := response.Response[*MaxNotionalAvailableRecord]{Data: maxNotionaLAvailable}
return &res, err
}
// GetEnqueueVaas get all the enqueued vaa.
func (s *Service) GetEnqueueVass(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*EnqueuedVaas], error) {
if p == nil {
p = pagination.Default()
}
query := QueryEnqueuedVaa().SetPagination(p)
enqueuedVaaResponse, err := s.repo.GetEnqueueVass(ctx, query)
res := response.Response[[]*EnqueuedVaas]{Data: enqueuedVaaResponse}
return &res, err
}
// GetEnqueueVassByChainID get enequeued vaa by chainID.
func (s *Service) GetEnqueueVassByChainID(ctx context.Context, p *pagination.Pagination, chainID vaa.ChainID) (*response.Response[[]*EnqueuedVaaDetail], error) {
if p == nil {
p = pagination.Default()
}
query := QueryEnqueuedVaa().SetPagination(p).SetChain(chainID)
enqueuedVaaRecord, err := s.repo.GetEnqueueVassByChainID(ctx, query)
res := response.Response[[]*EnqueuedVaaDetail]{Data: enqueuedVaaRecord}
return &res, err
}
// GetGovernorLimit get governor limit.
func (s *Service) GetGovernorLimit(ctx context.Context, p *pagination.Pagination) (*response.Response[[]*GovernorLimit], error) {
if p == nil {
p = pagination.Default()
}
query := NewGovernorQuery().SetPagination(p)
governorLimit, err := s.repo.GetGovernorLimit(ctx, query)
res := response.Response[[]*GovernorLimit]{Data: governorLimit}
return &res, err
}
// GetAvailNotionByChain get governor limit for each chainID.
// Guardian api migration.
func (s *Service) GetAvailNotionByChain(ctx context.Context) ([]*AvailableNotionalByChain, error) {
return s.repo.GetAvailNotionByChain(ctx)
}
// Get governor token list.
// Guardian api migration.
func (s *Service) GetTokenList(ctx context.Context) ([]*TokenList, error) {
return s.repo.GetTokenList(ctx)
}
// GetEnqueuedVaas get enqueued vaas.
// Guardian api migration.
func (s *Service) GetEnqueuedVaas(ctx context.Context) ([]*EnqueuedVaaItem, error) {
entries, err := s.repo.GetEnqueuedVaas(ctx)
if err != nil {
return nil, err
}
result := make([]*EnqueuedVaaItem, 0)
existingEnqueuedVaa := map[string]bool{}
for _, e := range entries {
// remove duplicates
key := fmt.Sprintf("%s/%s/%s", e.EmitterChain, e.EmitterAddress, e.Sequence)
if _, exists := existingEnqueuedVaa[key]; !exists {
result = append(result, e)
existingEnqueuedVaa[key] = true
}
}
return result, nil
}
// IsVaaEnqueued check vaa is enqueued.
// Guardian api migration.
func (s *Service) IsVaaEnqueued(ctx context.Context, chainID vaa.ChainID, emitter *types.Address, seq string) (bool, error) {
isEnqueued, err := s.repo.IsVaaEnqueued(ctx, chainID, emitter, seq)
return isEnqueued, err
}