mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Bitmex: Fix deprecated API endpoints and add config migration support (#1901)
* Bitmex: Fix configured WS url ignored * Bitmex: Replace deprecated WS api endpoint * [Bitmex deprecated the old WS multiplexing endpoint](https://blog.bitmex.com/api_announcement/api-update-remove-support-realtimemd/) * [Bitmex deprecated the www WS endpoint in 2021](https://blog.bitmex.com/api_announcement/change-of-websocket-endpoint/). Apparently still in service though. Fixes #1894
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
v5 "github.com/thrasher-corp/gocryptotrader/config/versions/v5"
|
||||
v6 "github.com/thrasher-corp/gocryptotrader/config/versions/v6"
|
||||
v7 "github.com/thrasher-corp/gocryptotrader/config/versions/v7"
|
||||
v8 "github.com/thrasher-corp/gocryptotrader/config/versions/v8"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -20,4 +21,5 @@ func init() {
|
||||
Manager.registerVersion(5, &v5.Version{})
|
||||
Manager.registerVersion(6, &v6.Version{})
|
||||
Manager.registerVersion(7, &v7.Version{})
|
||||
Manager.registerVersion(8, &v8.Version{})
|
||||
}
|
||||
|
||||
43
config/versions/v8/v8.go
Normal file
43
config/versions/v8/v8.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package v8
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/buger/jsonparser"
|
||||
)
|
||||
|
||||
// Version is an ExchangeVersion to remove deprecated WS endpoints from user config
|
||||
// Announcements:
|
||||
// * https://blog.bitmex.com/api_announcement/change-of-websocket-endpoint/
|
||||
// * https://blog.bitmex.com/api_announcement/api-update-remove-support-realtimemd/
|
||||
type Version struct{}
|
||||
|
||||
// Exchanges returns just Bitmex
|
||||
func (v *Version) Exchanges() []string { return []string{"Bitmex"} }
|
||||
|
||||
// UpgradeExchange replaces deprecated WS endpoints
|
||||
func (v *Version) UpgradeExchange(_ context.Context, e []byte) ([]byte, error) {
|
||||
url, err := jsonparser.GetString(e, "api", "urlEndpoints", "WebsocketSpotURL")
|
||||
switch {
|
||||
case errors.Is(err, jsonparser.KeyPathNotFoundError):
|
||||
return e, nil
|
||||
case err != nil:
|
||||
return e, err
|
||||
}
|
||||
|
||||
switch url {
|
||||
case "wss://ws.bitmex.com/realtimemd", "wss://www.bitmex.com/realtimemd", "wss://www.bitmex.com/realtime":
|
||||
// Old defaults, just delete them
|
||||
return jsonparser.Delete(e, "api", "urlEndpoints", "WebsocketSpotURL"), nil
|
||||
case "wss://ws.testnet.bitmex.com/realtimemd", "wss://testnet.bitmex.com/realtimemd", "wss://testnet.bitmex.com/realtime":
|
||||
// User wants to use testnet
|
||||
return jsonparser.Set(e, []byte(`"wss://ws.testnet.bitmex.com/realtime"`), "api", "urlEndpoints", "WebsocketSpotURL")
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
// DowngradeExchange is a no-op for v8
|
||||
func (v *Version) DowngradeExchange(_ context.Context, e []byte) ([]byte, error) {
|
||||
return e, nil
|
||||
}
|
||||
56
config/versions/v8/v8_test.go
Normal file
56
config/versions/v8/v8_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package v8_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
v8 "github.com/thrasher-corp/gocryptotrader/config/versions/v8"
|
||||
)
|
||||
|
||||
func TestExchanges(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert.Equal(t, []string{"Bitmex"}, new(v8.Version).Exchanges())
|
||||
}
|
||||
|
||||
func TestUpgradeExchange(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, tt := range []struct {
|
||||
in string
|
||||
exp string
|
||||
}{
|
||||
{"wss://private.bitmex.com/realtimemd", `"WebsocketSpotURL": "wss://private.bitmex.com/realtimemd"`},
|
||||
{"wss://ws.bitmex.com/realtimemd", ""},
|
||||
{"wss://www.bitmex.com/realtimemd", ""},
|
||||
{"wss://www.bitmex.com/realtime", ""},
|
||||
{"wss://ws.testnet.bitmex.com/realtimemd", `"WebsocketSpotURL": "wss://ws.testnet.bitmex.com/realtime"`},
|
||||
{"wss://testnet.bitmex.com/realtimemd", `"WebsocketSpotURL": "wss://ws.testnet.bitmex.com/realtime"`},
|
||||
{"wss://testnet.bitmex.com/realtime", `"WebsocketSpotURL": "wss://ws.testnet.bitmex.com/realtime"`},
|
||||
} {
|
||||
t.Run(tt.in, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
in := []byte(`{"name":"Bitmex","api":{"urlEndpoints":{"WebsocketSpotURL": "` + tt.in + `"}}}`)
|
||||
out, err := new(v8.Version).UpgradeExchange(t.Context(), in)
|
||||
require.NoError(t, err)
|
||||
exp := `{"name":"Bitmex","api":{"urlEndpoints":{` + tt.exp + `}}}`
|
||||
assert.Equal(t, exp, string(out))
|
||||
})
|
||||
}
|
||||
|
||||
in := []byte(`{"name":"Bitmex","api":{}`)
|
||||
out, err := new(v8.Version).UpgradeExchange(t.Context(), in)
|
||||
require.NoError(t, err, "UpgradeExchange must not error when urlEndpoints is missing")
|
||||
assert.Equal(t, string(in), string(out), "UpgradeExchange should return same input not error when urlEndpoints is missing")
|
||||
|
||||
_, err = new(v8.Version).UpgradeExchange(t.Context(), []byte(`{"name":"Bitmex","api":{"urlEndpoints":{"WebsocketSpotURL": 42}}}`))
|
||||
require.ErrorContains(t, err, "Value is not a string", "UpgradeExchange must error correctly on string value")
|
||||
}
|
||||
|
||||
func TestDowngradeExchange(t *testing.T) {
|
||||
t.Parallel()
|
||||
in := []byte(`{"name":"Bitmex","api":{"urlEndpoints":{"WebsocketSpotURL": 42}}}`)
|
||||
out, err := new(v8.Version).DowngradeExchange(t.Context(), in)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(in), string(out), "DowngradeExchange must not change json")
|
||||
}
|
||||
Reference in New Issue
Block a user