diff --git a/harnesses/token-quote-coverage/cmd/monitor/dexscreener.go b/harnesses/token-quote-coverage/cmd/monitor/dexscreener.go index 85bacda7..4e6258da 100644 --- a/harnesses/token-quote-coverage/cmd/monitor/dexscreener.go +++ b/harnesses/token-quote-coverage/cmd/monitor/dexscreener.go @@ -12,10 +12,13 @@ import ( var dexClient = &http.Client{Timeout: 15 * time.Second} -// boostEntry is one item from /token-boosts/latest/v1. +// boostEntry is one item from /token-boosts/latest/v1 or a discovery source. +// Venue is pre-assigned when the source already knows the launchpad (e.g. Virtuals API). +// An empty Venue is resolved via Dexscreener pair enrichment. type boostEntry struct { ChainId string `json:"chainId"` TokenAddress string `json:"tokenAddress"` + Venue string // optional: pre-assigned venue slug } // FetchBoostedTokens calls the Dexscreener token-boosts endpoint and returns @@ -131,6 +134,11 @@ func EnrichWithVenue(ctx context.Context, entries []boostEntry) ([]Token, error) var tokens []Token for _, e := range entries { + if e.Venue != "" { + // Venue pre-assigned by discovery source; skip Dexscreener lookup. + tokens = append(tokens, Token{Address: e.TokenAddress, Chain: e.ChainId, Venue: e.Venue}) + continue + } k := key{e.ChainId, strings.ToLower(e.TokenAddress)} dexId, ok := dexIdOf[k] if !ok { diff --git a/harnesses/token-quote-coverage/cmd/monitor/odos.go b/harnesses/token-quote-coverage/cmd/monitor/odos.go index 6d564331..8dae9538 100644 --- a/harnesses/token-quote-coverage/cmd/monitor/odos.go +++ b/harnesses/token-quote-coverage/cmd/monitor/odos.go @@ -16,12 +16,14 @@ const ( ) // OdosProvider hits api.odos.xyz/sor/quote/v2 for Base and BSC. +// sem limits to 2 concurrent requests to avoid 429 throttling. type OdosProvider struct { client *http.Client + sem chan struct{} } func NewOdosProvider() *OdosProvider { - return &OdosProvider{client: newWarmHTTPClient()} + return &OdosProvider{client: newWarmHTTPClient(), sem: make(chan struct{}, 2)} } func (p *OdosProvider) Slug() string { return "odos" } @@ -31,6 +33,14 @@ func (p *OdosProvider) SupportsChain(chain string) bool { } func (p *OdosProvider) Quote(ctx context.Context, token Token) (ok bool) { + select { + case p.sem <- struct{}{}: + defer func() { <-p.sem }() + case <-ctx.Done(): + RecordProbe(p.Slug(), token.Venue, token.Chain, false) + return false + } + var chainId int var usdcAddr string switch token.Chain { diff --git a/harnesses/token-quote-coverage/cmd/monitor/virtuals.go b/harnesses/token-quote-coverage/cmd/monitor/virtuals.go index ecfeb584..2d354800 100644 --- a/harnesses/token-quote-coverage/cmd/monitor/virtuals.go +++ b/harnesses/token-quote-coverage/cmd/monitor/virtuals.go @@ -67,7 +67,7 @@ func FetchVirtualsTokens(ctx context.Context) ([]boostEntry, error) { continue } seen[k] = true - out = append(out, boostEntry{ChainId: "base", TokenAddress: it.TokenAddress}) + out = append(out, boostEntry{ChainId: "base", TokenAddress: it.TokenAddress, Venue: "virtuals"}) } return out, nil }