mirror of
https://github.com/luxfi/indexer.git
synced 2026-09-24 00:25:37 +00:00
531 lines
17 KiB
Go
531 lines
17 KiB
Go
// Package defi indexes DeFi protocols on the Lux EVM.
|
|
//
|
|
// This package indexes all major DeFi protocols native to the Lux ecosystem:
|
|
// - AMM V2/V3 (Uniswap-style constant product and concentrated liquidity)
|
|
// - LSSVM (Sudoswap-style NFT AMM)
|
|
// - Perpetuals (GMX-style perpetual futures)
|
|
// - Synthetics (Alchemix-style self-repaying loans)
|
|
// - Staking (with cooldown periods and receipt tokens)
|
|
// - Bridge/Cross-chain (Warp, Teleporter, Token Bridge)
|
|
// - Order Book (CLOB with margin, lending, positions)
|
|
// - Market History (OHLCV candles, tickers, volume stats)
|
|
package defi
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"math/big"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// Note: LogEntry is defined in amm.go as the canonical definition
|
|
|
|
// DeFiIndexer is the unified indexer for all DeFi protocols
|
|
type DeFiIndexer struct {
|
|
mu sync.RWMutex
|
|
chainID ChainID
|
|
amm *AMMIndexer
|
|
lssvm *LSSVMIndexer
|
|
perps *PerpsIndexer
|
|
synths *SynthsIndexer
|
|
staking *StakingIndexer
|
|
bridge *BridgeIndexer
|
|
orderbook *OrderBookIndexer
|
|
marketHistory *MarketHistoryIndexer
|
|
nftMarketplace *NFTMarketplaceIndexer
|
|
|
|
// Event routing
|
|
eventHandlers map[string]func(*LogEntry) error
|
|
|
|
// Stats
|
|
stats *DeFiStats
|
|
}
|
|
|
|
// DeFiStats tracks indexer statistics
|
|
type DeFiStats struct {
|
|
EventsProcessed uint64 `json:"eventsProcessed"`
|
|
EventsByType map[string]uint64 `json:"eventsByType"`
|
|
LastBlockIndexed uint64 `json:"lastBlockIndexed"`
|
|
LastIndexTime time.Time `json:"lastIndexTime"`
|
|
ErrorCount uint64 `json:"errorCount"`
|
|
StartTime time.Time `json:"startTime"`
|
|
}
|
|
|
|
// NewDeFiIndexer creates a new unified DeFi indexer
|
|
func NewDeFiIndexer(chainID ChainID) *DeFiIndexer {
|
|
idx := &DeFiIndexer{
|
|
chainID: chainID,
|
|
amm: NewAMMIndexer(),
|
|
lssvm: NewLSSVMIndexer(),
|
|
perps: NewPerpsIndexer(),
|
|
synths: NewSynthsIndexer(),
|
|
staking: NewStakingIndexer(),
|
|
bridge: NewBridgeIndexer(chainID),
|
|
orderbook: NewOrderBookIndexer(),
|
|
marketHistory: NewMarketHistoryIndexer(),
|
|
nftMarketplace: NewNFTMarketplaceIndexer(),
|
|
eventHandlers: make(map[string]func(*LogEntry) error),
|
|
stats: &DeFiStats{
|
|
EventsByType: make(map[string]uint64),
|
|
StartTime: time.Now(),
|
|
},
|
|
}
|
|
|
|
// Register all event handlers
|
|
idx.registerEventHandlers()
|
|
|
|
return idx
|
|
}
|
|
|
|
// ammIndexLogWrapper wraps AMM's context-aware IndexLog to unified interface
|
|
func (d *DeFiIndexer) ammIndexLogWrapper(log *LogEntry) error {
|
|
return d.amm.IndexLog(context.Background(), log)
|
|
}
|
|
|
|
// registerEventHandlers sets up routing for all event signatures
|
|
func (d *DeFiIndexer) registerEventHandlers() {
|
|
// AMM V2 events
|
|
d.eventHandlers[AMMV2SwapSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV2MintSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV2BurnSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV2SyncSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV2PairCreatedSig] = d.ammIndexLogWrapper
|
|
|
|
// AMM V3 events
|
|
d.eventHandlers[AMMV3SwapSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV3MintSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV3BurnSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV3CollectSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV3FlashSig] = d.ammIndexLogWrapper
|
|
d.eventHandlers[AMMV3PoolCreatedSig] = d.ammIndexLogWrapper
|
|
|
|
// LSSVM events
|
|
d.eventHandlers[LSSVMSwapNFTInSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMSwapNFTOutSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMSpotPriceUpdateSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMDeltaUpdateSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMFeeUpdateSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMPairCreatedSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMTokenDepositSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMTokenWithdrawSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMNFTDepositSig] = d.lssvm.IndexLog
|
|
d.eventHandlers[LSSVMNFTWithdrawSig] = d.lssvm.IndexLog
|
|
|
|
// Perps events
|
|
d.eventHandlers[PerpsIncreasePositionSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsDecreasePositionSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsLiquidatePositionSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsClosePositionSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsCollectMarginFeesSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsUpdateFundingRateSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsSwapSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsCreateOrderSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsCancelOrderSig] = d.perps.IndexLog
|
|
d.eventHandlers[PerpsExecuteOrderSig] = d.perps.IndexLog
|
|
|
|
// Synths events
|
|
d.eventHandlers[SynthsDepositSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsWithdrawSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsMintSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsBurnSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsLiquidateSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsRepayDebtSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsHarvestSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsTransmuteSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsClaimSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsExchangeSig] = d.synths.IndexLog
|
|
d.eventHandlers[SynthsYieldUpdateSig] = d.synths.IndexLog
|
|
|
|
// Staking events
|
|
d.eventHandlers[StakingStakedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingUnstakedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingClaimedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingCooldownStartedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingCooldownCancelledSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingSlashedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingRewardsDistributedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingPoolCreatedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingDelegatedSig] = d.staking.IndexLog
|
|
d.eventHandlers[StakingUndelegatedSig] = d.staking.IndexLog
|
|
|
|
// Bridge events
|
|
d.eventHandlers[WarpMessageSentSig] = d.bridge.IndexLog
|
|
d.eventHandlers[WarpMessageReceivedSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TokenBridgeDepositSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TokenBridgeWithdrawSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TokenBridgeMintSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TokenBridgeBurnSig] = d.bridge.IndexLog
|
|
d.eventHandlers[NativeBridgeLockSig] = d.bridge.IndexLog
|
|
d.eventHandlers[NativeBridgeUnlockSig] = d.bridge.IndexLog
|
|
d.eventHandlers[CrossChainSwapInitSig] = d.bridge.IndexLog
|
|
d.eventHandlers[CrossChainSwapCompleteSig] = d.bridge.IndexLog
|
|
d.eventHandlers[CrossChainSwapRefundSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TeleporterSendSig] = d.bridge.IndexLog
|
|
d.eventHandlers[TeleporterReceiveSig] = d.bridge.IndexLog
|
|
|
|
// Order book events
|
|
d.eventHandlers[OrderPlacedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[OrderCancelledSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[OrderFilledSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[OrderPartialSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[TradeSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[TradeSettledSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[PositionOpenedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[PositionClosedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[PositionModifiedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[PositionLiquidatedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[MarginDepositedSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[MarginWithdrawnSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[MarginCallSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[LendingDepositSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[LendingWithdrawSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[LendingBorrowSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[LendingRepaySig] = d.orderbook.IndexLog
|
|
d.eventHandlers[FundingRateSig] = d.orderbook.IndexLog
|
|
d.eventHandlers[FundingPaymentSig] = d.orderbook.IndexLog
|
|
|
|
// NFT Marketplace events (OpenSea Seaport, LooksRare, Blur, Rarible, X2Y2, Zora)
|
|
d.eventHandlers[SeaportOrderFulfilledSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[SeaportOrderCancelledSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[SeaportCounterIncrementSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[LooksRareTakerBidSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[LooksRareTakerAskSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[LooksRareCancelAllSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[LooksRareV2TakerBidSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[LooksRareV2TakerAskSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[BlurOrdersMatchedSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[BlurOrderCancelledSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[BlurNonceIncrementedSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[RaribleMatchSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[RaribleCancelSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[X2Y2InventorySig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[X2Y2CancelSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[ZoraAskFilledSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[ZoraAskCreatedSig] = d.nftMarketplace.IndexLog
|
|
d.eventHandlers[ZoraAskCancelledSig] = d.nftMarketplace.IndexLog
|
|
}
|
|
|
|
// IndexLog processes a single log entry
|
|
func (d *DeFiIndexer) IndexLog(log *LogEntry) error {
|
|
if len(log.Topics) == 0 {
|
|
return nil
|
|
}
|
|
|
|
topic0 := log.Topics[0]
|
|
|
|
d.mu.Lock()
|
|
d.stats.EventsProcessed++
|
|
d.stats.EventsByType[topic0]++
|
|
d.stats.LastBlockIndexed = log.BlockNumber
|
|
d.stats.LastIndexTime = time.Now()
|
|
d.mu.Unlock()
|
|
|
|
// Route to appropriate handler
|
|
if handler, ok := d.eventHandlers[topic0]; ok {
|
|
if err := handler(log); err != nil {
|
|
d.mu.Lock()
|
|
d.stats.ErrorCount++
|
|
d.mu.Unlock()
|
|
return fmt.Errorf("handler error for %s: %w", topic0, err)
|
|
}
|
|
}
|
|
|
|
// Also record to market history if it's a trade event
|
|
if d.isTradeEvent(topic0) {
|
|
d.recordTradeHistory(log)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// IndexLogs processes multiple log entries
|
|
func (d *DeFiIndexer) IndexLogs(logs []*LogEntry) error {
|
|
for _, log := range logs {
|
|
if err := d.IndexLog(log); err != nil {
|
|
// Log error but continue processing
|
|
continue
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// isTradeEvent checks if an event represents a trade
|
|
func (d *DeFiIndexer) isTradeEvent(topic0 string) bool {
|
|
tradeEvents := map[string]bool{
|
|
AMMV2SwapSig: true,
|
|
AMMV3SwapSig: true,
|
|
LSSVMSwapNFTInSig: true,
|
|
LSSVMSwapNFTOutSig: true,
|
|
TradeSig: true,
|
|
}
|
|
return tradeEvents[topic0]
|
|
}
|
|
|
|
// recordTradeHistory records trade to market history
|
|
func (d *DeFiIndexer) recordTradeHistory(log *LogEntry) {
|
|
// Extract trade data based on event type
|
|
topic0 := log.Topics[0]
|
|
|
|
var trade *TradeHistory
|
|
|
|
switch topic0 {
|
|
case AMMV2SwapSig:
|
|
trade = d.extractAMMV2Trade(log)
|
|
case AMMV3SwapSig:
|
|
trade = d.extractAMMV3Trade(log)
|
|
case TradeSig:
|
|
trade = d.extractOrderBookTrade(log)
|
|
}
|
|
|
|
if trade != nil {
|
|
d.marketHistory.RecordTrade(trade)
|
|
}
|
|
}
|
|
|
|
// extractAMMV2Trade extracts trade from AMM V2 swap
|
|
func (d *DeFiIndexer) extractAMMV2Trade(log *LogEntry) *TradeHistory {
|
|
if len(log.Topics) < 3 || len(log.Data) < 256 {
|
|
return nil
|
|
}
|
|
|
|
// Data: amount0In, amount1In, amount0Out, amount1Out
|
|
amount0In := new(big.Int).SetBytes(hexToBytes(log.Data[0:64]))
|
|
amount1In := new(big.Int).SetBytes(hexToBytes(log.Data[64:128]))
|
|
amount0Out := new(big.Int).SetBytes(hexToBytes(log.Data[128:192]))
|
|
amount1Out := new(big.Int).SetBytes(hexToBytes(log.Data[192:256]))
|
|
|
|
var size, quoteSize *big.Int
|
|
var side OrderSide
|
|
|
|
if amount0In.Sign() > 0 {
|
|
side = OrderSideSell
|
|
size = amount0In
|
|
quoteSize = amount1Out
|
|
} else {
|
|
side = OrderSideBuy
|
|
size = amount0Out
|
|
quoteSize = amount1In
|
|
}
|
|
|
|
price := big.NewInt(0)
|
|
if size.Sign() > 0 {
|
|
price = new(big.Int).Mul(quoteSize, big.NewInt(1e18))
|
|
price.Div(price, size)
|
|
}
|
|
|
|
return &TradeHistory{
|
|
ID: fmt.Sprintf("%s-%d", log.TxHash, log.LogIndex),
|
|
Market: log.Address,
|
|
Price: price,
|
|
Size: size,
|
|
QuoteSize: quoteSize,
|
|
Side: side,
|
|
Timestamp: log.Timestamp,
|
|
TxHash: log.TxHash,
|
|
BlockNumber: log.BlockNumber,
|
|
Taker: "0x" + log.Topics[2][26:],
|
|
}
|
|
}
|
|
|
|
// extractAMMV3Trade extracts trade from AMM V3 swap
|
|
func (d *DeFiIndexer) extractAMMV3Trade(log *LogEntry) *TradeHistory {
|
|
if len(log.Topics) < 3 || len(log.Data) < 256 {
|
|
return nil
|
|
}
|
|
|
|
// Data: amount0, amount1, sqrtPriceX96, liquidity, tick
|
|
amount0Bytes := hexToBytes(log.Data[0:64])
|
|
amount1Bytes := hexToBytes(log.Data[64:128])
|
|
|
|
// Handle signed integers
|
|
amount0 := new(big.Int).SetBytes(amount0Bytes)
|
|
if amount0Bytes[0]&0x80 != 0 {
|
|
amount0.Sub(amount0, new(big.Int).Lsh(big.NewInt(1), 256))
|
|
}
|
|
amount1 := new(big.Int).SetBytes(amount1Bytes)
|
|
if amount1Bytes[0]&0x80 != 0 {
|
|
amount1.Sub(amount1, new(big.Int).Lsh(big.NewInt(1), 256))
|
|
}
|
|
|
|
var size, quoteSize *big.Int
|
|
var side OrderSide
|
|
|
|
if amount0.Sign() > 0 {
|
|
side = OrderSideSell
|
|
size = amount0
|
|
quoteSize = new(big.Int).Neg(amount1)
|
|
} else {
|
|
side = OrderSideBuy
|
|
size = new(big.Int).Neg(amount0)
|
|
quoteSize = amount1
|
|
}
|
|
|
|
price := big.NewInt(0)
|
|
if size.Sign() > 0 {
|
|
price = new(big.Int).Mul(quoteSize, big.NewInt(1e18))
|
|
price.Div(price, size)
|
|
if price.Sign() < 0 {
|
|
price.Neg(price)
|
|
}
|
|
}
|
|
|
|
return &TradeHistory{
|
|
ID: fmt.Sprintf("%s-%d", log.TxHash, log.LogIndex),
|
|
Market: log.Address,
|
|
Price: price,
|
|
Size: size,
|
|
QuoteSize: quoteSize,
|
|
Side: side,
|
|
Timestamp: log.Timestamp,
|
|
TxHash: log.TxHash,
|
|
BlockNumber: log.BlockNumber,
|
|
Taker: "0x" + log.Topics[2][26:],
|
|
}
|
|
}
|
|
|
|
// extractOrderBookTrade extracts trade from order book
|
|
func (d *DeFiIndexer) extractOrderBookTrade(log *LogEntry) *TradeHistory {
|
|
if len(log.Topics) < 4 || len(log.Data) < 192 {
|
|
return nil
|
|
}
|
|
|
|
price := new(big.Int).SetBytes(hexToBytes(log.Data[0:64]))
|
|
size := new(big.Int).SetBytes(hexToBytes(log.Data[64:128]))
|
|
sideRaw := new(big.Int).SetBytes(hexToBytes(log.Data[128:192])).Uint64()
|
|
|
|
side := OrderSideBuy
|
|
if sideRaw == 1 {
|
|
side = OrderSideSell
|
|
}
|
|
|
|
quoteSize := new(big.Int).Mul(price, size)
|
|
quoteSize.Div(quoteSize, big.NewInt(1e18))
|
|
|
|
return &TradeHistory{
|
|
ID: log.Topics[1],
|
|
Market: log.Address,
|
|
Price: price,
|
|
Size: size,
|
|
QuoteSize: quoteSize,
|
|
Side: side,
|
|
Timestamp: log.Timestamp,
|
|
TxHash: log.TxHash,
|
|
BlockNumber: log.BlockNumber,
|
|
}
|
|
}
|
|
|
|
// Accessor methods
|
|
|
|
// AMM returns the AMM indexer
|
|
func (d *DeFiIndexer) AMM() *AMMIndexer {
|
|
return d.amm
|
|
}
|
|
|
|
// LSSVM returns the LSSVM indexer
|
|
func (d *DeFiIndexer) LSSVM() *LSSVMIndexer {
|
|
return d.lssvm
|
|
}
|
|
|
|
// Perps returns the perpetuals indexer
|
|
func (d *DeFiIndexer) Perps() *PerpsIndexer {
|
|
return d.perps
|
|
}
|
|
|
|
// Synths returns the synthetics indexer
|
|
func (d *DeFiIndexer) Synths() *SynthsIndexer {
|
|
return d.synths
|
|
}
|
|
|
|
// Staking returns the staking indexer
|
|
func (d *DeFiIndexer) Staking() *StakingIndexer {
|
|
return d.staking
|
|
}
|
|
|
|
// Bridge returns the bridge indexer
|
|
func (d *DeFiIndexer) Bridge() *BridgeIndexer {
|
|
return d.bridge
|
|
}
|
|
|
|
// OrderBook returns the order book indexer
|
|
func (d *DeFiIndexer) OrderBook() *OrderBookIndexer {
|
|
return d.orderbook
|
|
}
|
|
|
|
// MarketHistory returns the market history indexer
|
|
func (d *DeFiIndexer) MarketHistory() *MarketHistoryIndexer {
|
|
return d.marketHistory
|
|
}
|
|
|
|
// NFTMarketplace returns the NFT marketplace indexer
|
|
func (d *DeFiIndexer) NFTMarketplace() *NFTMarketplaceIndexer {
|
|
return d.nftMarketplace
|
|
}
|
|
|
|
// Stats returns indexer statistics
|
|
func (d *DeFiIndexer) Stats() *DeFiStats {
|
|
d.mu.RLock()
|
|
defer d.mu.RUnlock()
|
|
return d.stats
|
|
}
|
|
|
|
// Start starts background monitoring
|
|
func (d *DeFiIndexer) Start(ctx context.Context) {
|
|
// Start bridge pending monitor
|
|
go d.bridge.StartPendingMonitor(ctx, 30*time.Second)
|
|
|
|
// Start market history cleanup
|
|
go d.startCleanup(ctx)
|
|
}
|
|
|
|
// startCleanup runs periodic cleanup
|
|
func (d *DeFiIndexer) startCleanup(ctx context.Context) {
|
|
ticker := time.NewTicker(1 * time.Hour)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case <-ticker.C:
|
|
d.marketHistory.Cleanup(7 * 24 * time.Hour)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetOverview returns the DeFi overview.
|
|
func (d *DeFiIndexer) GetOverview() *DeFiOverview {
|
|
return &DeFiOverview{
|
|
ChainID: d.chainID,
|
|
Stats: d.Stats(),
|
|
AMMStats: d.amm.GetStats(),
|
|
LSSVMStats: d.lssvm.GetStats(),
|
|
PerpsStats: d.perps.GetStats(),
|
|
SynthsStats: d.synths.GetStats(),
|
|
StakingStats: d.staking.GetStats(),
|
|
BridgeStats: d.bridge.GetStats(),
|
|
MarketStats: d.marketHistory.Stats(),
|
|
TopMarkets: d.marketHistory.GetTopMarkets(10),
|
|
NFTMarketStats: d.nftMarketplace.GetStats(),
|
|
TopNFTCollections: d.nftMarketplace.GetTopCollections(10),
|
|
Timestamp: time.Now(),
|
|
}
|
|
}
|
|
|
|
// DeFiOverview holds aggregated DeFi stats.
|
|
type DeFiOverview struct {
|
|
ChainID ChainID `json:"chainId"`
|
|
Stats *DeFiStats `json:"stats"`
|
|
AMMStats *AMMStats `json:"ammStats"`
|
|
LSSVMStats *LSSVMStats `json:"lssvmStats"`
|
|
PerpsStats *PerpsStats `json:"perpsStats"`
|
|
SynthsStats *SynthsStats `json:"synthsStats"`
|
|
StakingStats *StakingStats `json:"stakingStats"`
|
|
BridgeStats *BridgeStats `json:"bridgeStats"`
|
|
MarketStats map[string]interface{} `json:"marketStats"`
|
|
TopMarkets []*MarketTicker `json:"topMarkets"`
|
|
NFTMarketStats *NFTMarketplaceStats `json:"nftMarketStats"`
|
|
TopNFTCollections []*NFTCollection `json:"topNftCollections"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
}
|