Files
explorer-monorepo/backend/bridge/symbiosis_provider.go

96 lines
2.7 KiB
Go

package bridge
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
symbiosisAPIBase = "https://api.symbiosis.finance/crosschain"
symbiosisTimeout = 10 * time.Second
)
var symbiosisSupportedChains = map[int]bool{
1: true, 10: true, 137: true, 42161: true, 8453: true,
56: true, 43114: true, 100: true, 25: true, 250: true,
324: true, 59144: true, 534352: true, 42220: true, 5000: true,
}
type symbiosisReq struct {
Amount string `json:"amount"`
TokenInChain int `json:"tokenInChainId"`
TokenIn string `json:"tokenIn"`
TokenOutChain int `json:"tokenOutChainId"`
TokenOut string `json:"tokenOut"`
From string `json:"from"`
Slippage int `json:"slippage"`
}
type symbiosisResp struct {
AmountOut string `json:"amountOut"`
AmountOutMin string `json:"amountOutMin"`
}
type SymbiosisProvider struct {
apiBase string
client *http.Client
}
func NewSymbiosisProvider() *SymbiosisProvider {
return &SymbiosisProvider{apiBase: symbiosisAPIBase, client: &http.Client{Timeout: symbiosisTimeout}}
}
func (p *SymbiosisProvider) Name() string { return "Symbiosis" }
func (p *SymbiosisProvider) SupportsRoute(fromChain, toChain int) bool {
return symbiosisSupportedChains[fromChain] && symbiosisSupportedChains[toChain]
}
func (p *SymbiosisProvider) GetQuote(ctx context.Context, req *BridgeRequest) (*BridgeQuote, error) {
addr := req.Recipient
if addr == "" {
addr = "0x0000000000000000000000000000000000000000"
}
bodyReq := symbiosisReq{
Amount: req.Amount, TokenInChain: req.FromChain, TokenIn: req.FromToken,
TokenOutChain: req.ToChain, TokenOut: req.ToToken, From: addr, Slippage: 100,
}
jsonBody, _ := json.Marshal(bodyReq)
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, p.apiBase+"/v2/quote", bytes.NewReader(jsonBody))
if err != nil {
return nil, err
}
httpReq.Header.Set("Content-Type", "application/json")
resp, err := p.client.Do(httpReq)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Symbiosis API %d: %s", resp.StatusCode, string(body))
}
var r symbiosisResp
if err := json.Unmarshal(body, &r); err != nil {
return nil, err
}
toAmount := r.AmountOut
if toAmount == "" {
toAmount = r.AmountOutMin
}
if toAmount == "" {
return nil, fmt.Errorf("Symbiosis: no amount")
}
return &BridgeQuote{
Provider: "Symbiosis", FromChain: req.FromChain, ToChain: req.ToChain,
FromAmount: req.Amount, ToAmount: toAmount, Fee: "0", EstimatedTime: "1-5 min",
Route: []BridgeStep{{Provider: "Symbiosis", From: strconv.Itoa(req.FromChain), To: strconv.Itoa(req.ToChain), Type: "bridge"}},
}, nil
}