decred.org/dcrdex@v1.0.5/client/mm/libxc/interface.go (about)

     1  package libxc
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"decred.org/dcrdex/client/core"
     9  	"decred.org/dcrdex/dex"
    10  )
    11  
    12  // ExchangeBalance holds the available and locked balances of an asset
    13  // on a CEX.
    14  type ExchangeBalance struct {
    15  	Available uint64 `json:"available"`
    16  	Locked    uint64 `json:"locked"`
    17  }
    18  
    19  // Trade represents a trade made on a CEX.
    20  type Trade struct {
    21  	ID          string
    22  	Sell        bool
    23  	Qty         uint64
    24  	Rate        uint64
    25  	BaseID      uint32
    26  	QuoteID     uint32
    27  	BaseFilled  uint64
    28  	QuoteFilled uint64
    29  	Complete    bool // cancelled or filled
    30  }
    31  
    32  type MarketDay struct {
    33  	Vol            float64 `json:"vol"`
    34  	QuoteVol       float64 `json:"quoteVol"`
    35  	PriceChange    float64 `json:"priceChange"`
    36  	PriceChangePct float64 `json:"priceChangePct"`
    37  	AvgPrice       float64 `json:"avgPrice"`
    38  	LastPrice      float64 `json:"lastPrice"`
    39  	OpenPrice      float64 `json:"openPrice"`
    40  	HighPrice      float64 `json:"highPrice"`
    41  	LowPrice       float64 `json:"lowPrice"`
    42  }
    43  
    44  // Market is the base and quote assets of a market on a CEX.
    45  type Market struct {
    46  	BaseID           uint32     `json:"baseID"`
    47  	QuoteID          uint32     `json:"quoteID"`
    48  	Day              *MarketDay `json:"day"`
    49  	BaseMinWithdraw  uint64     `json:"baseMinWithdraw"`
    50  	QuoteMinWithdraw uint64     `json:"quoteMinWithdraw"`
    51  }
    52  
    53  type Status struct {
    54  	Markets  map[string]*Market          `json:"markets"`
    55  	Balances map[uint32]*ExchangeBalance `json:"balances"`
    56  }
    57  
    58  type DepositData struct {
    59  	AssetID            uint32
    60  	AmountConventional float64
    61  	TxID               string
    62  }
    63  
    64  // MarketMatch is a market for which both assets are supported by Bison Wallet.
    65  type MarketMatch struct {
    66  	BaseID  uint32 `json:"baseID"`
    67  	QuoteID uint32 `json:"quoteID"`
    68  	// MarketID is the id used by DCRDEX.
    69  	MarketID string `json:"marketID"`
    70  	// Slug is a market identifier used by the cex.
    71  	Slug string `json:"slug"`
    72  }
    73  
    74  type BalanceUpdate struct {
    75  	AssetID uint32           `json:"assetID"`
    76  	Balance *ExchangeBalance `json:"balance"`
    77  }
    78  
    79  var (
    80  	ErrWithdrawalPending = errors.New("withdrawal pending")
    81  	ErrUnsyncedOrderbook = errors.New("orderbook not synced")
    82  )
    83  
    84  // CEX implements a set of functions that can be used to interact with a
    85  // centralized exchange's spot trading API. All rates and quantities
    86  // when interacting with the CEX interface will adhere to the standard
    87  // rates and quantities of the DEX.
    88  type CEX interface {
    89  	dex.Connector
    90  	// Balance returns the balance of an asset at the CEX.
    91  	Balance(assetID uint32) (*ExchangeBalance, error)
    92  	// Balances returns the balances of known assets on the CEX.
    93  	Balances(ctx context.Context) (map[uint32]*ExchangeBalance, error)
    94  	// CancelTrade cancels a trade on the CEX.
    95  	CancelTrade(ctx context.Context, baseID, quoteID uint32, tradeID string) error
    96  	// MatchedMarkets returns the list of markets at the CEX.
    97  	MatchedMarkets(ctx context.Context) ([]*MarketMatch, error)
    98  	// Markets returns the list of markets at the CEX.
    99  	Markets(ctx context.Context) (map[string]*Market, error)
   100  	// SubscribeMarket subscribes to order book updates on a market. This must
   101  	// be called before calling VWAP.
   102  	SubscribeMarket(ctx context.Context, baseID, quoteID uint32) error
   103  	// SubscribeTradeUpdates returns a channel that the caller can use to
   104  	// listen for updates to a trade's status. When the subscription ID
   105  	// returned from this function is passed as the updaterID argument to
   106  	// Trade, then updates to the trade will be sent on the updated channel
   107  	// returned from this function.
   108  	SubscribeTradeUpdates() (updates <-chan *Trade, unsubscribe func(), subscriptionID int)
   109  	// Trade executes a trade on the CEX. updaterID takes a subscriptionID
   110  	// returned from SubscribeTradeUpdates.
   111  	Trade(ctx context.Context, baseID, quoteID uint32, sell bool, rate, qty uint64, subscriptionID int) (*Trade, error)
   112  	// UnsubscribeMarket unsubscribes from order book updates on a market.
   113  	UnsubscribeMarket(baseID, quoteID uint32) error
   114  	// VWAP returns the volume weighted average price for a certain quantity
   115  	// of the base asset on a market. The sell parameter specifies the side of
   116  	// the market on which to get the average price. SubscribeMarket must be
   117  	// called, and the market must be synced before results can be expected.
   118  	VWAP(baseID, quoteID uint32, sell bool, qty uint64) (vwap, extrema uint64, filled bool, err error)
   119  	// MidGap returns the mid-gap price for an order book.
   120  	MidGap(baseID, quoteID uint32) uint64
   121  	// GetDepositAddress returns a deposit address for an asset.
   122  	GetDepositAddress(ctx context.Context, assetID uint32) (string, error)
   123  	// ConfirmDeposit is an async function that calls onConfirm when the status
   124  	// of a deposit has been confirmed.
   125  	ConfirmDeposit(ctx context.Context, deposit *DepositData) (bool, uint64)
   126  	// Withdraw withdraws funds from the CEX to a certain address. onComplete
   127  	// is called with the actual amount withdrawn (amt - fees) and the
   128  	// transaction ID of the withdrawal.
   129  	Withdraw(ctx context.Context, assetID uint32, amt uint64, address string) (string, error)
   130  	// ConfirmWithdrawal checks whether a withdrawal has been completed. If the
   131  	// withdrawal has not yet been sent, ErrWithdrawalPending is returned.
   132  	ConfirmWithdrawal(ctx context.Context, withdrawalID string, assetID uint32) (uint64, string, error)
   133  	// TradeStatus returns the current status of a trade.
   134  	TradeStatus(ctx context.Context, id string, baseID, quoteID uint32) (*Trade, error)
   135  	// Book generates the CEX's current view of a market's orderbook.
   136  	Book(baseID, quoteID uint32) (buys, sells []*core.MiniOrder, _ error)
   137  }
   138  
   139  const (
   140  	Binance   = "Binance"
   141  	BinanceUS = "BinanceUS"
   142  )
   143  
   144  // IsValidCEXName returns whether or not a cex name is supported.
   145  func IsValidCexName(cexName string) bool {
   146  	return cexName == Binance || cexName == BinanceUS
   147  }
   148  
   149  type CEXConfig struct {
   150  	Net       dex.Network
   151  	APIKey    string
   152  	SecretKey string
   153  	Logger    dex.Logger
   154  	Notify    func(interface{})
   155  }
   156  
   157  // NewCEX creates a new CEX.
   158  func NewCEX(cexName string, cfg *CEXConfig) (CEX, error) {
   159  	switch cexName {
   160  	case Binance:
   161  		return newBinance(cfg, false), nil
   162  	case BinanceUS:
   163  		return newBinance(cfg, true), nil
   164  	default:
   165  		return nil, fmt.Errorf("unrecognized CEX: %v", cexName)
   166  	}
   167  }