From 691251169d12502be4cb775d4f649d8ac0480961 Mon Sep 17 00:00:00 2001 From: ycdesu Date: Sat, 27 Mar 2021 16:58:51 +0800 Subject: [PATCH] ftx: define ws login request --- pkg/exchange/ftx/stream.go | 9 ++++- pkg/exchange/ftx/websocket_messages.go | 44 ++++++++++++++++++++- pkg/exchange/ftx/websocket_messages_test.go | 12 ++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/pkg/exchange/ftx/stream.go b/pkg/exchange/ftx/stream.go index 8da44f6d9..c40bfea0f 100644 --- a/pkg/exchange/ftx/stream.go +++ b/pkg/exchange/ftx/stream.go @@ -28,7 +28,14 @@ func NewStream(key, secret string) *Stream { } func (s *Stream) Connect(ctx context.Context) error { - return s.wsService.Connect(ctx) + if err := s.wsService.Connect(ctx); err != nil { + return err + } + // If it's not public only, let's do the authentication. + if atomic.LoadInt32(&s.publicOnly) == 0 { + } + + return nil } func (s *Stream) SetPublicOnly() { diff --git a/pkg/exchange/ftx/websocket_messages.go b/pkg/exchange/ftx/websocket_messages.go index 2422ca672..47c8bb94c 100644 --- a/pkg/exchange/ftx/websocket_messages.go +++ b/pkg/exchange/ftx/websocket_messages.go @@ -15,6 +15,7 @@ import ( type operation string +const login operation = "login" const subscribe operation = "subscribe" const unsubscribe operation = "unsubscribe" @@ -24,7 +25,48 @@ const orderbook channel = "orderbook" const trades channel = "trades" const ticker channel = "ticker" -// {'op': 'subscribe', 'channel': 'trades', 'market': 'BTC-PERP'} +type websocketRequest struct { + Operation operation `json:"op"` + + // {'op': 'subscribe', 'channel': 'trades', 'market': 'BTC-PERP'} + Channel channel `json:"channel,omitempty"` + Market string `json:"market,omitempty"` + + Login loginArgs `json:"args,omitempty"` +} + +/* +{ + "args": { + "key": "", + "sign": "", + "time": + }, + "op": "login" +} +*/ +type loginArgs struct { + Key string `json:"key"` + Signature string `json:"sign"` + Time int64 `json:"time"` +} + +func newLoginRequest(key, secret string, t time.Time) websocketRequest { + millis := t.UnixNano() / int64(time.Millisecond) + return websocketRequest{ + Operation: login, + Login: loginArgs{ + Key: key, + Signature: sign(secret, loginBody(millis)), + Time: millis, + }, + } +} + +func loginBody(millis int64) string { + return fmt.Sprintf("%dwebsocket_login", millis) +} + type SubscribeRequest struct { Operation operation `json:"op"` Channel channel `json:"channel"` diff --git a/pkg/exchange/ftx/websocket_messages_test.go b/pkg/exchange/ftx/websocket_messages_test.go index 1196385f3..97122331c 100644 --- a/pkg/exchange/ftx/websocket_messages_test.go +++ b/pkg/exchange/ftx/websocket_messages_test.go @@ -3,7 +3,9 @@ package ftx import ( "encoding/json" "io/ioutil" + "strings" "testing" + "time" "github.com/stretchr/testify/assert" @@ -170,3 +172,13 @@ func Test_insertAt(t *testing.T) { r = insertAt([][]json.Number{{"1.2", "2"}, {"1.4", "2"}}, 2, []json.Number{"1.5", "2"}) assert.Equal(t, [][]json.Number{{"1.2", "2"}, {"1.4", "2"}, {"1.5", "2"}}, r) } + +func Test_newLoginRequest(t *testing.T) { + // From API doc: https://docs.ftx.com/?javascript#authentication-2 + r := newLoginRequest("", "Y2QTHI23f23f23jfjas23f23To0RfUwX3H42fvN-", time.Unix(0, 1557246346499*int64(time.Millisecond))) + expectedSignature := "d10b5a67a1a941ae9463a60b285ae845cdeac1b11edc7da9977bef0228b96de9" + assert.Equal(t, expectedSignature, r.Login.Signature) + jsonStr, err := json.Marshal(r) + assert.NoError(t, err) + assert.True(t, strings.Contains(string(jsonStr), expectedSignature)) +}