Skip to content

Commit

Permalink
added current state
Browse files Browse the repository at this point in the history
  • Loading branch information
decanus committed Feb 16, 2024
1 parent 171b959 commit 5f3c6c2
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
pull_request:
push:
branches:
- master

jobs:
test:
strategy:
matrix:
go-version: [1.22.x]
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Test
run: go test ./...
lint:
strategy:
matrix:
go-version: [1.22.x]
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@master
with:
fetch-depth: 1
- uses: reviewdog/action-golangci-lint@v2
staticcheck:
strategy:
matrix:
go-version: [ 1.22.x ]
platform: [ ubuntu-latest ]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 1
- uses: dominikh/[email protected]
with:
version: "2022.1.1"
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Squid Router

This repository contains Go bindings for the [0xSquid](https://www.squidrouter.com/) API.

Currently supported versions of the API:
- [v1](https://squidrouter.readme.io/reference/getting-started-with-your-api-1)
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/project-blanc/go-squid-router

go 1.21.7

require github.com/pkg/errors v0.9.1
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
63 changes: 63 additions & 0 deletions v1/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package v1

import (
"encoding/json"
"io"
"net/http"

"github.com/pkg/errors"
)

type Client struct {
cli *http.Client
}

func NewClient() *Client {
return &Client{
cli: &http.Client{}, // @TODO inject
}
}

// Route calls the route endpoint returning route information and the call data object
func (c *Client) Route(params RouteRequestParameters) (*RouteResponse, error) {
if params.Slippage <= 0.0 || params.Slippage > 99.99 {
return nil, errors.New("slippage must be > 0 and < 99.99")
}

resp, err := c.cli.Get("https://api.0xsquid.com/v1/route?" + params.ToQuery().Encode())
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, errorForResponse(resp.Body)
}

buff, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read response body")
}

rr := map[string]*RouteResponse{}
err = json.Unmarshal(buff, &rr)
if err != nil {
return nil, errors.Wrap(err, "failed to unmarshal response body")
}

return rr["route"], nil
}

func errorForResponse(body io.Reader) error {
buff, err := io.ReadAll(body)
if err != nil {
return errors.Wrap(err, "failed to read error response body")
}

er := map[string][]ErrorResponse{}
err = json.Unmarshal(buff, &er)
if err != nil {
return errors.Wrap(err, "failed to unmarshal error response body")
}

return er["errors"][0].Err()
}
119 changes: 119 additions & 0 deletions v1/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package v1

import (
"fmt"
"net/url"
"strconv"
)

type CallType int

const (
CallTypeDefault CallType = iota
CallTypeFullTokenBalance
CallTypeFullNativeBalance
CollectTokenBalance
)

type CustomContractCall struct {
CallType CallType
Target string
Value string
CallData string
EstimatedGas string
Payload struct {
TokenAddress string
InputPosition string
}
}

type RouteRequestParameters struct {
// FromChain is the from chain id
FromChain string
// ToChain is the to chain id
ToChain string
// FromToken is the from token address
FromToken string
// ToToken is the to token address
ToToken string
// FromAmount is the amount to be sent from To Chain
FromAmount string
// FromAddress EVM address for EVM to Cosmos, and Cosmos address for Cosmos to EVM.
FromAddress string
// ToAddress is the ToChain recipient address
ToAddress string
// Slippage must be between 0 and 99.99
Slippage float64
// QuoteOnly returns only the route quote and excludes all call data
QuoteOnly bool
// EnableExpress enables express feature
EnableExpress bool
// CustomContractCalls array of custom contract calls
CustomContractCalls []CustomContractCall
// Prefer array of supported DEXs for this trade
Prefer []string
// ReceiveGasOnDestination receive gas on destination chain
ReceiveGasOnDestination bool
}

func (p RouteRequestParameters) ToQuery() url.Values {
query := url.Values{}
query.Add("fromChain", p.FromChain)
query.Add("toChain", p.ToChain)
query.Add("fromToken", p.FromToken)
query.Add("toToken", p.ToToken)
query.Add("fromAmount", p.FromAmount)

if p.FromAddress != "" {
query.Add("fromAddress", p.FromAddress)
}

query.Add("toAddress", p.ToAddress)

query.Add("slippage", strconv.FormatFloat(p.Slippage, 'f', -1, 64))
query.Add("quoteOnly", strconv.FormatBool(p.QuoteOnly))
query.Add("enableExpress", strconv.FormatBool(p.EnableExpress))

for i, call := range p.CustomContractCalls {
query.Add(fmt.Sprintf("customContractCalls[%d][callType]", i), strconv.Itoa(int(call.CallType)))
query.Add(fmt.Sprintf("customContractCalls[%d][target]", i), call.Target)
query.Add(fmt.Sprintf("customContractCalls[%d][value]", i), call.Value)
query.Add(fmt.Sprintf("customContractCalls[%d][callData]", i), call.CallData)
query.Add(fmt.Sprintf("customContractCalls[%d][estimatedGas]", i), call.EstimatedGas)
query.Add(fmt.Sprintf("customContractCalls[%d][payload][tokenAddress]", i), call.Payload.TokenAddress)
query.Add(fmt.Sprintf("customContractCalls[%d][payload][inputPos]", i), call.Payload.InputPosition)
}

for i, prefer := range p.Prefer {
query.Add(fmt.Sprintf("prefer[%d]", i), prefer)
}

query.Add("receiveGasOnDestination", strconv.FormatBool(p.ReceiveGasOnDestination))

return query
}

type TransactionRequest struct {
TargetAddress string `json:"targetAddress"`
Data string `json:"data"`
Value string `json:"value"`
GasLimit string `json:"gasLimit"`
GasPrice string `json:"gasPrice"`
MaxFeePerGas string `json:"maxFeePerGas"`
MaxPriorityFeePerGas string `json:"maxPriorityFeePerGas"`
}

type RouteResponse struct {
// @TODO estimate
// @TodO params
TransactionRequest TransactionRequest `json:"transactionRequest"`
}

type ErrorResponse struct {
Message string `json:"message"`
ErrorType string `json:"errorType"`
}

func (e ErrorResponse) Err() error {
return fmt.Errorf("squid err: %s message: %s", e.ErrorType, e.Message)
}

0 comments on commit 5f3c6c2

Please sign in to comment.