Add full monorepo: virtual-banker, backend, frontend, docs, scripts, deployment
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
130
backend/swap/aggregator.go
Normal file
130
backend/swap/aggregator.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package swap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Aggregator aggregates quotes from multiple DEX aggregators
|
||||
type Aggregator struct {
|
||||
providers []QuoteProvider
|
||||
}
|
||||
|
||||
// NewAggregator creates a new swap aggregator
|
||||
func NewAggregator() *Aggregator {
|
||||
return &Aggregator{
|
||||
providers: []QuoteProvider{
|
||||
NewOneInchProvider(),
|
||||
NewZeroXProvider(),
|
||||
NewParaswapProvider(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// QuoteProvider interface for DEX aggregators
|
||||
type QuoteProvider interface {
|
||||
GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error)
|
||||
Name() string
|
||||
}
|
||||
|
||||
// QuoteRequest represents a swap quote request
|
||||
type QuoteRequest struct {
|
||||
FromToken string
|
||||
ToToken string
|
||||
Amount string
|
||||
FromChain int
|
||||
ToChain int
|
||||
Slippage float64
|
||||
}
|
||||
|
||||
// Quote represents a swap quote
|
||||
type Quote struct {
|
||||
Provider string
|
||||
FromToken string
|
||||
ToToken string
|
||||
FromAmount string
|
||||
ToAmount string
|
||||
EstimatedGas string
|
||||
PriceImpact float64
|
||||
Route []RouteStep
|
||||
}
|
||||
|
||||
// RouteStep represents a step in the swap route
|
||||
type RouteStep struct {
|
||||
Protocol string
|
||||
From string
|
||||
To string
|
||||
}
|
||||
|
||||
// GetBestQuote gets the best quote from all providers
|
||||
func (a *Aggregator) GetBestQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
|
||||
var bestQuote *Quote
|
||||
var bestAmount string
|
||||
|
||||
for _, provider := range a.providers {
|
||||
quote, err := provider.GetQuote(ctx, req)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if bestQuote == nil || quote.ToAmount > bestAmount {
|
||||
bestQuote = quote
|
||||
bestAmount = quote.ToAmount
|
||||
}
|
||||
}
|
||||
|
||||
if bestQuote == nil {
|
||||
return nil, fmt.Errorf("no quotes available")
|
||||
}
|
||||
|
||||
return bestQuote, nil
|
||||
}
|
||||
|
||||
// OneInchProvider implements QuoteProvider for 1inch
|
||||
type OneInchProvider struct{}
|
||||
|
||||
func NewOneInchProvider() *OneInchProvider {
|
||||
return &OneInchProvider{}
|
||||
}
|
||||
|
||||
func (p *OneInchProvider) Name() string {
|
||||
return "1inch"
|
||||
}
|
||||
|
||||
func (p *OneInchProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
|
||||
// Implementation would call 1inch API
|
||||
return nil, fmt.Errorf("not implemented - requires 1inch API integration")
|
||||
}
|
||||
|
||||
// ZeroXProvider implements QuoteProvider for 0x
|
||||
type ZeroXProvider struct{}
|
||||
|
||||
func NewZeroXProvider() *ZeroXProvider {
|
||||
return &ZeroXProvider{}
|
||||
}
|
||||
|
||||
func (p *ZeroXProvider) Name() string {
|
||||
return "0x"
|
||||
}
|
||||
|
||||
func (p *ZeroXProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
|
||||
// Implementation would call 0x API
|
||||
return nil, fmt.Errorf("not implemented - requires 0x API integration")
|
||||
}
|
||||
|
||||
// ParaswapProvider implements QuoteProvider for Paraswap
|
||||
type ParaswapProvider struct{}
|
||||
|
||||
func NewParaswapProvider() *ParaswapProvider {
|
||||
return &ParaswapProvider{}
|
||||
}
|
||||
|
||||
func (p *ParaswapProvider) Name() string {
|
||||
return "Paraswap"
|
||||
}
|
||||
|
||||
func (p *ParaswapProvider) GetQuote(ctx context.Context, req *QuoteRequest) (*Quote, error) {
|
||||
// Implementation would call Paraswap API
|
||||
return nil, fmt.Errorf("not implemented - requires Paraswap API integration")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user