131 lines
2.8 KiB
Go
131 lines
2.8 KiB
Go
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")
|
|
}
|
|
|