fswap

package module
v2.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2024 License: MIT Imports: 17 Imported by: 0

README

4swap SDK go

4swap

4swap is a decentralized protocol implement for automated liquidity provision on Mixin Network

Install

go get github.com/fox-one/4swap-sdk-go/v2
Authorization

4swap supports two kinds of access tokens:

  1. the access token that complete the OAuth flow at 4swap's webpage: https://app.4swap.org
  2. the access token that generated by your own Mixn Application. The token should sign the URL /me and the scope should be "FULL". Please read this document for more details.
Example
func TestPreOrder(t *testing.T) {
    ctx := context.Background()

    c := New()
    c.UseToken("your auth token")
    
    pairs, err := c.ListPairs(ctx)
    if err != nil {
        t.Fatal(err)
    }
    
    req := &PreOrderReq{
        PayAssetID:  "4d8c508b-91c5-375b-92b0-ee702ed2dac5",
        FillAssetID: "31d2ea9c-95eb-3355-b65b-ba096853bc18",
        PayAmount:   decimal.NewFromFloat(0.1),
    }
    
    preOrder, err := PreOrderWithPairs(pairs, req)
    if err != nil {
        t.Fatal(err)
    }
    
    t.Logf("fill amount: %s", preOrder.FillAmount)
    
    followID := uuid.NewString()
    minAmount := preOrder.FillAmount.Mul(decimal.NewFromFloat(0.99)).Truncate(8)
    memo := BuildSwap(followID, req.FillAssetID, preOrder.Paths, minAmount)
    
    t.Logf("memo: %s", memo)
    
    group, err := c.ReadGroup(ctx)
    if err != nil {
        t.Fatal(err)
    }
    
    t.Logf("target mix address: %s", group.MixAddress)
    
    transfer := &mixin.TransferInput{
        AssetID:    req.PayAssetID,
        OpponentID: group.MixAddress,
        Amount:     req.PayAmount,
        TraceID:    followID,
        Memo:       memo,
    }
    
    t.Log(mixin.URL.SafePay(transfer))
    
    // transfer pay asset to mix address
    
    // view order detail
    order, err := c.ReadOrder(ctx, followID)
    if err != nil {
        assert.True(t, IsErrorCode(err, 401))
    } else {
        t.Logf("order state: %s", order.State)
    }
}

Documentation

Index

Constants

View Source
const (
	ActionAdd    uint16 = 1
	ActionRemove uint16 = 2
	ActionSwap   uint16 = 3

	ProtocolVersion uint8 = 2
)
View Source
const (
	DepositStatePending   = "Pending"
	DepositStateCancelled = "Cancelled"
	DepositStateDone      = "Done"
)
View Source
const (
	OrderStateTrading  = "Trading"
	OrderStateRejected = "Rejected"
	OrderStateDone     = "Done"
)
View Source
const (
	MaxRouteDepth = 4
)

Variables

View Source
var (
	ErrInsufficientLiquiditySwapped = errors.New("insufficient liquidity swapped")
)

Functions

func BuildAdd

func BuildAdd(followID string, oppositeAsset string, slippage decimal.Decimal, expireDuration time.Duration) string

func BuildRemove

func BuildRemove(followID string) string

func BuildSwap

func BuildSwap(followID string, fillAsset string, paths route.Paths, minAmount decimal.Decimal) string

func Ceil

func Ceil(d decimal.Decimal, precision int32) decimal.Decimal

func Decimal

func Decimal(v string) decimal.Decimal

func DecodeResponse

func DecodeResponse(resp *resty.Response) ([]byte, error)

func GenerateToken

func GenerateToken(clientID, sessionID, sessionKey string, exp time.Duration) (string, error)

GenerateToken create a new mixin authorization token store.Scope must be 'FULL'

func IsErrorCode

func IsErrorCode(err error, code int) bool

func UnmarshalResponse

func UnmarshalResponse(resp *resty.Response, v interface{}) error

Types

type Asset

type Asset struct {
	ID            string          `json:"id,omitempty"`
	Name          string          `json:"name,omitempty"`
	Symbol        string          `json:"symbol,omitempty"`
	DisplaySymbol string          `json:"display_symbol,omitempty"`
	ChainID       string          `json:"chain_id,omitempty"`
	Price         decimal.Decimal `json:"price,omitempty"`
	Tag           string          `json:"tag,omitempty"`
	Chain         *Asset          `json:"chain,omitempty"`
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

func New

func New() *Client

func (*Client) ListAssets

func (c *Client) ListAssets(ctx context.Context) ([]*Asset, error)

ListAssets list all assets

func (*Client) ListPairs

func (c *Client) ListPairs(ctx context.Context) ([]*Pair, error)

ListPairs list all pairs

func (*Client) PreOrder

func (c *Client) PreOrder(ctx context.Context, req *PreOrderReq) (*Order, error)

PreOrder 预下单

如果要同时对多个交易对预下单,不建议使用这个方法;而是先调用 ListPairs 然后重复使用 Pairs 去 Route 或者 ReverseRoute,这样只需要调用一次 /pairs 接口 不会那么容易触发 Rate Limit

func (*Client) ReadAsset

func (c *Client) ReadAsset(ctx context.Context, assetID string) (*Asset, error)

ReadAsset read asset

func (*Client) ReadDeposit

func (c *Client) ReadDeposit(ctx context.Context, depositID string) (*Deposit, error)

func (*Client) ReadGroup

func (c *Client) ReadGroup(ctx context.Context) (*Group, error)

ReadGroup return mtg Group info ( MTG only)

func (*Client) ReadOrder

func (c *Client) ReadOrder(ctx context.Context, id string) (*Order, error)

ReadOrder return order detail by id WithToken required

func (*Client) ReadPair

func (c *Client) ReadPair(ctx context.Context, base, quote string) (*Pair, error)

ReadPair return pair detail by base asset id & quote asset id

func (*Client) Resty

func (c *Client) Resty() *resty.Client

func (*Client) UseEndpoint

func (c *Client) UseEndpoint(endpoint string)

func (*Client) UseToken

func (c *Client) UseToken(token string)

type Deposit

type Deposit struct {
	ID           string          `json:"id,omitempty"`
	CreatedAt    time.Time       `json:"created_at,omitempty"`
	State        string          `json:"state,omitempty"`
	UserID       string          `json:"user_id,omitempty"`
	FollowID     string          `json:"follow_id,omitempty"`
	BaseAssetID  string          `json:"base_asset_id,omitempty"`
	QuoteAssetID string          `json:"quote_asset_id,omitempty"`
	BaseAmount   decimal.Decimal `json:"base_amount,omitempty"`
	QuoteAmount  decimal.Decimal `json:"quote_amount,omitempty"`
	Slippage     decimal.Decimal `json:"slippage,omitempty"`
}

type Error

type Error struct {
	Code int    `json:"code,omitempty"`
	Msg  string `json:"msg,omitempty"`
}

func (*Error) Error

func (err *Error) Error() string

type Graph

type Graph map[string]map[string]*Pair

func (Graph) Add

func (g Graph) Add(pay, fill string, pair *Pair)

func (Graph) AddPair

func (g Graph) AddPair(pair *Pair)

type Group

type Group struct {
	Members    []string `json:"members,omitempty"`
	Threshold  uint8    `json:"threshold,omitempty"`
	MixAddress string   `json:"mix_address,omitempty"`
}

type Order

type Order struct {
	ID          string          `json:"id,omitempty"`
	CreatedAt   time.Time       `json:"created_at,omitempty"`
	UserID      string          `json:"user_id,omitempty"`
	State       string          `json:"state,omitempty"`
	PayAssetID  string          `json:"pay_asset_id,omitempty"`
	PayAmount   decimal.Decimal `json:"pay_amount,omitempty"`
	FillAssetID string          `json:"fill_asset_id,omitempty"`
	FillAmount  decimal.Decimal `json:"fill_amount,omitempty"`
	MinAmount   decimal.Decimal `json:"min_amount,omitempty"`
	Paths       route.Paths     `json:"paths,omitempty"`
}

func MergeOrders

func MergeOrders(orders []*Order) *Order

func PreOrderWithPairs

func PreOrderWithPairs(pairs []*Pair, req *PreOrderReq) (*Order, error)

func ReverseRoute

func ReverseRoute(pairs []*Pair, payAssetID, fillAssetID string, fillAmount decimal.Decimal) (*Order, error)

func Route

func Route(pairs []*Pair, payAssetID, fillAssetID string, payAmount decimal.Decimal) (*Order, error)

type Pair

type Pair struct {
	BaseAssetID  string          `json:"base_asset_id,omitempty"`
	BaseAmount   decimal.Decimal `json:"base_amount,omitempty"`
	QuoteAssetID string          `json:"quote_asset_id,omitempty"`
	QuoteAmount  decimal.Decimal `json:"quote_amount,omitempty"`
	FeePercent   decimal.Decimal `json:"fee_percent,omitempty"`
	ProfitRate   decimal.Decimal `json:"profit_rate,omitempty"`
	RouteID      uint16          `json:"route_id,omitempty"`
	// 池子总的流动性份额
	LiquidityAssetID string          `json:"liquidity_asset_id,omitempty"`
	Liquidity        decimal.Decimal `json:"liquidity,omitempty"`
	SwapMethod       string          `json:"swap_method,omitempty"`
	Version          int64           `json:"version,omitempty"`
	// volume
	Volume24h      decimal.Decimal `json:"volume_24h,omitempty"`
	BaseVolume24h  decimal.Decimal `json:"base_volume_24h,omitempty"`
	QuoteVolume24h decimal.Decimal `json:"quote_volume_24h,omitempty"`
	// value
	BaseValue  decimal.Decimal `json:"base_value,omitempty"`
	QuoteValue decimal.Decimal `json:"quote_value,omitempty"`
	// stat
	Fee24h              decimal.Decimal `json:"fee_24h,omitempty"`
	TransactionCount24h int64           `json:"transaction_count_24h,omitempty"`
}

type PreOrderReq

type PreOrderReq struct {
	PayAssetID  string `json:"pay_asset_id,omitempty"`
	FillAssetID string `json:"fill_asset_id,omitempty"`
	// pay amount 和 fill amount 二选一
	PayAmount  decimal.Decimal `json:"pay_amount,omitempty"`
	FillAmount decimal.Decimal `json:"fill_amount,omitempty"`
}

type Result

type Result struct {
	PayAssetID   string
	PayAmount    decimal.Decimal
	FillAssetID  string
	FillAmount   decimal.Decimal
	FeeAssetID   string
	FeeAmount    decimal.Decimal
	ProfitAmount decimal.Decimal
	RouteID      uint16
}

Result represent Swap Result

func ReverseSwap

func ReverseSwap(pair *Pair, fillAssetID string, fillAmount decimal.Decimal) (*Result, error)

ReverseSwap is a Reverse version of Swap

func Swap

func Swap(pair *Pair, payAssetID string, payAmount decimal.Decimal) (*Result, error)

Swap trade in a pair

Directories

Path Synopsis
uni

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL