103 lines
3.5 KiB
Go
103 lines
3.5 KiB
Go
package transactions
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/wormhole-foundation/wormhole-explorer/api/cacheable"
|
|
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/types"
|
|
"github.com/wormhole-foundation/wormhole-explorer/common/client/cache"
|
|
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
|
|
"github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type Service struct {
|
|
repo *Repository
|
|
cache cache.Cache
|
|
supportedChainIDs map[vaa.ChainID]string
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewService create a new Service.
|
|
func NewService(repo *Repository, cache cache.Cache, logger *zap.Logger) *Service {
|
|
supportedChainIDs := domain.GetSupportedChainIDs()
|
|
return &Service{repo: repo, supportedChainIDs: supportedChainIDs, cache: cache, logger: logger.With(zap.String("module", "TransactionService"))}
|
|
}
|
|
|
|
// GetTransactionCount get the last transactions.
|
|
func (s *Service) GetTransactionCount(ctx context.Context, q *TransactionCountQuery) ([]TransactionCountResult, error) {
|
|
return s.repo.GetTransactionCount(ctx, q)
|
|
}
|
|
|
|
func (s *Service) GetScorecards(ctx context.Context) (*Scorecards, error) {
|
|
return s.repo.GetScorecards(ctx)
|
|
}
|
|
|
|
func (s *Service) GetTopAssets(ctx context.Context, timeSpan *TopStatisticsTimeSpan) ([]AssetDTO, error) {
|
|
return s.repo.GetTopAssets(ctx, timeSpan)
|
|
}
|
|
|
|
func (s *Service) GetTopChainPairs(ctx context.Context, timeSpan *TopStatisticsTimeSpan) ([]ChainPairDTO, error) {
|
|
return s.repo.GetTopChainPairs(ctx, timeSpan)
|
|
}
|
|
|
|
// GetChainActivity get chain activity.
|
|
func (s *Service) GetChainActivity(ctx context.Context, q *ChainActivityQuery) ([]ChainActivityResult, error) {
|
|
key := fmt.Sprintf("wormscan:chain-activity:%s:%v:%s", q.TimeSpan, q.IsNotional, strings.Join(q.GetAppIDs(), ","))
|
|
return cacheable.GetOrLoad(ctx, s.logger, s.cache, 5*time.Minute, key,
|
|
func() ([]ChainActivityResult, error) {
|
|
return s.repo.FindChainActivity(ctx, q)
|
|
})
|
|
}
|
|
|
|
// FindGlobalTransactionByID find a global transaction by id.
|
|
func (s *Service) FindGlobalTransactionByID(ctx context.Context, chainID vaa.ChainID, emitter *types.Address, seq string) (*GlobalTransactionDoc, error) {
|
|
|
|
key := fmt.Sprintf("%d/%s/%s", chainID, emitter.Hex(), seq)
|
|
q := GlobalTransactionQuery{id: key}
|
|
|
|
return s.repo.FindGlobalTransactionByID(ctx, &q)
|
|
}
|
|
|
|
// GetTokenByChainAndAddress get token by chain and address.
|
|
func (s *Service) GetTokenByChainAndAddress(ctx context.Context, chainID vaa.ChainID, tokenAddress *types.Address) (*Token, error) {
|
|
// check if chainID is valid
|
|
if _, ok := s.supportedChainIDs[chainID]; !ok {
|
|
return nil, errs.ErrNotFound
|
|
}
|
|
|
|
//get token by contractID (chainID + tokenAddress)
|
|
tokenMetadata, ok := domain.GetTokenByAddress(chainID, tokenAddress.Hex())
|
|
if !ok {
|
|
return nil, errs.ErrNotFound
|
|
}
|
|
|
|
return &Token{
|
|
Symbol: tokenMetadata.Symbol,
|
|
CoingeckoID: tokenMetadata.CoingeckoID,
|
|
Decimals: tokenMetadata.Decimals,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) ListTransactions(
|
|
ctx context.Context,
|
|
pagination *pagination.Pagination,
|
|
) (*ListTransactonsOutput, error) {
|
|
|
|
return s.repo.ListTransactions(ctx, pagination)
|
|
}
|
|
|
|
func (s *Service) ListTransactionsByAddress(
|
|
ctx context.Context,
|
|
address *types.Address,
|
|
pagination *pagination.Pagination,
|
|
) (*ListTransactonsOutput, error) {
|
|
|
|
return s.repo.ListTransactionsByAddress(ctx, address, pagination)
|
|
}
|