Documentation ¶
Overview ¶
go-dydx is a golang api for dydx.exchange
Apis are mapped directly to https://docs.dydx.exchange.
No authentication is necessary for public information on dydx.exchange. Api key and stark key are necessary to access the private apis and trade. Api key and stark key can be obtained through the LocalStorage tab of the browser development console.
Example ¶
An example with subscriptions
package main import ( "context" "fmt" "time" "github.com/davecgh/go-spew/spew" "github.com/fardream/go-dydx" ) var _ = "keep" // An example with subscriptions func main() { const ethAddress = "<eth address>" client, err := dydx.NewClient( dydx.NewStarkKey( "<stark pubkey>", "<stark pubkey y coordinate>", "<stark private key>"), dydx.NewApiKey( "<api key>", "<api passphrase>", "<api secret>"), ethAddress, false) if err != nil { panic(err) } orderbook := make(chan *dydx.OrderbookChannelResponse) ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() go func() { if err := client.SubscribeOrderbook(ctx, "BTC-USD", orderbook); err != nil { fmt.Printf("sub order error: %#v\n", err) } close(orderbook) }() for v := range orderbook { spew.Printf("%#v\n", v) } ctx, cancel = context.WithTimeout(context.Background(), time.Second*15) defer cancel() trades := make(chan *dydx.TradesChannelResponse) go func() { if err := client.SubscribeTrades(ctx, "BTC-USD", trades); err != nil { fmt.Printf("sub trades error: %v\n", err) } close(trades) }() for v := range trades { spew.Printf("%v\n", v) } markets := make(chan *dydx.MarketsChannelResponse) ctx, cancel = context.WithTimeout(context.Background(), time.Second*15) defer cancel() go func() { if err := client.SubscribeMarkets(ctx, markets); err != nil { fmt.Printf("sub order error: %#v\n", err) } close(markets) }() for v := range markets { spew.Printf("%#v\n", v) } ctx, cancel = context.WithTimeout(context.Background(), time.Second*15) defer cancel() accounts := make(chan *dydx.AccountChannelResponse) go func() { if err := client.SubscribeAccount(ctx, 0, accounts); err != nil { fmt.Printf("sub trades error: %v\n", err) } close(accounts) }() for v := range accounts { spew.Printf("%v\n", v) } }
Output:
Index ¶
- Constants
- func GetAccountIdFromEth(ethAddress string) string
- func GetIsoDateStr(t time.Time) string
- func GetUserId(ethAddress string) string
- func NewEcdsaPrivateKeySigner(key *ecdsa.PrivateKey) *ecdsaPrivateKeySigner
- func ParseApiKeyMap(input []byte) (map[string]*ApiKey, error)
- func ParseStarkKeyMap(input []byte) (map[string]*StarkKey, error)
- func SetClientEndpoint(isMainnet bool) clientOption
- func SetClientTimeout(timeout time.Duration) clientOption
- type Account
- type AccountChannelResponse
- type AccountChannelResponseContents
- type AccountInfoByMarket
- type AccountProcessor
- type AccountResponse
- type AccountsResponse
- type ActiveOrder
- type ActiveOrdersResponse
- type ApiKey
- type Asks
- type Bids
- type CancelActiveOrdersParam
- type CancelActiveOrdersResponse
- type CancelOrderResponse
- type CancelOrdersParam
- type CancelOrdersResponse
- type CancelReason
- type Candle
- type CandlesParam
- type CandlesResponse
- type ChannelResponse
- type ChannelResponseHeader
- type Client
- func (c *Client) CancelActiveOrders(ctx context.Context, params *CancelActiveOrdersParam) (*CancelActiveOrdersResponse, error)
- func (c *Client) CancelOrder(ctx context.Context, id string) (*CancelOrderResponse, error)
- func (c *Client) CancelOrders(ctx context.Context, params *CancelOrdersParam) (*CancelOrdersResponse, error)
- func (c *Client) CreateUser(ctx context.Context, signer SignTypedData, param *CreateUserParam) (*CreateUserResponse, error)
- func (c *Client) GetAccount(ctx context.Context, id string) (*AccountResponse, error)
- func (c *Client) GetAccounts(ctx context.Context) (*AccountsResponse, error)
- func (c *Client) GetActiveOrders(ctx context.Context, params *QueryActiveOrdersParam) (*ActiveOrdersResponse, error)
- func (c *Client) GetCandles(ctx context.Context, params *CandlesParam) (*CandlesResponse, error)
- func (c *Client) GetFills(ctx context.Context, params *FillsParam) (*FillsResponse, error)
- func (c *Client) GetFundingPayments(ctx context.Context, params *FundingPaymentsParam) (*FundingPaymentsResponse, error)
- func (c *Client) GetHistoricalFunding(ctx context.Context, params *HistoricalFundingsParam) (*HistoricalFundingsResponse, error)
- func (c *Client) GetHistoricalPnL(ctx context.Context, params *HistoricalPnLParam) (*HistoricalPnLResponse, error)
- func (c *Client) GetMarkets(ctx context.Context) (*MarketsResponse, error)
- func (c *Client) GetOrderByClientId(ctx context.Context, clientId string) (*OrderResponse, error)
- func (c *Client) GetOrderById(ctx context.Context, id string) (*OrderResponse, error)
- func (c *Client) GetOrderbook(ctx context.Context, market string) (*OrderbookResponse, error)
- func (c *Client) GetOrders(ctx context.Context, params *OrderQueryParam) (*OrdersResponse, error)
- func (c *Client) GetPositions(ctx context.Context, params *PositionParams) (*PositionResponse, error)
- func (c *Client) GetTrades(ctx context.Context, params *TradesParam) (*TradesResponse, error)
- func (c *Client) GetTradingRewards(ctx context.Context, epoch int64) (*TradingRewardsResponse, error)
- func (c *Client) GetUser(ctx context.Context) (*UsersResponse, error)
- func (c *Client) NewOrder(ctx context.Context, order *CreateOrderRequest, positionId int64) (*CreateOrderResponse, error)
- func (c *Client) RequestTestnetTokens(ctx context.Context) (*RequestTestnetTokensResponse, error)
- func (c *Client) SubscribeAccount(ctx context.Context, accountNumber int, ...) error
- func (c *Client) SubscribeMarkets(ctx context.Context, outputChan chan<- *MarketsChannelResponse) error
- func (c *Client) SubscribeOrderbook(ctx context.Context, market string, ...) error
- func (c *Client) SubscribeTrades(ctx context.Context, market string, outputChan chan<- *TradesChannelResponse) error
- type CreateOrderRequest
- type CreateOrderResponse
- type CreateUserParam
- type CreateUserResponse
- type Decimal
- type DydxError
- type FastWithdrawalParam
- type Fill
- type FillList
- type FillsParam
- type FillsResponse
- type FundingPayment
- type FundingPaymentsParam
- type FundingPaymentsResponse
- type HistoricalFunding
- type HistoricalFundingsParam
- type HistoricalFundingsResponse
- type HistoricalPnL
- type HistoricalPnLParam
- type HistoricalPnLResponse
- type JsonInt
- type Logger
- type Market
- type MarketsChannelResponse
- type MarketsChannelResponseContents
- type MarketsResponse
- type Order
- type OrderQueryParam
- type OrderResponse
- type OrderSide
- type OrderStatus
- type OrderType
- type OrderbookChannelResponse
- type OrderbookChannelResponseContents
- type OrderbookOrder
- type OrderbookProcessor
- type OrderbookResponse
- type OrdersResponse
- type Position
- type PositionParams
- type PositionResponse
- type QueryActiveOrdersParam
- type RequestTestnetTokensResponse
- type SignTypedData
- type StarkKey
- type TimeInForce
- type Trade
- type TradesChannelResponse
- type TradesChannelResponseContents
- type TradesParam
- type TradesResponse
- type TradingReward
- type TradingRewardsResponse
- type Transfer
- type TransfersParam
- type TransfersResponse
- type User
- type UsersResponse
- type WithdrawResponse
- type Withdrawal
Examples ¶
Constants ¶
const ( ApiHostMainnet = "https://api.dydx.exchange" ApiHostRopsten = "https://api.stage.dydx.exchange" WsHostMainnet = "wss://api.dydx.exchange/v3/ws" WsHostRopsten = "wss://api.stage.dydx.exchange/v3/ws" )
const ( NetworkIdMainnet = 1 NetworkIdRopsten = 3 )
const ( Resolution1D = "1DAY" Resolution4HOURS = "4HOURS" Resolution1HOUR = "1HOUR" Resolution30MINS = "30MINS" Resolution15MINS = "15MINS" Resolution5MINS = "5MINS" Resolution1MIN = "1MIN" )
const ( PositionStatusOpen = "OPEN" PositionStatusClosed = "CLOSED" PositionStatusLiquidated = "LIQUIDATED" )
const ( AccountChannel = "v3_accounts" MarketsChannel = "v3_markets" OrderbookChannel = "v3_orderbook" TradesChannel = "v3_trades" )
const ( ChannelResponseTypeSubscribe = "subscribed" ChannelResponseTypeUnsubscribe = "unsubscribed" // unused ChannelResponseTypeError = "error" ChannelResponseTypeConnected = "connected" ChannelResponseTypeChannelData = "channel_data" )
Variables ¶
This section is empty.
Functions ¶
func GetAccountIdFromEth ¶
func GetIsoDateStr ¶
func NewEcdsaPrivateKeySigner ¶
func NewEcdsaPrivateKeySigner(key *ecdsa.PrivateKey) *ecdsaPrivateKeySigner
NewEcdsaPrivateKeySigner converts an *ecdsa.PrivateKey into a signer to EthSignTypedData
func SetClientEndpoint ¶
func SetClientEndpoint(isMainnet bool) clientOption
func SetClientTimeout ¶
Types ¶
type Account ¶
type Account struct { PositionId int64 `json:"positionId,string"` ID string `json:"id"` StarkKey string `json:"starkKey"` Equity Decimal `json:"equity"` FreeCollateral Decimal `json:"freeCollateral"` QuoteBalance Decimal `json:"quoteBalance"` PendingDeposits string `json:"pendingDeposits"` PendingWithdrawals string `json:"pendingWithdrawals"` AccountNumber JsonInt `json:"accountNumber"` OpenPositions map[string]Position `json:"openPositions,omitempty"` CreatedAt time.Time `json:"createdAt"` }
type AccountChannelResponse ¶
type AccountChannelResponse = ChannelResponse[AccountChannelResponseContents]
type AccountChannelResponseContents ¶
type AccountChannelResponseContents struct { Account *Account `json:"account,omitempty"` Orders []*Order `json:"orders,omitempty"` Fills []*Fill `json:"fills,omitempty"` Accounts []*Account `json:"accounts,omitempty"` Transfers []*Transfer `json:"transfers,omitempty"` Positions []*Position `json:"positions,omitempty"` }
type AccountInfoByMarket ¶
type AccountInfoByMarket struct { Market string // OpenPosition currently active OpenPosition *Position // All Positions AllPositions []*Position // ActiveOrders ActiveOrders map[string]*Order // ClosedOrders ClosedOrders map[string]*Order // Fills Fills map[string]*FillList }
AccountInfoByMarket contains market specific information.
func NewAccountInfoByMarket ¶
func NewAccountInfoByMarket(market string) *AccountInfoByMarket
func (*AccountInfoByMarket) AddFill ¶
func (info *AccountInfoByMarket) AddFill(fill *Fill)
func (*AccountInfoByMarket) AddOrder ¶
func (info *AccountInfoByMarket) AddOrder(order *Order)
func (*AccountInfoByMarket) AddPosition ¶
func (info *AccountInfoByMarket) AddPosition(position *Position)
type AccountProcessor ¶
type AccountProcessor struct { Account *Account Info map[string]*AccountInfoByMarket // contains filtered or unexported fields }
AccountProcessor can be used to process Account Channel Updates
func NewAccountProcessor ¶
func NewAccountProcessor() *AccountProcessor
func (*AccountProcessor) ProcessChannelResponse ¶
func (ap *AccountProcessor) ProcessChannelResponse(resp *AccountChannelResponse)
ProcessChannelResponse processes the channel responses in sequence.
type AccountResponse ¶
type AccountResponse struct {
Account Account `json:"account"`
}
type AccountsResponse ¶
type AccountsResponse struct {
Accounts []*Account `json:"accounts"`
}
type ActiveOrder ¶
type ActiveOrdersResponse ¶
type ActiveOrdersResponse struct {
Orders []ActiveOrder `json:"orders"`
}
type ApiKey ¶
type ApiKey struct { Secret string `json:"secret"` Key string `json:"key"` Passphrase string `json:"passphrase"` }
ApiKey is the format from browser's local storage. Below are from browser but not necessary
- WalletAddress string `json:"walletAddress"` - LegacySigning bool `json:"legacySigning"` - WalletType string `json:"walletType"`
func RecoverDefaultApiKeyCredentials ¶
func RecoverDefaultApiKeyCredentials(signer SignTypedData, isMainnet bool) (*ApiKey, error)
RecoverDefaultApiKeyCredentials recovers the default credentials.
Implementation is a carbon-copy of the code in python version of official dydx client: https://github.com/dydxprotocol/dydx-v3-python/blob/914fc66e542d82080702e03f6ad078ca2901bb46/dydx3/modules/onboarding.py#L147-L184
type Asks ¶
type Asks struct {
// contains filtered or unexported fields
}
Asks side of the book.
func (*Asks) Pop ¶
func (m *Asks) Pop() *OrderbookOrder
func (*Asks) Push ¶
func (m *Asks) Push(order *OrderbookOrder)
type Bids ¶
type Bids struct {
// contains filtered or unexported fields
}
Bids side of the book.
func (*Bids) Pop ¶
func (m *Bids) Pop() *OrderbookOrder
func (*Bids) Push ¶
func (m *Bids) Push(order *OrderbookOrder)
type CancelActiveOrdersParam ¶
type CancelActiveOrdersResponse ¶
type CancelActiveOrdersResponse struct {
CancelOrders []ActiveOrder `json:"cancelOrders"`
}
type CancelOrderResponse ¶
type CancelOrderResponse struct {
CancelOrder Order `json:"cancelOrder"`
}
type CancelOrdersParam ¶
type CancelOrdersParam struct {
Market string `url:"market,omitempty"`
}
type CancelOrdersResponse ¶
type CancelOrdersResponse struct {
CancelOrders []Order `json:"cancelOrders"`
}
type CancelReason ¶
type CancelReason string
CancelReason is the reason for order cancellation. See here https://docs.dydx.exchange/#get-orders (section "Cancel Reasons")
const ( CancelReasonUndercollateralized CancelReason = "UNDERCOLLATERALIZED" // Order would have led to an undercollateralized state for the user. CancelReasonExpired CancelReason = "EXPIRED" // Order expired. CancelReasonUserCancelled CancelReason = "USER_CANCELED" // Order was canceled by the user. CancelReasonSelfTrade CancelReason = "SELF_TRADE" // Order would have resulted in a self trade for the user. CancelReasonFailed CancelReason = "FAILED" // An internal issue caused the order to be canceled. CancelReasonCouldNotFill CancelReason = "COULD_NOT_FILL" // A FOK or IOC order could not be fully filled. CancelReasonPostOnlyWouldCross CancelReason = "POST_ONLY_WOULD_CROSS" // A post-only order would cross the orderbook. )
func GetCancelReason ¶
func GetCancelReason(input string) (CancelReason, error)
func (CancelReason) MarshalJSON ¶
func (ot CancelReason) MarshalJSON() ([]byte, error)
func (*CancelReason) UnmarshalJSON ¶
func (ot *CancelReason) UnmarshalJSON(input []byte) error
type Candle ¶
type Candle struct { Market string `json:"market"` Resolution string `json:"resolution"` Low string `json:"low"` High string `json:"high"` Open string `json:"open"` Close string `json:"close"` BaseTokenVolume string `json:"baseTokenVolume"` Trades string `json:"trades"` UsdVolume string `json:"usdVolume"` StartingOpenInterest string `json:"startingOpenInterest"` StartedAt time.Time `json:"startedAt"` UpdatedAt time.Time `json:"updatedAt"` }
type CandlesParam ¶
type CandlesResponse ¶
type CandlesResponse struct {
Candles []Candle `json:"candles"`
}
type ChannelResponse ¶
type ChannelResponse[TContents any] struct { ChannelResponseHeader Contents *TContents `json:"contents,omitempty"` }
type ChannelResponseHeader ¶
type ChannelResponseHeader struct { // Type of the response (see ChannelResponseType*) Type string `json:"type"` // Channel Channel string `json:"channel"` // ConnectionId ConnectionID string `json:"connection_id,omitempty"` // MessageId MessageID int `json:"message_id,omitempty"` // Message contains the error message if there is an error Message string `json:"message,omitempty"` // Id is the subscribed to id, such as account, market (BTC-USD) etc. Id string `json:"id,omitempty"` }
ChannelResponseHeader contains all the common information in the channel response.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a struct holding the information necessary to connect to dydx.
func NewClient ¶
func NewClient(starkKey *StarkKey, apiKey *ApiKey, ethAddress string, isMainnet bool, clientOptions ...clientOption) (*Client, error)
NewClient creates a new Client, but doesn't connect to the dydx.exchange yet. If only public method is needed, keys and eth addersse can be empty/nil.
func (*Client) CancelActiveOrders ¶
func (c *Client) CancelActiveOrders(ctx context.Context, params *CancelActiveOrdersParam) (*CancelActiveOrdersResponse, error)
CancelActiveOrders cancels mulitple orders at the same time, however, it utilizes the active order api. It implements https://docs.dydx.exchange/?json#cancel-active-orders
func (*Client) CancelOrder ¶
CancelOrder
func (*Client) CancelOrders ¶
func (c *Client) CancelOrders(ctx context.Context, params *CancelOrdersParam) (*CancelOrdersResponse, error)
CancelOrders cancels multiple orders at the same time. It implements https://docs.dydx.exchange/?json#cancel-orders
func (*Client) CreateUser ¶
func (c *Client) CreateUser(ctx context.Context, signer SignTypedData, param *CreateUserParam) (*CreateUserResponse, error)
CreateUser creates a new user on dydx. See here: https://docs.dydx.exchange/#onboarding Note this is re-produced from python version https://github.com/dydxprotocol/dydx-v3-python/blob/914fc66e542d82080702e03f6ad078ca2901bb46/dydx3/modules/onboarding.py#L32-L112
Example ¶
An example that generate a new private key for ethereum network, use the default stark key and api credentials, then create the user on the testnet, and request token airdrops.
package main import ( "context" "fmt" "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/fardream/go-dydx" ) const createUserIsMainnet = false // An example that generate a new private key for ethereum network, // use the default stark key and api credentials, then create the user on the // testnet, and request token airdrops. func main() { // create private key on the ethereum network privateKey, err := crypto.GenerateKey() if err != nil { panic(err) } fmt.Printf("testing private key: %s\n", hexutil.Encode(crypto.FromECDSA(privateKey))) // public key address ethAddress := crypto.PubkeyToAddress(privateKey.PublicKey) fmt.Printf("testing public key: %s\n", ethAddress.String()) // signer signer := dydx.NewEcdsaPrivateKeySigner(privateKey) // stark key starkKey, err := dydx.DeriveStarkKey(signer, createUserIsMainnet) if err != nil { panic(err) } // api key apiKey, err := dydx.RecoverDefaultApiKeyCredentials(signer, false) if err != nil { panic(err) } // create a new client client, err := dydx.NewClient(starkKey, apiKey, ethAddress.String(), createUserIsMainnet) if err != nil { panic(err) } // create user on the dydx resp, err := client.CreateUser(context.Background(), signer, nil) if err != nil { panic(err) } else { spew.Dump(resp) } // request airdrop _, err = client.RequestTestnetTokens(context.Background()) if err != nil { panic(err) } }
Output:
func (*Client) GetAccount ¶
GetAccount with a specific id, implements https://docs.dydx.exchange/#get-account
func (*Client) GetAccounts ¶
func (c *Client) GetAccounts(ctx context.Context) (*AccountsResponse, error)
GetAccounts implements https://docs.dydx.exchange/#get-accounts, it gets all accounts
func (*Client) GetActiveOrders ¶
func (c *Client) GetActiveOrders(ctx context.Context, params *QueryActiveOrdersParam) (*ActiveOrdersResponse, error)
GetActiveOrders implements https://docs.dydx.exchange/#cancel-active-orders
func (*Client) GetCandles ¶
func (c *Client) GetCandles(ctx context.Context, params *CandlesParam) (*CandlesResponse, error)
func (*Client) GetFills ¶
func (c *Client) GetFills(ctx context.Context, params *FillsParam) (*FillsResponse, error)
GetFills implements https://docs.dydx.exchange/#get-fills
func (*Client) GetFundingPayments ¶
func (c *Client) GetFundingPayments(ctx context.Context, params *FundingPaymentsParam) (*FundingPaymentsResponse, error)
func (*Client) GetHistoricalFunding ¶
func (c *Client) GetHistoricalFunding(ctx context.Context, params *HistoricalFundingsParam) (*HistoricalFundingsResponse, error)
func (*Client) GetHistoricalPnL ¶
func (c *Client) GetHistoricalPnL(ctx context.Context, params *HistoricalPnLParam) (*HistoricalPnLResponse, error)
func (*Client) GetMarkets ¶
func (c *Client) GetMarkets(ctx context.Context) (*MarketsResponse, error)
func (*Client) GetOrderByClientId ¶
func (*Client) GetOrderById ¶
func (*Client) GetOrderbook ¶
Example ¶
Get the orderbook for BTC-USD
package main import ( "context" "time" "github.com/davecgh/go-spew/spew" "github.com/fardream/go-dydx" ) var _ = "keep" // Get the orderbook for BTC-USD func main() { // No private key necesary client, _ := dydx.NewClient(nil, nil, "", false) // Set 15 minutes timeout ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() spew.Dump(getOrPanic(client.GetOrderbook(ctx, "BTC-USD"))) }
Output:
func (*Client) GetOrders ¶
func (c *Client) GetOrders(ctx context.Context, params *OrderQueryParam) (*OrdersResponse, error)
func (*Client) GetPositions ¶
func (c *Client) GetPositions(ctx context.Context, params *PositionParams) (*PositionResponse, error)
func (*Client) GetTrades ¶
func (c *Client) GetTrades(ctx context.Context, params *TradesParam) (*TradesResponse, error)
func (*Client) GetTradingRewards ¶
func (*Client) NewOrder ¶
func (c *Client) NewOrder(ctx context.Context, order *CreateOrderRequest, positionId int64) (*CreateOrderResponse, error)
Example ¶
Place a new order for BTC at the price of 35000
package main import ( "context" "crypto/rand" "math/big" "time" "github.com/davecgh/go-spew/spew" "github.com/fardream/go-dydx" ) func getOrPanic[T any](input T, err error) T { if err != nil { panic(err) } return input } // Place a new order for BTC at the price of 35000 func main() { const ethAddress = "<eth address>" client, err := dydx.NewClient( dydx.NewStarkKey( "<stark pubkey>", "<stark pubkey y coordinate>", "<stark private key>"), dydx.NewApiKey( "<api key>", "<api passphrase>", "<api secret>"), ethAddress, false) if err != nil { panic(err) } // generate a big id id, _ := rand.Int(rand.Reader, big.NewInt(10000)) id.Add(id, big.NewInt(1000000)) // create a new order order := dydx.NewCreateOrderRequest("BTC-USD", dydx.OrderSideSell, dydx.OrderTypeLimit, getOrPanic(dydx.NewDecimalFromString("0.001")), getOrPanic(dydx.NewDecimalFromString("35000")), id.String(), "", time.Now().Add(5*time.Minute), getOrPanic(dydx.NewDecimalFromString("0.125")), false) // place the order r := getOrPanic(client.NewOrder(context.Background(), order, 62681)) spew.Dump(r) time.Sleep(5 * time.Second) // get the order spew.Dump(getOrPanic( client.GetOrderById(context.Background(), r.Order.ID)).Order) time.Sleep(2 * time.Second) // cancel all active orders spew.Dump(client.CancelActiveOrders(context.Background(), &dydx.CancelActiveOrdersParam{Market: "BTC-USD"})) time.Sleep(2 * time.Second) // get your positions spew.Dump(getOrPanic(client.GetPositions(context.Background(), &dydx.PositionParams{Market: "BTC-USD"}))) time.Sleep(2 * time.Second) // get the active orders spew.Dump(getOrPanic(client.GetActiveOrders(context.Background(), &dydx.QueryActiveOrdersParam{Market: "BTC-USD"}))) }
Output:
func (*Client) RequestTestnetTokens ¶
func (c *Client) RequestTestnetTokens(ctx context.Context) (*RequestTestnetTokensResponse, error)
RequestTestnetTokens implements https://docs.dydx.exchange/#request-testnet-tokens Obtain testnet tokens (USDC)
func (*Client) SubscribeAccount ¶
func (c *Client) SubscribeAccount(ctx context.Context, accountNumber int, outputChan chan<- *AccountChannelResponse) error
SubscribeAccount gets the accounts update It will feed the account update in sequence into the channel provided. It returns after the subscription is done and closed.
func (*Client) SubscribeMarkets ¶
func (c *Client) SubscribeMarkets(ctx context.Context, outputChan chan<- *MarketsChannelResponse) error
func (*Client) SubscribeOrderbook ¶
func (*Client) SubscribeTrades ¶
type CreateOrderRequest ¶
type CreateOrderRequest struct { Signature string `json:"signature"` Expiration time.Time `json:"expiration"` Market string `json:"market"` Side OrderSide `json:"side"` Type OrderType `json:"type"` Size *Decimal `json:"size"` Price *Decimal `json:"price,omitempty"` ClientId string `json:"clientId"` TimeInForce TimeInForce `json:"timeInForce"` LimitFee *Decimal `json:"limitFee"` CancelId string `json:"cancelId,omitempty"` TriggerPrice string `json:"triggerPrice,omitempty"` TrailingPercent string `json:"trailingPercent,omitempty"` PostOnly bool `json:"postOnly"` }
CreateOrderRequest is the post payload to create a new order https://docs.dydx.exchange/?json#create-a-new-order
func NewCreateOrderRequest ¶
func NewCreateOrderRequest(market string, side OrderSide, order_type OrderType, size *Decimal, price *Decimal, clientid string, tif TimeInForce, expiration time.Time, limitfee *Decimal, postonly bool) *CreateOrderRequest
NewCreateOrderRequest
type CreateOrderResponse ¶
type CreateOrderResponse struct {
Order *Order `json:"order,omitempty"`
}
type CreateUserParam ¶
type CreateUserParam struct { StarkPublicKey string `json:"starkKey"` StarkPublicKeyYCoordinate string `json:"starkKeyYCoordinate"` // ethereumAddress, even though listed on the documentation, is not part of the request. EthereumAddress string `json:"-"` ReferredByAffiliateLink string `json:"referredByAffiliateLink,omitempty"` Country string `json:"country,omitempty"` }
CreateUserParam contains the parameters to create a new user. Note ethereumAddress is actually not part of the api according to python implementation: https://github.com/dydxprotocol/dydx-v3-python/blob/914fc66e542d82080702e03f6ad078ca2901bb46/dydx3/modules/onboarding.py#L103-L111
type CreateUserResponse ¶
type Decimal ¶
func NewDecimalFromString ¶
type DydxError ¶
DydxError represents a successful HTTP request with status code >= 400 This can indicates errors like failed authentication with api key or bad parameters.
type FastWithdrawalParam ¶
type FastWithdrawalParam struct { ClientID string `json:"clientId"` ToAddress string `json:"toAddress"` CreditAsset string `json:"creditAsset"` CreditAmount string `json:"creditAmount"` DebitAmount string `json:"debitAmount"` LpPositionId string `json:"lpPositionId"` Expiration string `json:"expiration"` Signature string `json:"signature"` }
type Fill ¶
type Fill struct { ID string `json:"id"` Side OrderSide `json:"side"` Liquidity string `json:"liquidity"` Type OrderType `json:"type"` Market string `json:"market"` OrderID string `json:"orderId"` Price Decimal `json:"price"` Size Decimal `json:"size"` Fee Decimal `json:"fee"` CreatedAt time.Time `json:"createdAt"` }
type FillsParam ¶
type FillsParam struct { Market string `json:"market,omitempty"` OrderId string `json:"order_id,omitempty"` Limit string `json:"limit,omitempty"` CreatedBeforeOrAt string `json:"createdBeforeOrAt,omitempty"` }
FillsParam: https://docs.dydx.exchange/#get-fills
type FillsResponse ¶
type FillsResponse struct {
Fills []*Fill `json:"fills"`
}
type FundingPayment ¶
type FundingPaymentsParam ¶
type FundingPaymentsResponse ¶
type FundingPaymentsResponse struct {
FundingPayments []FundingPayment `json:"fundingPayments"`
}
type HistoricalFunding ¶
type HistoricalFundingsParam ¶
type HistoricalFundingsResponse ¶
type HistoricalFundingsResponse struct {
HistoricalFundings []HistoricalFunding `json:"historicalFunding"`
}
type HistoricalPnL ¶
type HistoricalPnLParam ¶
type HistoricalPnLResponse ¶
type HistoricalPnLResponse struct {
HistoricalPnLs []HistoricalPnL `json:"historicalPnl"`
}
type JsonInt ¶
type JsonInt int
JsonInt is an int, but can be json-unmarshaled from either int or string, marshalled into string.
func (JsonInt) MarshalJSON ¶
MarshalJSON converts JsonInt into string and marshal that.
func (*JsonInt) UnmarshalJSON ¶
type Logger ¶
type Logger interface { Debugf(string, ...any) Infof(string, ...any) Warnf(string, ...any) Errorf(string, ...any) Fatalf(string, ...any) }
Logger defines an interface to log. By default this is uber's zap.
func SetupLogger ¶
type Market ¶
type Market struct { Market string `json:"market,omitempty"` BaseAsset string `json:"baseAsset,omitempty"` QuoteAsset string `json:"quoteAsset,omitempty"` StepSize *Decimal `json:"stepSize,omitempty"` TickSize *Decimal `json:"tickSize,omitempty"` IndexPrice *Decimal `json:"indexPrice,omitempty"` OraclePrice *Decimal `json:"oraclePrice,omitempty"` PriceChange24H *Decimal `json:"priceChange24H,omitempty"` NextFundingRate *Decimal `json:"nextFundingRate,omitempty"` MinOrderSize *Decimal `json:"minOrderSize,omitempty"` Type string `json:"type,omitempty"` InitialMarginFraction *Decimal `json:"initialMarginFraction,omitempty"` MaintenanceMarginFraction *Decimal `json:"maintenanceMarginFraction,omitempty"` BaselinePositionSize *Decimal `json:"baselinePositionSize,omitempty"` IncrementalPositionSize *Decimal `json:"incrementalPositionSize,omitempty"` IncrementalInitialMarginFraction *Decimal `json:"incrementalInitialMarginFraction,omitempty"` Volume24H *Decimal `json:"volume24H,omitempty"` Trades24H *Decimal `json:"trades24H,omitempty"` OpenInterest *Decimal `json:"openInterest,omitempty"` MaxPositionSize *Decimal `json:"maxPositionSize,omitempty"` AssetResolution string `json:"assetResolution,omitempty"` SyntheticAssetID string `json:"syntheticAssetId,omitempty"` Status string `json:"status,omitempty"` NextFundingAt *time.Time `json:"nextFundingAt,omitempty"` }
type MarketsChannelResponse ¶
type MarketsChannelResponse = ChannelResponse[MarketsChannelResponseContents]
type MarketsResponse ¶
Market contains the meta data for a market. https://docs.dydx.exchange/#get-markets
type Order ¶
type Order struct { ID string `json:"id"` ClientID string `json:"clientId"` AccountID string `json:"accountId"` Market string `json:"market"` Side OrderSide `json:"side"` Price Decimal `json:"price"` TriggerPrice *Decimal `json:"triggerPrice,omitempty"` TrailingPercent *Decimal `json:"trailingPercent,omitempty"` Size Decimal `json:"size"` RemainingSize Decimal `json:"remainingSize"` Type OrderType `json:"type"` UnfillableAt *time.Time `json:"unfillableAt,omitempty"` Status OrderStatus `json:"status"` TimeInForce TimeInForce `json:"timeInForce"` CancelReason *CancelReason `json:"cancelReason,omitempty"` PostOnly bool `json:"postOnly"` CreatedAt time.Time `json:"createdAt"` ExpiresAt time.Time `json:"expiresAt"` }
Order is the information returned from dydx
type OrderQueryParam ¶
type OrderQueryParam struct { Limit int `url:"limit,omitempty"` Market string `url:"market,omitempty"` Status string `url:"status,omitempty"` Type string `url:"type,omitempty"` Side string `url:"side,omitempty"` CreatedBeforeOrAt string `url:"createdAt,omitempty"` ReturnLatestOrders string `url:"returnLatestOrders,omitempty"` }
type OrderResponse ¶
type OrderResponse struct {
Order Order `json:"order"`
}
type OrderSide ¶
type OrderSide string
func GetOrderSide ¶
func (OrderSide) MarshalJSON ¶
func (*OrderSide) UnmarshalJSON ¶
type OrderStatus ¶
type OrderStatus string
const ( OrderStatusPending OrderStatus = "PENDING" OrderStatusOpen OrderStatus = "OPEN" OrderStatusFilled OrderStatus = "FILLED" OrderStatusCanceled OrderStatus = "CANCELED" OrderStatusUntriggered OrderStatus = "UNTRIGGERED" )
func GetOrderStatus ¶
func GetOrderStatus(input string) (OrderStatus, error)
func (OrderStatus) MarshalJSON ¶
func (ot OrderStatus) MarshalJSON() ([]byte, error)
func (*OrderStatus) UnmarshalJSON ¶
func (ot *OrderStatus) UnmarshalJSON(input []byte) error
type OrderType ¶
type OrderType string
OrderType indicates if the order is market, limit, stop, trailing stop or taking profit. See https://docs.dydx.exchange/#order-types
func GetOrderType ¶
func (OrderType) MarshalJSON ¶
func (*OrderType) UnmarshalJSON ¶
type OrderbookChannelResponse ¶
type OrderbookChannelResponse = ChannelResponse[OrderbookChannelResponseContents]
type OrderbookChannelResponseContents ¶
type OrderbookChannelResponseContents = OrderbookResponse
type OrderbookOrder ¶
type OrderbookOrder struct { Price *Decimal `json:"price"` Size *Decimal `json:"size"` Offset *int64 `json:"offset,omitempty"` PriceString string `json:"-"` }
OrderbookOrder is an entry on the order book, it only contains price, quantity, and potentially an offset.
func (*OrderbookOrder) IsOtherNewerOffset ¶
func (o *OrderbookOrder) IsOtherNewerOffset(other *OrderbookOrder) bool
func (*OrderbookOrder) UnmarshalJSON ¶
func (p *OrderbookOrder) UnmarshalJSON(data []byte) error
UnmarshalJSON parse the content into an orderbook order. Right now the process first tries to parse the data with []string, if that failed, parse it with map[string]string
type OrderbookProcessor ¶
type OrderbookProcessor struct { Market string Bids Asks Data []*OrderbookChannelResponse // contains filtered or unexported fields }
OrderbookProcessor maintains the state of the order book
For now the bids and asks are maintained as a heap and it is easy to return top of the book. There doesn't look to be a difficult way to implement this as list as always sorted.
func NewOrderbookProcessor ¶
func NewOrderbookProcessor(market string, dropData bool) *OrderbookProcessor
NewOrderbookProcessor creates a orderbook processor. - set `dropData` to true to drop the updates.
func (*OrderbookProcessor) BookTop ¶
func (ob *OrderbookProcessor) BookTop() (*OrderbookOrder, *OrderbookOrder)
BookTop returns the best bid and ask of the book. nil if the side of the book is empty.
func (*OrderbookProcessor) Process ¶
func (ob *OrderbookProcessor) Process(resp *OrderbookChannelResponse)
Process a update from the orderbook
type OrderbookResponse ¶
type OrderbookResponse struct { Offset *int64 `json:"offset,string,omitempty"` Bids []*OrderbookOrder `json:"bids"` Asks []*OrderbookOrder `json:"asks"` }
OrderbookResponse is from https://docs.dydx.exchange/?json#get-orderbook
type OrdersResponse ¶
type OrdersResponse struct {
Orders []Order `json:"orders"`
}
type Position ¶
type Position struct { Market string `json:"market,omitempty"` Status string `json:"status,omitempty"` Side string `json:"side,omitempty"` Size Decimal `json:"size,omitempty"` MaxSize Decimal `json:"maxSize,omitempty"` EntryPrice Decimal `json:"entryPrice,omitempty"` ExitPrice *Decimal `json:"exitPrice,omitempty"` UnrealizedPnl Decimal `json:"unrealizedPnl,omitempty"` RealizedPnl Decimal `json:"realizedPnl,omitempty"` CreatedAt time.Time `json:"createdAt,omitempty"` ClosedAt *time.Time `json:"closedAt,omitempty"` NetFunding Decimal `json:"netFunding,omitempty"` SumOpen Decimal `json:"sumOpen,omitempty"` SumClose Decimal `json:"sumClose,omitempty"` }
type PositionParams ¶
type PositionResponse ¶
type PositionResponse struct {
Positions []Position `json:"positions"`
}
type QueryActiveOrdersParam ¶
type RequestTestnetTokensResponse ¶
type RequestTestnetTokensResponse struct {
*Transfer `json:"transfer,omitempty"`
}
type SignTypedData ¶
SignTypedData is an interface to sign apitypes.TypedData on ethereum network. For a reference implementation, see: https://pkg.go.dev/github.com/ethereum/go-ethereum@v1.10.18/signer/core#SignerAPI.SignTypedData
type StarkKey ¶
type StarkKey struct { PublicKey string `json:"publicKey"` PublicKeyYCoordinate string `json:"publicKeyYCoordinate"` PrivateKey string `json:"privateKey"` }
StarkKey is the private key on the Stark L2. Below fields are from the browser cache but unused. - WalletAddress string `json:"walletAddress"` - LegacySigning bool `json:"legacySigning"` - WalletType string `json:"walletType"`
func DeriveStarkKey ¶
func DeriveStarkKey(signer SignTypedData, isMainnet bool) (*StarkKey, error)
DeriveStarkKey gets the default deterministic stark key.
Derived from the python implementation of official dydx client: https://github.com/dydxprotocol/dydx-v3-python/blob/914fc66e542d82080702e03f6ad078ca2901bb46/dydx3/modules/onboarding.py#L116-L145
- sign the typed data for key derivation.
- append 0 to the signature.
- crypto.keccak hash the signature bytes. in python implementation, it convert the siganture to a big int. and the resulting big int is crypto.keccak hashed as an uint256 - note uint256 is 32 bytes. however, in reality, it takes the whole 66 bytes and hashes it.
- convert the resulted signature bytes into a big int.
- right shift the big int by 5 - this is our private key.
- `starkex.PrivateKeyToEcPointOnStarkCurv` to get the x and y big ints.
- convert private key, x, y into hex encoded strings (without the 0x).
Function requires a signer to sign typed data
Example ¶
package main import ( "fmt" "log" "github.com/ethereum/go-ethereum/crypto" "github.com/fardream/go-dydx" ) var _ = "keep" func main() { key, err := crypto.GenerateKey() if err != nil { log.Fatalf("failed to generate an ethereum key: %#v", err) } stark_key, err := dydx.DeriveStarkKey(dydx.NewEcdsaPrivateKeySigner(key), false) if err != nil { log.Fatalf("failed to derivate stark key: %#v", err) } fmt.Println(stark_key) }
Output:
func NewStarkKey ¶
type TimeInForce ¶
type TimeInForce string
const ( TimeInForceGtt TimeInForce = "GTT" // Good til time TimeInForceFok TimeInForce = "FOK" // Fill or Kill TimeInForceIoc TimeInForce = "IOC" // Immediate or Cancel )
func GetTimeInForce ¶
func GetTimeInForce(input string) (TimeInForce, error)
func (TimeInForce) MarshalJSON ¶
func (ot TimeInForce) MarshalJSON() ([]byte, error)
func (*TimeInForce) UnmarshalJSON ¶
func (ot *TimeInForce) UnmarshalJSON(input []byte) error
type TradesChannelResponse ¶
type TradesChannelResponse = ChannelResponse[TradesChannelResponseContents]
type TradesChannelResponseContents ¶
type TradesChannelResponseContents = TradesResponse
type TradesParam ¶
type TradesResponse ¶
type TradesResponse struct {
Trades []Trade `json:"trades"`
}
type TradingReward ¶
type TradingReward struct { Epoch int `json:"epoch"` EpochStart time.Time `json:"epochStart"` EpochEnd time.Time `json:"epochEnd"` Fees struct { FeesPaid string `json:"feesPaid"` TotalFeesPaid string `json:"totalFeesPaid"` } `json:"fees"` OpenInterest struct { AverageOpenInterest string `json:"averageOpenInterest"` TotalAverageOpenInterest string `json:"totalAverageOpenInterest"` } `json:"openInterest"` StakedDYDX struct { AverageStakedDYDX string `json:"averageStakedDYDX"` AverageStakedDYDXWithFloor string `json:"averageStakedDYDXWithFloor"` TotalAverageStakedDYDX string `json:"totalAverageStakedDYDX"` } `json:"stakedDYDX"` Weight struct { Weight string `json:"weight"` TotalWeight string `json:"totalWeight"` } `json:"weight"` TotalRewards string `json:"totalRewards"` EstimatedRewards string `json:"estimatedRewards"` }
type TradingRewardsResponse ¶
type TradingRewardsResponse TradingReward
type Transfer ¶
type Transfer struct { Type string `json:"type"` ID string `json:"id"` ClientID string `json:"clientId"` CreditAmount *Decimal `json:"creditAmount,omitempty"` CreditAsset string `json:"creditAsset,omitempty"` DebitAmount *Decimal `json:"debitAmount,omitempty"` DebitAsset string `json:"debitAsset,omitempty"` FromAddress string `json:"fromAddress"` Status string `json:"status"` ToAddress string `json:"toAddress,omitempty"` TransactionHash string `json:"transactionHash,omitempty"` ConfirmedAt *time.Time `json:"confirmedAt,omitempty"` CreatedAt time.Time `json:"createdAt"` }
type TransfersParam ¶
type TransfersParam struct{}
type TransfersResponse ¶
type TransfersResponse struct {
Transfers []Transfer `json:"transfers"`
}
type User ¶
type User struct { PublicID string `json:"publicId"` EthereumAddress string `json:"ethereumAddress"` IsRegistered bool `json:"isRegistered"` Email string `json:"email"` Username string `json:"username"` UserData struct { WalletType string `json:"walletType"` Preferences struct { SaveOrderAmount bool `json:"saveOrderAmount"` UserTradeOptions struct { Limit struct { PostOnlyChecked bool `json:"postOnlyChecked"` GoodTilTimeInput string `json:"goodTilTimeInput"` GoodTilTimeTimescale string `json:"goodTilTimeTimescale"` SelectedTimeInForceOption string `json:"selectedTimeInForceOption"` } `json:"LIMIT"` Market struct { PostOnlyChecked bool `json:"postOnlyChecked"` GoodTilTimeInput string `json:"goodTilTimeInput"` GoodTilTimeTimescale string `json:"goodTilTimeTimescale"` SelectedTimeInForceOption string `json:"selectedTimeInForceOption"` } `json:"MARKET"` StopLimit struct { PostOnlyChecked bool `json:"postOnlyChecked"` GoodTilTimeInput string `json:"goodTilTimeInput"` GoodTilTimeTimescale string `json:"goodTilTimeTimescale"` SelectedTimeInForceOption string `json:"selectedTimeInForceOption"` } `json:"STOP_LIMIT"` TakeProfit struct { PostOnlyChecked bool `json:"postOnlyChecked"` GoodTilTimeInput string `json:"goodTilTimeInput"` GoodTilTimeTimescale string `json:"goodTilTimeTimescale"` SelectedTimeInForceOption string `json:"selectedTimeInForceOption"` } `json:"TAKE_PROFIT"` LastPlacedTradeType string `json:"lastPlacedTradeType"` } `json:"userTradeOptions"` PopUpNotifications bool `json:"popUpNotifications"` OrderbookAnimations bool `json:"orderbookAnimations"` OneTimeNotifications []string `json:"oneTimeNotifications"` LeaguesCurrentStartDate time.Time `json:"leaguesCurrentStartDate"` } `json:"preferences"` Notifications struct { Trade struct { Email bool `json:"email"` } `json:"trade"` Deposit struct { Email bool `json:"email"` } `json:"deposit"` Transfer struct { Email bool `json:"email"` } `json:"transfer"` Marketing struct { Email bool `json:"email"` } `json:"marketing"` Withdrawal struct { Email bool `json:"email"` } `json:"withdrawal"` Liquidation struct { Email bool `json:"email"` } `json:"liquidation"` FundingPayment struct { Email bool `json:"email"` } `json:"funding_payment"` } `json:"notifications"` StarredMarkets []interface{} `json:"starredMarkets"` } `json:"userData"` MakerFeeRate string `json:"makerFeeRate"` TakerFeeRate string `json:"takerFeeRate"` MakerVolume30D string `json:"makerVolume30D"` TakerVolume30D string `json:"takerVolume30D"` Fees30D string `json:"fees30D"` ReferredByAffiliateLink string `json:"referredByAffiliateLink"` IsSharingUsername bool `json:"isSharingUsername"` IsSharingAddress bool `json:"isSharingAddress"` DydxTokenBalance string `json:"dydxTokenBalance"` StakedDydxTokenBalance string `json:"stakedDydxTokenBalance"` ActiveStakedDydxTokenBalance string `json:"activeStakedDydxTokenBalance"` IsEmailVerified bool `json:"isEmailVerified"` Country any `json:"country"` HedgiesHeld []any `json:"hedgiesHeld"` }
type UsersResponse ¶
type UsersResponse struct {
User User `json:"user"`
}
type WithdrawResponse ¶
type WithdrawResponse struct {
Withdrawal []Withdrawal `json:"withdrawal"`
}
type Withdrawal ¶
type Withdrawal = Transfer
Withdrawal is one type of transfer: https://docs.dydx.exchange/#create-withdrawal
Source Files ¶
- account.go
- account_channel.go
- account_processor.go
- active_order.go
- api_key.go
- cancel_orders.go
- cancel_reason.go
- candles.go
- client.go
- constants.go
- create_order.go
- decimal.go
- derive_keys.go
- doc.go
- fill.go
- funding_payments.go
- historical_fundings.go
- historical_pnl.go
- json_int.go
- log.go
- market.go
- markets_channel.go
- order.go
- order_side.go
- order_status.go
- order_type.go
- orderbook.go
- orderbook_channel.go
- orderbook_processor.go
- position.go
- rpc.go
- sign_typed_data.go
- stark_key.go
- testnet_tokens.go
- time_in_force.go
- trades.go
- trades_channel.go
- trading_rewards.go
- transfer.go
- user.go
- util.go
- websocket.go
- withdrawal.go
Directories ¶
Path | Synopsis |
---|---|
dydx-cli is a command line interface for dydx.exchange
|
dydx-cli is a command line interface for dydx.exchange |
dydx-replay-orderbook is a cli to replay orderbook updates from dydx websocket subscription.
|
dydx-replay-orderbook is a cli to replay orderbook updates from dydx websocket subscription. |
Package heap provides heap operations for any type that implements heap.Interface.
|
Package heap provides heap operations for any type that implements heap.Interface. |
starkex provides signing and other algorithms for starkex (https://starkware.co/starkex/).
|
starkex provides signing and other algorithms for starkex (https://starkware.co/starkex/). |