diff --git a/.golangci.yml b/.golangci.yml index 698ce31cadc..5fdbce3e6f3 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -12,7 +12,7 @@ linters: enable: # defaults # - deadcode -# - errcheck + - errcheck - gosimple - govet - ineffassign diff --git a/cmd/apichecker/apicheck.go b/cmd/apichecker/apicheck.go index 0faea87a8ed..d157f8bc4cc 100644 --- a/cmd/apichecker/apicheck.go +++ b/cmd/apichecker/apicheck.go @@ -1137,7 +1137,10 @@ func htmlScrapeLocalBitcoins(htmlData *HTMLScrapingData) ([]string, error) { return nil, err } str := r.FindString(string(a)) - sha := crypto.GetSHA256([]byte(str)) + sha, err := crypto.GetSHA256([]byte(str)) + if err != nil { + return nil, err + } var resp []string resp = append(resp, crypto.HexEncodeToString(sha)) return resp, nil diff --git a/cmd/gctcli/commands.go b/cmd/gctcli/commands.go index 804adf5435f..65e74ecd7f0 100644 --- a/cmd/gctcli/commands.go +++ b/cmd/gctcli/commands.go @@ -2953,8 +2953,7 @@ var withdrawalRequestCommand = &cli.Command{ func withdrawlRequestByID(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } var ID string @@ -2990,8 +2989,7 @@ func withdrawlRequestByID(c *cli.Context) error { func withdrawlRequestByExchangeID(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } var exchange, currency string @@ -3058,8 +3056,7 @@ func withdrawlRequestByExchangeID(c *cli.Context) error { func withdrawlRequestByDate(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } var exchange string @@ -3842,8 +3839,7 @@ var gctScriptCommand = &cli.Command{ func gctScriptAutoload(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } var command, script string @@ -3866,8 +3862,7 @@ func gctScriptAutoload(c *cli.Context) error { case "remove": status = true default: - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } conn, err := setupClient() @@ -3893,8 +3888,7 @@ func gctScriptAutoload(c *cli.Context) error { func gctScriptExecute(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } if !c.IsSet("filename") { @@ -3973,8 +3967,7 @@ func gctScriptList(c *cli.Context) error { func gctScriptStop(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } if !c.IsSet("uuid") { @@ -4024,8 +4017,7 @@ func gctScriptStopAll(c *cli.Context) error { func gctScriptRead(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } if !c.IsSet("name") { @@ -4058,8 +4050,7 @@ func gctScriptRead(c *cli.Context) error { func gctScriptQuery(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } if !c.IsSet("uuid") { @@ -4093,8 +4084,7 @@ func gctScriptQuery(c *cli.Context) error { func gctScriptUpload(c *cli.Context) error { if c.NArg() == 0 && c.NumFlags() == 0 { - _ = cli.ShowSubcommandHelp(c) - return nil + return cli.ShowSubcommandHelp(c) } var overwrite bool diff --git a/cmd/portfolio/portfolio.go b/cmd/portfolio/portfolio.go index 35400ff061a..36cf9ad686b 100644 --- a/cmd/portfolio/portfolio.go +++ b/cmd/portfolio/portfolio.go @@ -89,7 +89,12 @@ func main() { Subtotal float64 } - cfg.RetrieveConfigCurrencyPairs(true, asset.Spot) + err = cfg.RetrieveConfigCurrencyPairs(true, asset.Spot) + if err != nil { + log.Printf("Failed to retrieve config currency pairs %v\n", err) + os.Exit(1) + } + portfolioMap := make(map[currency.Code]PortfolioTemp) total := float64(0) diff --git a/cmd/websocket_client/main.go b/cmd/websocket_client/main.go index 00545cef88f..5bda3bb3438 100644 --- a/cmd/websocket_client/main.go +++ b/cmd/websocket_client/main.go @@ -97,11 +97,17 @@ func main() { resp.Body.Close() log.Println("Connected to websocket!") + hash, err := crypto.GetSHA256([]byte(cfg.RemoteControl.Password)) + if err != nil { + log.Println("Unable to generate SHA256 hash from remote control password:", err) + return + } + log.Println("Authenticating..") var wsResp WebsocketEventResponse reqData := WebsocketAuth{ Username: cfg.RemoteControl.Username, - Password: crypto.HexEncodeToString(crypto.GetSHA256([]byte(cfg.RemoteControl.Password))), + Password: crypto.HexEncodeToString(hash), } err = SendWebsocketEvent("auth", reqData, &wsResp) if err != nil { diff --git a/common/crypto/crypto.go b/common/crypto/crypto.go index 49f9caeebe8..3912d3f14bd 100644 --- a/common/crypto/crypto.go +++ b/common/crypto/crypto.go @@ -62,29 +62,29 @@ func GetRandomSalt(input []byte, saltLen int) ([]byte, error) { } // GetMD5 returns a MD5 hash of a byte array -func GetMD5(input []byte) []byte { +func GetMD5(input []byte) ([]byte, error) { m := md5.New() // nolint:gosec // hash function used by some exchanges - m.Write(input) - return m.Sum(nil) + _, err := m.Write(input) + return m.Sum(nil), err } // GetSHA512 returns a SHA512 hash of a byte array -func GetSHA512(input []byte) []byte { +func GetSHA512(input []byte) ([]byte, error) { sha := sha512.New() - sha.Write(input) - return sha.Sum(nil) + _, err := sha.Write(input) + return sha.Sum(nil), err } // GetSHA256 returns a SHA256 hash of a byte array -func GetSHA256(input []byte) []byte { +func GetSHA256(input []byte) ([]byte, error) { sha := sha256.New() - sha.Write(input) - return sha.Sum(nil) + _, err := sha.Write(input) + return sha.Sum(nil), err } // GetHMAC returns a keyed-hash message authentication code using the desired // hashtype -func GetHMAC(hashType int, input, key []byte) []byte { +func GetHMAC(hashType int, input, key []byte) ([]byte, error) { var hasher func() hash.Hash switch hashType { @@ -101,14 +101,14 @@ func GetHMAC(hashType int, input, key []byte) []byte { } h := hmac.New(hasher, key) - h.Write(input) - return h.Sum(nil) + _, err := h.Write(input) + return h.Sum(nil), err } // Sha1ToHex takes a string, sha1 hashes it and return a hex string of the // result -func Sha1ToHex(data string) string { +func Sha1ToHex(data string) (string, error) { h := sha1.New() // nolint:gosec // hash function used by some exchanges - h.Write([]byte(data)) - return hex.EncodeToString(h.Sum(nil)) + _, err := h.Write([]byte(data)) + return hex.EncodeToString(h.Sum(nil)), err } diff --git a/common/crypto/crypto_test.go b/common/crypto/crypto_test.go index 4873988b36e..a5693e27bf5 100644 --- a/common/crypto/crypto_test.go +++ b/common/crypto/crypto_test.go @@ -74,7 +74,10 @@ func TestGetMD5(t *testing.T) { t.Parallel() var originalString = []byte("I am testing the MD5 function in common!") var expectedOutput = []byte("18fddf4a41ba90a7352765e62e7a8744") - actualOutput := GetMD5(originalString) + actualOutput, err := GetMD5(originalString) + if err != nil { + t.Fatal(err) + } actualStr := HexEncodeToString(actualOutput) if !bytes.Equal(expectedOutput, []byte(actualStr)) { t.Errorf("Expected '%s'. Actual '%s'", @@ -88,7 +91,10 @@ func TestGetSHA512(t *testing.T) { var expectedOutput = []byte( `a2273f492ea73fddc4f25c267b34b3b74998bd8a6301149e1e1c835678e3c0b90859fce22e4e7af33bde1711cbb924809aedf5d759d648d61774b7185c5dc02b`, ) - actualOutput := GetSHA512(originalString) + actualOutput, err := GetSHA512(originalString) + if err != nil { + t.Fatal(err) + } actualStr := HexEncodeToString(actualOutput) if !bytes.Equal(expectedOutput, []byte(actualStr)) { t.Errorf("Expected '%x'. Actual '%x'", @@ -102,7 +108,11 @@ func TestGetSHA256(t *testing.T) { var expectedOutput = []byte( "0962813d7a9f739cdcb7f0c0be0c2a13bd630167e6e54468266e4af6b1ad9303", ) - actualOutput := GetSHA256(originalString) + actualOutput, err := GetSHA256(originalString) + if err != nil { + t.Fatal(err) + } + actualStr := HexEncodeToString(actualOutput) if !bytes.Equal(expectedOutput, []byte(actualStr)) { t.Errorf("Expected '%x'. Actual '%x'", expectedOutput, @@ -135,31 +145,46 @@ func TestGetHMAC(t *testing.T) { 113, 64, 132, 129, 213, 68, 231, 99, 252, 15, 175, 109, 198, 132, 139, 39, } - sha1 := GetHMAC(HashSHA1, []byte("Hello,World"), []byte("1234")) + sha1, err := GetHMAC(HashSHA1, []byte("Hello,World"), []byte("1234")) + if err != nil { + t.Fatal(err) + } if string(sha1) != string(expectedSha1) { t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'", expectedSha1, sha1, ) } - sha256 := GetHMAC(HashSHA256, []byte("Hello,World"), []byte("1234")) + sha256, err := GetHMAC(HashSHA256, []byte("Hello,World"), []byte("1234")) + if err != nil { + t.Fatal(err) + } if string(sha256) != string(expectedsha256) { t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'", expectedsha256, sha256, ) } - sha512 := GetHMAC(HashSHA512, []byte("Hello,World"), []byte("1234")) + sha512, err := GetHMAC(HashSHA512, []byte("Hello,World"), []byte("1234")) + if err != nil { + t.Fatal(err) + } if string(sha512) != string(expectedsha512) { t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'", expectedsha512, sha512, ) } - sha512384 := GetHMAC(HashSHA512_384, []byte("Hello,World"), []byte("1234")) + sha512384, err := GetHMAC(HashSHA512_384, []byte("Hello,World"), []byte("1234")) + if err != nil { + t.Fatal(err) + } if string(sha512384) != string(expectedsha512384) { t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'", expectedsha512384, sha512384, ) } - md5 := GetHMAC(HashMD5, []byte("Hello World"), []byte("1234")) + md5, err := GetHMAC(HashMD5, []byte("Hello World"), []byte("1234")) + if err != nil { + t.Fatal(err) + } if string(md5) != string(expectedmd5) { t.Errorf("Common GetHMAC error: Expected '%x'. Actual '%x'", expectedmd5, md5, @@ -170,7 +195,10 @@ func TestGetHMAC(t *testing.T) { func TestSha1Tohex(t *testing.T) { t.Parallel() expectedResult := "fcfbfcd7d31d994ef660f6972399ab5d7a890149" - actualResult := Sha1ToHex("Testing Sha1ToHex") + actualResult, err := Sha1ToHex("Testing Sha1ToHex") + if err != nil { + t.Fatal(err) + } if actualResult != expectedResult { t.Errorf("Expected '%s'. Actual '%s'", expectedResult, actualResult) diff --git a/config/config_test.go b/config/config_test.go index cfdd76cca81..f06c2c556ae 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -35,7 +35,10 @@ func TestGetNonExistentDefaultFilePathDoesNotCreateDefaultDir(t *testing.T) { if file.Exists(dir) { t.Skip("The default directory already exists before running the test") } - GetFilePath("") + _, _, err := GetFilePath("") + if err != nil { + t.Fatal(err) + } if file.Exists(dir) { t.Fatalf("The target directory was created in %s", dir) } diff --git a/currency/code_test.go b/currency/code_test.go index 7ebb0acac73..8bb140fedd5 100644 --- a/currency/code_test.go +++ b/currency/code_test.go @@ -245,12 +245,15 @@ func TestBaseCode(t *testing.T) { true) } - main.LoadItem(&Item{ + err = main.LoadItem(&Item{ ID: 0, FullName: "Cardano", Role: Cryptocurrency, Symbol: "ADA", }) + if err != nil { + t.Fatal(err) + } full, err := main.GetFullCurrencyData() if err != nil { diff --git a/currency/forexprovider/exchangerate.host/exchangerate_test.go b/currency/forexprovider/exchangerate.host/exchangerate_test.go index 5fc8c97a037..d732778d115 100644 --- a/currency/forexprovider/exchangerate.host/exchangerate_test.go +++ b/currency/forexprovider/exchangerate.host/exchangerate_test.go @@ -1,6 +1,7 @@ package exchangeratehost import ( + "log" "os" "testing" "time" @@ -14,9 +15,12 @@ var ( ) func TestMain(t *testing.M) { - e.Setup(base.Settings{ + err := e.Setup(base.Settings{ Name: "ExchangeRateHost", }) + if err != nil { + log.Fatal(err) + } os.Exit(t.Run()) } diff --git a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go index c401733737e..eb7505feee2 100644 --- a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go +++ b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go @@ -16,10 +16,12 @@ import ( "github.com/thrasher-corp/gocryptotrader/log" ) +var errAPIKeyNotSet = errors.New("API key must be set") + // Setup sets appropriate values for CurrencyLayer func (e *ExchangeRates) Setup(config base.Settings) error { if config.APIKey == "" { - return errors.New("API key must be set") + return errAPIKeyNotSet } e.Name = config.Name e.Enabled = config.Enabled diff --git a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi_test.go b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi_test.go index f21f005c781..93c5d0bb173 100644 --- a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi_test.go +++ b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi_test.go @@ -2,6 +2,7 @@ package exchangerates import ( "errors" + "log" "os" "testing" "time" @@ -17,11 +18,14 @@ const ( ) func TestMain(t *testing.M) { - e.Setup(base.Settings{ + err := e.Setup(base.Settings{ Name: "ExchangeRates", APIKey: apiKey, APIKeyLvl: apiKeyLevel, }) + if err != nil && !errors.Is(err, errAPIKeyNotSet) { + log.Fatal(err) + } os.Exit(t.Run()) } diff --git a/currency/forexprovider/forexprovider.go b/currency/forexprovider/forexprovider.go index b52809a965e..fdcda7d3b46 100644 --- a/currency/forexprovider/forexprovider.go +++ b/currency/forexprovider/forexprovider.go @@ -88,8 +88,10 @@ func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) { return nil, err } - handler.SetProvider(provider) - + err = handler.SetProvider(provider) + if err != nil { + return nil, err + } case fxProviders[i].Name == "CurrencyLayer" && fxProviders[i].Enabled: provider := new(currencylayer.CurrencyLayer) err := provider.Setup(fxProviders[i]) @@ -97,8 +99,10 @@ func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) { return nil, err } - handler.SetProvider(provider) - + err = handler.SetProvider(provider) + if err != nil { + return nil, err + } case fxProviders[i].Name == "ExchangeRates" && fxProviders[i].Enabled: provider := new(exchangerates.ExchangeRates) err := provider.Setup(fxProviders[i]) @@ -106,8 +110,10 @@ func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) { return nil, err } - handler.SetProvider(provider) - + err = handler.SetProvider(provider) + if err != nil { + return nil, err + } case fxProviders[i].Name == "Fixer" && fxProviders[i].Enabled: provider := new(fixer.Fixer) err := provider.Setup(fxProviders[i]) @@ -115,8 +121,10 @@ func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) { return nil, err } - handler.SetProvider(provider) - + err = handler.SetProvider(provider) + if err != nil { + return nil, err + } case fxProviders[i].Name == "OpenExchangeRates" && fxProviders[i].Enabled: provider := new(openexchangerates.OXR) err := provider.Setup(fxProviders[i]) @@ -124,7 +132,10 @@ func StartFXService(fxProviders []base.Settings) (*ForexProviders, error) { return nil, err } - handler.SetProvider(provider) + err = handler.SetProvider(provider) + if err != nil { + return nil, err + } } } diff --git a/currency/forexprovider/openexchangerates/openexchangerates_test.go b/currency/forexprovider/openexchangerates/openexchangerates_test.go index 184c9c88692..962de96b5af 100644 --- a/currency/forexprovider/openexchangerates/openexchangerates_test.go +++ b/currency/forexprovider/openexchangerates/openexchangerates_test.go @@ -1,6 +1,8 @@ package openexchangerates import ( + "log" + "os" "testing" "github.com/thrasher-corp/gocryptotrader/currency/forexprovider/base" @@ -15,20 +17,21 @@ const ( var o OXR -var initialSetup bool - -func setup() { - o.Setup(base.Settings{ - Name: "OpenExchangeRates", - Enabled: true, +func TestMain(m *testing.M) { + err := o.Setup(base.Settings{ + Name: "OpenExchangeRates", + Enabled: true, + APIKey: apikey, + APIKeyLvl: apilvl, }) - initialSetup = true + if err != nil { + log.Fatal(err) + } + os.Exit(m.Run()) } func TestGetRates(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetRates("USD", "AUD") if err == nil { t.Error("GetRates() Expected error") @@ -36,9 +39,7 @@ func TestGetRates(t *testing.T) { } func TestGetLatest(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetLatest("USD", "AUD", false, false) if err == nil { t.Error("GetLatest() Expected error") @@ -46,9 +47,7 @@ func TestGetLatest(t *testing.T) { } func TestGetHistoricalRates(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetHistoricalRates("2017-12-01", "USD", []string{"CNH", "AUD", "ANG"}, false, false) if err == nil { t.Error("GetRates() Expected error") @@ -56,9 +55,7 @@ func TestGetHistoricalRates(t *testing.T) { } func TestGetCurrencies(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetCurrencies(true, true, true) if err != nil { t.Error("GetCurrencies() error", err) @@ -66,9 +63,7 @@ func TestGetCurrencies(t *testing.T) { } func TestGetTimeSeries(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetTimeSeries("USD", "2017-12-01", "2017-12-02", []string{"CNH", "AUD", "ANG"}, false, false) if err == nil { t.Error("GetTimeSeries() Expected error") @@ -76,9 +71,7 @@ func TestGetTimeSeries(t *testing.T) { } func TestConvertCurrency(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.ConvertCurrency(1337, "USD", "AUD") if err == nil { t.Error("ConvertCurrency() Expected error") @@ -86,9 +79,7 @@ func TestConvertCurrency(t *testing.T) { } func TestGetOHLC(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetOHLC("2017-07-17T08:30:00Z", "1m", "USD", []string{"AUD"}, false) if err == nil { t.Error("GetOHLC() Expected error") @@ -96,9 +87,7 @@ func TestGetOHLC(t *testing.T) { } func TestGetUsageStats(t *testing.T) { - if !initialSetup { - setup() - } + t.Parallel() _, err := o.GetUsageStats(false) if err == nil { t.Error("GetUsageStats() Expected error") diff --git a/currency/manager.go b/currency/manager.go index 37165f5c0f6..f0d328168c4 100644 --- a/currency/manager.go +++ b/currency/manager.go @@ -8,6 +8,10 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/asset" ) +// ErrAssetAlreadyEnabled defines an error for the pairs management system +// that declares the asset is already enabled. +var ErrAssetAlreadyEnabled = errors.New("asset already enabled") + // GetAssetTypes returns a list of stored asset types func (p *PairsManager) GetAssetTypes(enabled bool) asset.Items { p.m.RLock() @@ -185,7 +189,7 @@ func (p *PairsManager) SetAssetEnabled(a asset.Item, enabled bool) error { if !*c.AssetEnabled && !enabled { return errors.New("asset already disabled") } else if *c.AssetEnabled && enabled { - return errors.New("asset already enabled") + return ErrAssetAlreadyEnabled } *c.AssetEnabled = enabled diff --git a/currency/storage.go b/currency/storage.go index eb67ece82ee..8fef8ff0f96 100644 --- a/currency/storage.go +++ b/currency/storage.go @@ -539,9 +539,7 @@ func (s *Storage) SetupCryptoProvider(settings coinmarketcap.Settings) error { s.currencyAnalysis = new(coinmarketcap.Coinmarketcap) s.currencyAnalysis.SetDefaults() - s.currencyAnalysis.Setup(settings) - - return nil + return s.currencyAnalysis.Setup(settings) } // GetTotalMarketCryptocurrencies returns the total seeded market diff --git a/engine/apiserver.go b/engine/apiserver.go index e7c95feaf50..67c9701fca0 100644 --- a/engine/apiserver.go +++ b/engine/apiserver.go @@ -686,7 +686,12 @@ func wsAuth(client *websocketClient, data interface{}) error { return err } - hashPW := crypto.HexEncodeToString(crypto.GetSHA256([]byte(client.password))) + hash, err := crypto.GetSHA256([]byte(client.password)) + if err != nil { + return err + } + + hashPW := crypto.HexEncodeToString(hash) if auth.Username == client.username && auth.Password == hashPW { client.Authenticated = true wsResp.Data = WebsocketResponseSuccess diff --git a/engine/rpcserver_test.go b/engine/rpcserver_test.go index ed7175792e5..283dc5daf9b 100644 --- a/engine/rpcserver_test.go +++ b/engine/rpcserver_test.go @@ -1779,7 +1779,7 @@ func TestRPCServer_GetTicker_LastUpdatedNanos(t *testing.T) { // Push a mock-up ticker. now := time.Now() - ticker.ProcessTicker(&ticker.Price{ + err = ticker.ProcessTicker(&ticker.Price{ ExchangeName: testExchange, Pair: pair, AssetType: asset.Spot, @@ -1790,6 +1790,9 @@ func TestRPCServer_GetTicker_LastUpdatedNanos(t *testing.T) { Low: 169, Close: 196, }) + if err != nil { + t.Fatal(err) + } // Prepare a ticker request. request := &gctrpc.GetTickerRequest{ diff --git a/exchanges/alphapoint/alphapoint.go b/exchanges/alphapoint/alphapoint.go index ed5a6a4b436..68e1d4907b3 100644 --- a/exchanges/alphapoint/alphapoint.go +++ b/exchanges/alphapoint/alphapoint.go @@ -567,9 +567,14 @@ func (a *Alphapoint) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path headers["Content-Type"] = "application/json" data["apiKey"] = a.API.Credentials.Key data["apiNonce"] = n - hmac := crypto.GetHMAC(crypto.HashSHA256, + + hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte(n.String()+a.API.Credentials.ClientID+a.API.Credentials.Key), []byte(a.API.Credentials.Secret)) + if err != nil { + return err + } + data["apiSig"] = strings.ToUpper(crypto.HexEncodeToString(hmac)) path = fmt.Sprintf("%s/ajax/v%s/%s", endpoint, alphapointAPIVersion, path) diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index 57b3473d405..2b13f33b413 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -743,7 +743,13 @@ func (b *Binance) SendAuthHTTPRequest(ePath exchange.URL, method, path string, p fullPath := endpointPath + path params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10)) signature := params.Encode() - hmacSigned := crypto.GetHMAC(crypto.HashSHA256, []byte(signature), []byte(b.API.Credentials.Secret)) + var hmacSigned []byte + hmacSigned, err = crypto.GetHMAC(crypto.HashSHA256, + []byte(signature), + []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } hmacSignedStr := crypto.HexEncodeToString(hmacSigned) headers := make(map[string]string) headers["X-MBX-APIKEY"] = b.API.Credentials.Key diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index 4e216a83a3d..2168ac0945f 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -1331,7 +1331,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() || mockTests { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index eab3abab490..e0c27c8e2b2 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -1542,9 +1542,12 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path st } PayloadBase64 := crypto.Base64Encode(PayloadJSON) - hmac := crypto.GetHMAC(crypto.HashSHA512_384, + hmac, err := crypto.GetHMAC(crypto.HashSHA512_384, []byte(PayloadBase64), []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["X-BFX-APIKEY"] = b.API.Credentials.Key headers["X-BFX-PAYLOAD"] = PayloadBase64 @@ -1594,11 +1597,14 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ep exchange.URL, method, path headers["bfx-nonce"] = n strPath := "/api" + bitfinexAPIVersion2 + path + string(payload) signStr := strPath + n - hmac := crypto.GetHMAC( + hmac, err := crypto.GetHMAC( crypto.HashSHA512_384, []byte(signStr), []byte(b.API.Credentials.Secret), ) + if err != nil { + return nil, err + } headers["bfx-signature"] = crypto.HexEncodeToString(hmac) return &request.Item{ diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index be0cde084c6..47fa4ca7a26 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -723,7 +723,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bitfinex/bitfinex_websocket.go b/exchanges/bitfinex/bitfinex_websocket.go index cd1cea44cbe..beff583f28e 100644 --- a/exchanges/bitfinex/bitfinex_websocket.go +++ b/exchanges/bitfinex/bitfinex_websocket.go @@ -1167,19 +1167,25 @@ func (b *Bitfinex) WsSendAuth() error { return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", b.Name) } + nonce := strconv.FormatInt(time.Now().Unix(), 10) payload := "AUTH" + nonce + + hmac, err := crypto.GetHMAC(crypto.HashSHA512_384, + []byte(payload), + []byte(b.API.Credentials.Secret)) + if err != nil { + return err + } request := WsAuthRequest{ - Event: "auth", - APIKey: b.API.Credentials.Key, - AuthPayload: payload, - AuthSig: crypto.HexEncodeToString(crypto.GetHMAC(crypto.HashSHA512_384, - []byte(payload), - []byte(b.API.Credentials.Secret))), + Event: "auth", + APIKey: b.API.Credentials.Key, + AuthPayload: payload, + AuthSig: crypto.HexEncodeToString(hmac), AuthNonce: nonce, DeadManSwitch: 0, } - err := b.Websocket.AuthConn.SendJSONMessage(request) + err = b.Websocket.AuthConn.SendJSONMessage(request) if err != nil { b.Websocket.SetCanUseAuthenticatedEndpoints(false) return err diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index 14e76e0efce..e835d1bd7fb 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -187,7 +187,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index 61529ce9b82..333f64f5f7d 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -500,9 +500,14 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, par payload := params.Encode() hmacPayload := path + string('\x00') + payload + string('\x00') + n - hmac := crypto.GetHMAC(crypto.HashSHA512, + + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA512, []byte(hmacPayload), []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } hmacStr := crypto.HexEncodeToString(hmac) headers := make(map[string]string) diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index 462beb6c14d..f0a133b8d99 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -261,7 +261,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 0a6a175971d..adbc6da9207 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -868,9 +868,13 @@ func (b *Bitmex) SendAuthenticatedHTTPRequest(ep exchange.URL, verb, path string payload = string(data) } - hmac := crypto.GetHMAC(crypto.HashSHA256, + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, []byte(verb+"/api/v1"+path+timestampNew+payload), []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers["api-signature"] = crypto.HexEncodeToString(hmac) diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index bf1f3afa543..8331d36f2a2 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -500,7 +500,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bitmex/bitmex_websocket.go b/exchanges/bitmex/bitmex_websocket.go index 8c65f9f95e6..d37d24901d8 100644 --- a/exchanges/bitmex/bitmex_websocket.go +++ b/exchanges/bitmex/bitmex_websocket.go @@ -666,16 +666,19 @@ func (b *Bitmex) websocketSendAuth() error { b.Websocket.SetCanUseAuthenticatedEndpoints(true) timestamp := time.Now().Add(time.Hour * 1).Unix() newTimestamp := strconv.FormatInt(timestamp, 10) - hmac := crypto.GetHMAC(crypto.HashSHA256, + hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte("GET/realtime"+newTimestamp), []byte(b.API.Credentials.Secret)) + if err != nil { + return err + } signature := crypto.HexEncodeToString(hmac) var sendAuth WebsocketRequest sendAuth.Command = "authKeyExpires" sendAuth.Arguments = append(sendAuth.Arguments, b.API.Credentials.Key, timestamp, signature) - err := b.Websocket.Conn.SendJSONMessage(sendAuth) + err = b.Websocket.Conn.SendJSONMessage(sendAuth) if err != nil { b.Websocket.SetCanUseAuthenticatedEndpoints(false) return err diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 9a8ec6ad5a8..233ffe6bfa8 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -631,9 +631,15 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, v2 values.Set("key", b.API.Credentials.Key) values.Set("nonce", n) - hmac := crypto.GetHMAC(crypto.HashSHA256, + + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, []byte(n+b.API.Credentials.ClientID+b.API.Credentials.Key), []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } + values.Set("signature", strings.ToUpper(crypto.HexEncodeToString(hmac))) var fullPath string diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index 9bdf65fb522..aebed087c9d 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -44,7 +44,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", diff --git a/exchanges/bitstamp/bitstamp_websocket.go b/exchanges/bitstamp/bitstamp_websocket.go index 9c9788af885..831ef6424da 100644 --- a/exchanges/bitstamp/bitstamp_websocket.go +++ b/exchanges/bitstamp/bitstamp_websocket.go @@ -81,7 +81,12 @@ func (b *Bitstamp) wsHandleData(respRaw []byte) error { if b.Verbose { log.Debugf(log.ExchangeSys, "%v - Websocket reconnection request received", b.Name) } - go b.Websocket.Shutdown() // Connection monitor will reconnect + go func() { + err := b.Websocket.Shutdown() + if err != nil { + log.Errorf(log.WebsocketMgr, "%s failed to shutdown websocket: %v", b.Name, err) + } + }() // Connection monitor will reconnect case "data": wsOrderBookTemp := websocketOrderBookResponse{} err := json.Unmarshal(respRaw, &wsOrderBookTemp) diff --git a/exchanges/bittrex/bittrex.go b/exchanges/bittrex/bittrex.go index ced133b6a2d..1e329ed6b2f 100644 --- a/exchanges/bittrex/bittrex.go +++ b/exchanges/bittrex/bittrex.go @@ -386,9 +386,18 @@ func (b *Bittrex) SendAuthHTTPRequest(ep exchange.URL, method, action string, pa } } body = bytes.NewBuffer(payload) - contentHash = crypto.HexEncodeToString(crypto.GetSHA512(payload)) + hash, err := crypto.GetSHA512(payload) + if err != nil { + return nil, err + } + contentHash = crypto.HexEncodeToString(hash) sigPayload := ts + endpoint + path + method + contentHash - hmac = crypto.GetHMAC(crypto.HashSHA512, []byte(sigPayload), []byte(b.API.Credentials.Secret)) + hmac, err = crypto.GetHMAC(crypto.HashSHA512, + []byte(sigPayload), + []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["Api-Key"] = b.API.Credentials.Key diff --git a/exchanges/bittrex/bittrex_test.go b/exchanges/bittrex/bittrex_test.go index e77c289f0b0..019555ca96f 100644 --- a/exchanges/bittrex/bittrex_test.go +++ b/exchanges/bittrex/bittrex_test.go @@ -339,7 +339,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/bittrex/bittrex_websocket.go b/exchanges/bittrex/bittrex_websocket.go index 18af918d52a..2a566015047 100644 --- a/exchanges/bittrex/bittrex_websocket.go +++ b/exchanges/bittrex/bittrex_websocket.go @@ -155,11 +155,15 @@ func (b *Bittrex) WsAuth() error { return err } timestamp := strconv.FormatInt(time.Now().UnixNano()/1000000, 10) - hmac := crypto.GetHMAC( + hmac, err := crypto.GetHMAC( crypto.HashSHA512, []byte(timestamp+randomContent.String()), []byte(b.API.Credentials.Secret), ) + if err != nil { + return err + } + signature := crypto.HexEncodeToString(hmac) req := WsEventRequest{ diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index 605ac43b6de..6555842b7f2 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -144,7 +144,10 @@ func (b *Bittrex) Setup(exch *config.ExchangeConfig) error { return nil } - b.SetupDefaults(exch) + err := b.SetupDefaults(exch) + if err != nil { + return err + } wsRunningEndpoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot) if err != nil { diff --git a/exchanges/bittrex/bittrex_ws_orderbook.go b/exchanges/bittrex/bittrex_ws_orderbook.go index 353086f27b9..b13c6f61c84 100644 --- a/exchanges/bittrex/bittrex_ws_orderbook.go +++ b/exchanges/bittrex/bittrex_ws_orderbook.go @@ -166,7 +166,10 @@ func (b *Bittrex) applyBufferUpdate(pair currency.Pair) error { "%s error processing update - initiating new orderbook sync via REST: %s\n", b.Name, err) - b.obm.setNeedsFetchingBook(pair) + err = b.obm.setNeedsFetchingBook(pair) + if err != nil { + return err + } } } return nil diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index 6ae69065645..73688171b57 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -716,13 +716,20 @@ func (b *BTCMarkets) SendAuthenticatedRequest(method, path string, data, result } body = bytes.NewBuffer(payload) strMsg := method + btcMarketsAPIVersion + path + strTime + string(payload) - hmac = crypto.GetHMAC(crypto.HashSHA512, - []byte(strMsg), []byte(b.API.Credentials.Secret)) + hmac, err = crypto.GetHMAC(crypto.HashSHA512, + []byte(strMsg), + []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } default: strArray := strings.Split(path, "?") - hmac = crypto.GetHMAC(crypto.HashSHA512, + hmac, err = crypto.GetHMAC(crypto.HashSHA512, []byte(method+btcMarketsAPIVersion+strArray[0]+strTime), []byte(b.API.Credentials.Secret)) + if err != nil { + return nil, err + } } headers := make(map[string]string) diff --git a/exchanges/btcmarkets/btcmarkets_types.go b/exchanges/btcmarkets/btcmarkets_types.go index 8c9c77a635f..2a0182e2145 100644 --- a/exchanges/btcmarkets/btcmarkets_types.go +++ b/exchanges/btcmarkets/btcmarkets_types.go @@ -1,12 +1,9 @@ package btcmarkets import ( - "errors" "time" ) -var errInvalidTimeInterval = errors.New("invalid time interval") - // Market holds a tradable market instrument type Market struct { MarketID string `json:"marketId"` diff --git a/exchanges/btcmarkets/btcmarkets_websocket.go b/exchanges/btcmarkets/btcmarkets_websocket.go index 76fc2d92509..88b686b7234 100644 --- a/exchanges/btcmarkets/btcmarkets_websocket.go +++ b/exchanges/btcmarkets/btcmarkets_websocket.go @@ -344,9 +344,12 @@ func (b *BTCMarkets) Subscribe(channelsToSubscribe []stream.ChannelSubscription) } signTime := strconv.FormatInt(time.Now().UTC().UnixNano()/1000000, 10) strToSign := "/users/self/subscribe" + "\n" + signTime - tempSign := crypto.GetHMAC(crypto.HashSHA512, + tempSign, err := crypto.GetHMAC(crypto.HashSHA512, []byte(strToSign), []byte(b.API.Credentials.Secret)) + if err != nil { + return err + } sign := crypto.Base64Encode(tempSign) payload.Key = b.API.Credentials.Key payload.Signature = sign diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index ad676ba326f..8297b534765 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -483,23 +483,30 @@ func (b *BTSE) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint st "btse-nonce": nonce, } if req != nil { - reqPayload, err := json.Marshal(req) + var reqPayload []byte + reqPayload, err = json.Marshal(req) if err != nil { return nil, err } body = bytes.NewBuffer(reqPayload) - hmac = crypto.GetHMAC( + hmac, err = crypto.GetHMAC( crypto.HashSHA512_384, []byte((expandedEndpoint + nonce + string(reqPayload))), []byte(b.API.Credentials.Secret), ) + if err != nil { + return nil, err + } headers["Content-Type"] = "application/json" } else { - hmac = crypto.GetHMAC( + hmac, err = crypto.GetHMAC( crypto.HashSHA512_384, []byte((expandedEndpoint + nonce)), []byte(b.API.Credentials.Secret), ) + if err != nil { + return nil, err + } if len(values) > 0 { host += "?" + values.Encode() } diff --git a/exchanges/btse/btse_test.go b/exchanges/btse/btse_test.go index e51b313dc4b..d2572ee466d 100644 --- a/exchanges/btse/btse_test.go +++ b/exchanges/btse/btse_test.go @@ -466,7 +466,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { PurchasePrice: 1000, } - b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/btse/btse_websocket.go b/exchanges/btse/btse_websocket.go index 148afc8e25b..39543a49e43 100644 --- a/exchanges/btse/btse_websocket.go +++ b/exchanges/btse/btse_websocket.go @@ -57,10 +57,15 @@ func (b *BTSE) WsConnect() error { func (b *BTSE) WsAuthenticate() error { nonce := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) path := "/spotWS" + nonce - hmac := crypto.GetHMAC(crypto.HashSHA512_384, + + hmac, err := crypto.GetHMAC(crypto.HashSHA512_384, []byte((path)), []byte(b.API.Credentials.Secret), ) + if err != nil { + return err + } + sign := crypto.HexEncodeToString(hmac) req := wsSub{ Operation: "authKeyExpires", diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 0d147785d89..3fc5b74c81b 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -28,11 +28,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" ) -const ( - spotURL = "spotURL" - spotWSURL = "websocketURL" -) - // GetDefaultConfig returns a default exchange config func (b *BTSE) GetDefaultConfig() (*config.ExchangeConfig, error) { b.SetDefaults() diff --git a/exchanges/coinbasepro/coinbasepro.go b/exchanges/coinbasepro/coinbasepro.go index e25a346a292..2a7652d1aa6 100644 --- a/exchanges/coinbasepro/coinbasepro.go +++ b/exchanges/coinbasepro/coinbasepro.go @@ -722,7 +722,14 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path now := time.Now() n := strconv.FormatInt(now.Unix(), 10) message := n + method + "/" + path + string(payload) - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(message), []byte(c.API.Credentials.Secret)) + + hmac, err := crypto.GetHMAC(crypto.HashSHA256, + []byte(message), + []byte(c.API.Credentials.Secret)) + if err != nil { + return nil, err + } + headers := make(map[string]string) headers["CB-ACCESS-SIGN"] = crypto.Base64Encode(hmac) headers["CB-ACCESS-TIMESTAMP"] = n diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index 365e851fdc6..82b64cd78b2 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -214,7 +214,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - c.GetFeeByType(feeBuilder) + _, err := c.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/coinbasepro/coinbasepro_websocket.go b/exchanges/coinbasepro/coinbasepro_websocket.go index c5542942a3c..fb9fe940638 100644 --- a/exchanges/coinbasepro/coinbasepro_websocket.go +++ b/exchanges/coinbasepro/coinbasepro_websocket.go @@ -416,8 +416,12 @@ subscriptions: channelsToSubscribe[i].Channel == "full" { n := strconv.FormatInt(time.Now().Unix(), 10) message := n + http.MethodGet + "/users/self/verify" - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(message), + hmac, err := crypto.GetHMAC(crypto.HashSHA256, + []byte(message), []byte(c.API.Credentials.Secret)) + if err != nil { + return err + } subscribe.Signature = crypto.Base64Encode(hmac) subscribe.Key = c.API.Credentials.Key subscribe.Passphrase = c.API.Credentials.ClientID diff --git a/exchanges/coinbene/coinbene.go b/exchanges/coinbene/coinbene.go index 12887412b6e..4a142c70bc4 100644 --- a/exchanges/coinbene/coinbene.go +++ b/exchanges/coinbene/coinbene.go @@ -1166,9 +1166,13 @@ func (c *Coinbene) SendAuthHTTPRequest(ep exchange.URL, method, path, epPath str default: preSign = timestamp + method + authPath + epPath } - tempSign := crypto.GetHMAC(crypto.HashSHA256, + tempSign, err := crypto.GetHMAC(crypto.HashSHA256, []byte(preSign), []byte(c.API.Credentials.Secret)) + if err != nil { + return nil, err + } + headers := make(map[string]string) headers["Content-Type"] = "application/json" headers["ACCESS-KEY"] = c.API.Credentials.Key diff --git a/exchanges/coinbene/coinbene_websocket.go b/exchanges/coinbene/coinbene_websocket.go index 3d5c94471cf..302ecac1168 100644 --- a/exchanges/coinbene/coinbene_websocket.go +++ b/exchanges/coinbene/coinbene_websocket.go @@ -502,9 +502,14 @@ func (c *Coinbene) Login() error { var sub WsSub expTime := time.Now().Add(time.Minute * 10).Format("2006-01-02T15:04:05Z") signMsg := expTime + http.MethodGet + "/login" - tempSign := crypto.GetHMAC(crypto.HashSHA256, + + tempSign, err := crypto.GetHMAC(crypto.HashSHA256, []byte(signMsg), []byte(c.API.Credentials.Secret)) + if err != nil { + return err + } + sign := crypto.HexEncodeToString(tempSign) sub.Operation = "login" sub.Arguments = []string{c.API.Credentials.Key, expTime, sign} diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index 015a069ecb8..d9688edc717 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -44,10 +44,7 @@ const ( wsRateLimitInMilliseconds = 33 ) -var ( - errLookupInstrumentID = errors.New("unable to lookup instrument ID") - errLookupInstrumentCurrency = errors.New("unable to lookup instrument") -) +var errLookupInstrumentID = errors.New("unable to lookup instrument ID") // COINUT is the overarching type across the coinut package type COINUT struct { @@ -174,11 +171,6 @@ func (c *COINUT) CancelExistingOrder(instrumentID, orderID int64) (bool, error) func (c *COINUT) CancelOrders(orders []CancelOrders) (CancelOrdersResponse, error) { var result CancelOrdersResponse params := make(map[string]interface{}) - type Request struct { - InstrumentID int `json:"inst_id"` - OrderID int `json:"order_id"` - } - var entries []CancelOrders entries = append(entries, orders...) params["entries"] = entries @@ -288,7 +280,13 @@ func (c *COINUT) SendHTTPRequest(ep exchange.URL, apiRequest string, params map[ headers := make(map[string]string) if authenticated { headers["X-USER"] = c.API.Credentials.ClientID - hmac := crypto.GetHMAC(crypto.HashSHA256, payload, []byte(c.API.Credentials.Key)) + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, + payload, + []byte(c.API.Credentials.Key)) + if err != nil { + return nil, err + } headers["X-SIGNATURE"] = crypto.HexEncodeToString(hmac) } headers["Content-Type"] = "application/json" diff --git a/exchanges/coinut/coinut_test.go b/exchanges/coinut/coinut_test.go index 76a53d795b7..d79c048549f 100644 --- a/exchanges/coinut/coinut_test.go +++ b/exchanges/coinut/coinut_test.go @@ -117,7 +117,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - c.GetFeeByType(feeBuilder) + _, err := c.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if apiKey == "" { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/coinut/coinut_websocket.go b/exchanges/coinut/coinut_websocket.go index 1143c8f7b33..b15e99a0c5a 100644 --- a/exchanges/coinut/coinut_websocket.go +++ b/exchanges/coinut/coinut_websocket.go @@ -690,9 +690,14 @@ func (c *COINUT) wsAuthenticate() error { payload := c.API.Credentials.ClientID + "|" + strconv.FormatInt(timestamp, 10) + "|" + strconv.FormatInt(nonce, 10) - hmac := crypto.GetHMAC(crypto.HashSHA256, + + hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte(payload), []byte(c.API.Credentials.Key)) + if err != nil { + return err + } + loginRequest := struct { Request string `json:"request"` Username string `json:"username"` diff --git a/exchanges/exchange.go b/exchanges/exchange.go index af81acd8946..107d686f03e 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -37,8 +37,11 @@ const ( DefaultWebsocketOrderbookBufferLimit = 5 ) -// ErrAuthenticatedRequestWithoutCredentialsSet error message for authenticated request without credentials set -var ErrAuthenticatedRequestWithoutCredentialsSet = errors.New("authenticated HTTP request called but not supported due to unset/default API keys") +var ( + // ErrAuthenticatedRequestWithoutCredentialsSet error message for authenticated request without credentials set + ErrAuthenticatedRequestWithoutCredentialsSet = errors.New("authenticated HTTP request called but not supported due to unset/default API keys") + errTransportNotSet = errors.New("transport not set, cannot set timeout") +) func (b *Base) checkAndInitRequester() { if b.Requester == nil { @@ -54,7 +57,7 @@ func (b *Base) SetHTTPClientTimeout(t time.Duration) error { b.Requester.HTTPClient.Timeout = t tr, ok := b.Requester.HTTPClient.Transport.(*http.Transport) if !ok { - return errors.New("transport not set, cannot set timeout") + return errTransportNotSet } tr.IdleConnTimeout = t return nil @@ -294,6 +297,7 @@ func (b *Base) SetConfigPairs() error { "%s exchange asset type %s unsupported, please manually remove from configuration", b.Name, assetTypes[x]) + continue // If there are unsupported assets contained in config, skip. } cfgPS, err := b.Config.CurrencyPairs.Get(assetTypes[x]) if err != nil { @@ -304,7 +308,14 @@ func (b *Base) SetConfigPairs() error { if b.Config.CurrencyPairs.IsAssetEnabled(assetTypes[x]) == nil { enabledAsset = true } - b.CurrencyPairs.SetAssetEnabled(assetTypes[x], enabledAsset) + + err = b.CurrencyPairs.SetAssetEnabled(assetTypes[x], enabledAsset) + // Suppress error when assets are enabled by default and they are being + // enabled by config. A check for the inverse + // e.g. currency.ErrAssetAlreadyDisabled is not needed. + if err != nil && err != currency.ErrAssetAlreadyEnabled { + return err + } if b.Config.CurrencyPairs.UseGlobalFormat { b.CurrencyPairs.StorePairs(assetTypes[x], cfgPS.Available, false) diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index 6f417e4e593..1e0526d7000 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -111,10 +111,13 @@ func TestGetURL(t *testing.T) { Name: "HELAAAAAOOOOOOOOO", } b.API.Endpoints = b.NewEndpoints() - b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ + err := b.API.Endpoints.SetDefaultEndpoints(map[URL]string{ EdgeCase1: "http://test1.com/", EdgeCase2: "http://test2.com/", }) + if err != nil { + t.Fatal(err) + } getVal, err := b.API.Endpoints.GetURL(EdgeCase1) if err != nil { t.Error(err) @@ -189,7 +192,10 @@ func TestSetDefaultEndpoints(t *testing.T) { func TestHTTPClient(t *testing.T) { t.Parallel() r := Base{Name: "asdf"} - r.SetHTTPClientTimeout(time.Second * 5) + err := r.SetHTTPClientTimeout(time.Second * 5) + if err != nil { + t.Fatal(err) + } if r.GetHTTPClient().Timeout != time.Second*5 { t.Fatalf("TestHTTPClient unexpected value") @@ -210,10 +216,19 @@ func TestHTTPClient(t *testing.T) { } b := Base{Name: "RAWR"} - b.Requester = request.New(b.Name, - new(http.Client)) - b.SetHTTPClientTimeout(time.Second * 5) + b.Requester = request.New(b.Name, new(http.Client)) + err = b.SetHTTPClientTimeout(time.Second * 5) + if !errors.Is(err, errTransportNotSet) { + t.Fatalf("received: %v but expected: %v", err, errTransportNotSet) + } + + b.Requester = request.New(b.Name, &http.Client{Transport: new(http.Transport)}) + err = b.SetHTTPClientTimeout(time.Second * 5) + if err != nil { + t.Fatal(err) + } + if b.GetHTTPClient().Timeout != time.Second*5 { t.Fatalf("TestHTTPClient unexpected value") } @@ -656,7 +671,10 @@ func TestLoadConfigPairs(t *testing.T) { b.Config.CurrencyPairs.UseGlobalFormat = false b.CurrencyPairs.UseGlobalFormat = false - b.SetConfigPairs() + err = b.SetConfigPairs() + if err != nil { + t.Fatal(err) + } // Test four things: // 1) XRP-USD is set // 2) pair format is set for RequestFormat @@ -1286,7 +1304,10 @@ func TestSetupDefaults(t *testing.T) { }, }, ) - b.SetupDefaults(&cfg) + err = b.SetupDefaults(&cfg) + if err != nil { + t.Fatal(err) + } ps, err := cfg.CurrencyPairs.Get(asset.Spot) if err != nil { t.Fatal(err) @@ -1298,7 +1319,6 @@ func TestSetupDefaults(t *testing.T) { // Test websocket support b.Websocket = stream.New() b.Features.Supports.Websocket = true - b.SetupDefaults(&cfg) err = b.Websocket.Setup(&stream.WebsocketSetup{ Enabled: false, WebsocketTimeout: time.Second * 30, diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index 1ac3e77360d..a97b7513b20 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -336,9 +336,12 @@ func (e *EXMO) SendAuthenticatedHTTPRequest(epath exchange.URL, method, endpoint vals.Set("nonce", n) payload := vals.Encode() - hash := crypto.GetHMAC(crypto.HashSHA512, + hash, err := crypto.GetHMAC(crypto.HashSHA512, []byte(payload), []byte(e.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["Key"] = e.API.Credentials.Key diff --git a/exchanges/exmo/exmo_test.go b/exchanges/exmo/exmo_test.go index 90847406fb4..e3db13502c9 100644 --- a/exchanges/exmo/exmo_test.go +++ b/exchanges/exmo/exmo_test.go @@ -126,7 +126,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - e.GetFeeByType(feeBuilder) + _, err := e.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/ftx/ftx.go b/exchanges/ftx/ftx.go index f34afe4667d..c8ad3f19935 100644 --- a/exchanges/ftx/ftx.go +++ b/exchanges/ftx/ftx.go @@ -1153,18 +1153,24 @@ func (f *FTX) SendAuthHTTPRequest(ep exchange.URL, method, path string, data, re ts := strconv.FormatInt(time.Now().UnixNano()/1000000, 10) var body io.Reader var hmac, payload []byte + + sigPayload := ts + method + "/api" + path if data != nil { payload, err = json.Marshal(data) if err != nil { return nil, err } body = bytes.NewBuffer(payload) - sigPayload := ts + method + "/api" + path + string(payload) - hmac = crypto.GetHMAC(crypto.HashSHA256, []byte(sigPayload), []byte(f.API.Credentials.Secret)) - } else { - sigPayload := ts + method + "/api" + path - hmac = crypto.GetHMAC(crypto.HashSHA256, []byte(sigPayload), []byte(f.API.Credentials.Secret)) + sigPayload += string(payload) } + + hmac, err = crypto.GetHMAC(crypto.HashSHA256, + []byte(sigPayload), + []byte(f.API.Credentials.Secret)) + if err != nil { + return nil, err + } + headers := make(map[string]string) headers["FTX-KEY"] = f.API.Credentials.Key headers["FTX-SIGN"] = crypto.HexEncodeToString(hmac) diff --git a/exchanges/ftx/ftx_websocket.go b/exchanges/ftx/ftx_websocket.go index dd004ab46b8..8496a2a3698 100644 --- a/exchanges/ftx/ftx_websocket.go +++ b/exchanges/ftx/ftx_websocket.go @@ -76,11 +76,14 @@ func (f *FTX) WsConnect() error { func (f *FTX) WsAuth() error { intNonce := time.Now().UnixNano() / 1000000 strNonce := strconv.FormatInt(intNonce, 10) - hmac := crypto.GetHMAC( + hmac, err := crypto.GetHMAC( crypto.HashSHA256, []byte(strNonce+"websocket_login"), []byte(f.API.Credentials.Secret), ) + if err != nil { + return err + } sign := crypto.HexEncodeToString(hmac) req := Authenticate{Operation: "login", Args: AuthenticationData{ diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index b1112355914..19327fc13a8 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -399,7 +399,7 @@ func (g *Gateio) GetTradeHistory(symbol string) (TradHistoryResponse, error) { } // GenerateSignature returns hash for authenticated requests -func (g *Gateio) GenerateSignature(message string) []byte { +func (g *Gateio) GenerateSignature(message string) ([]byte, error) { return crypto.GetHMAC(crypto.HashSHA512, []byte(message), []byte(g.API.Credentials.Secret)) } @@ -418,7 +418,11 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint, headers["Content-Type"] = "application/x-www-form-urlencoded" headers["key"] = g.API.Credentials.Key - hmac := g.GenerateSignature(param) + hmac, err := g.GenerateSignature(param) + if err != nil { + return err + } + headers["sign"] = crypto.HexEncodeToString(hmac) urlPath := fmt.Sprintf("%s/%s/%s", ePoint, gateioAPIVersion, endpoint) diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index c6cae8a7e30..507d14674be 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -186,7 +186,10 @@ func TestGetTradeHistory(t *testing.T) { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - g.GetFeeByType(feeBuilder) + _, err := g.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/gateio/gateio_websocket.go b/exchanges/gateio/gateio_websocket.go index 0687d93e39a..ee2b7ed50cd 100644 --- a/exchanges/gateio/gateio_websocket.go +++ b/exchanges/gateio/gateio_websocket.go @@ -67,7 +67,10 @@ func (g *Gateio) WsConnect() error { func (g *Gateio) wsServerSignIn() error { nonce := int(time.Now().Unix() * 1000) - sigTemp := g.GenerateSignature(strconv.Itoa(nonce)) + sigTemp, err := g.GenerateSignature(strconv.Itoa(nonce)) + if err != nil { + return err + } signature := crypto.Base64Encode(sigTemp) signinWsRequest := WebsocketRequest{ ID: g.Websocket.Conn.GenerateMessageID(false), diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 3110929b974..677e94f3ab4 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -41,13 +41,6 @@ const ( geminiWithdraw = "withdraw/" geminiHeartbeat = "heartbeat" geminiVolume = "notionalvolume" - - // Too many requests returns this - geminiRateError = "429" - - // Assigned API key roles on creation - geminiRoleTrader = "trader" - geminiRoleFundManager = "fundmanager" ) // Gemini is the overarching type across the Gemini package, create multiple @@ -392,7 +385,12 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path stri } PayloadBase64 := crypto.Base64Encode(PayloadJSON) - hmac := crypto.GetHMAC(crypto.HashSHA512_384, []byte(PayloadBase64), []byte(g.API.Credentials.Secret)) + hmac, err := crypto.GetHMAC(crypto.HashSHA512_384, + []byte(PayloadBase64), + []byte(g.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["Content-Length"] = "0" diff --git a/exchanges/gemini/gemini_test.go b/exchanges/gemini/gemini_test.go index 50705c29af2..ee89ea986fe 100644 --- a/exchanges/gemini/gemini_test.go +++ b/exchanges/gemini/gemini_test.go @@ -241,8 +241,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - g.GetFeeByType(feeBuilder) - + _, err := g.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", diff --git a/exchanges/gemini/gemini_websocket.go b/exchanges/gemini/gemini_websocket.go index be5047ded0d..8c324b225e2 100644 --- a/exchanges/gemini/gemini_websocket.go +++ b/exchanges/gemini/gemini_websocket.go @@ -193,7 +193,13 @@ func (g *Gemini) WsAuth(dialer *websocket.Dialer) error { } endpoint := wsEndpoint + geminiWsOrderEvents PayloadBase64 := crypto.Base64Encode(PayloadJSON) - hmac := crypto.GetHMAC(crypto.HashSHA512_384, []byte(PayloadBase64), []byte(g.API.Credentials.Secret)) + hmac, err := crypto.GetHMAC(crypto.HashSHA512_384, + []byte(PayloadBase64), + []byte(g.API.Credentials.Secret)) + if err != nil { + return err + } + headers := http.Header{} headers.Add("Content-Length", "0") headers.Add("Content-Type", "text/plain") diff --git a/exchanges/hitbtc/hitbtc_test.go b/exchanges/hitbtc/hitbtc_test.go index 2890e1b265c..2b0e9d624fe 100644 --- a/exchanges/hitbtc/hitbtc_test.go +++ b/exchanges/hitbtc/hitbtc_test.go @@ -132,7 +132,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - h.GetFeeByType(feeBuilder) + _, err := h.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) @@ -453,7 +456,10 @@ func setupWsAuth(t *testing.T) { t.Fatal(err) } go h.wsReadData() - h.wsLogin() + err = h.wsLogin() + if err != nil { + t.Fatal(err) + } timer := time.NewTimer(time.Second) select { case loginError := <-h.Websocket.DataHandler: diff --git a/exchanges/hitbtc/hitbtc_websocket.go b/exchanges/hitbtc/hitbtc_websocket.go index 82a26c7c8c2..547f40d046f 100644 --- a/exchanges/hitbtc/hitbtc_websocket.go +++ b/exchanges/hitbtc/hitbtc_websocket.go @@ -15,7 +15,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" - "github.com/thrasher-corp/gocryptotrader/exchanges/nonce" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/stream" @@ -32,8 +31,6 @@ const ( errAuthFailed = 1002 ) -var requestID nonce.Nonce - // WsConnect starts a new connection with the websocket API func (h *HitBTC) WsConnect() error { if !h.Websocket.IsEnabled() || !h.IsEnabled() { @@ -564,7 +561,13 @@ func (h *HitBTC) wsLogin() error { } h.Websocket.SetCanUseAuthenticatedEndpoints(true) n := strconv.FormatInt(time.Now().Unix(), 10) - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(n), []byte(h.API.Credentials.Secret)) + hmac, err := crypto.GetHMAC(crypto.HashSHA256, + []byte(n), + []byte(h.API.Credentials.Secret)) + if err != nil { + return err + } + request := WsLoginRequest{ Method: "login", Params: WsLoginData{ @@ -576,7 +579,7 @@ func (h *HitBTC) wsLogin() error { ID: h.Websocket.Conn.GenerateMessageID(false), } - err := h.Websocket.Conn.SendJSONMessage(request) + err = h.Websocket.Conn.SendJSONMessage(request) if err != nil { h.Websocket.SetCanUseAuthenticatedEndpoints(false) return err diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 2262d893edf..90195b5da31 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -859,7 +859,14 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint s headers["Content-Type"] = "application/json" } - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(payload), []byte(h.API.Credentials.Secret)) + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, + []byte(payload), + []byte(h.API.Credentials.Secret)) + if err != nil { + return nil, err + } + values.Set("Signature", crypto.Base64Encode(hmac)) urlPath := ePoint + common.EncodeURLValues(endpoint, values) diff --git a/exchanges/huobi/huobi_futures.go b/exchanges/huobi/huobi_futures.go index d1dd4f6d31e..7abcf89b1f6 100644 --- a/exchanges/huobi/huobi_futures.go +++ b/exchanges/huobi/huobi_futures.go @@ -1134,7 +1134,14 @@ func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ep exchange.URL, method, endpoin } else { headers["Content-Type"] = "application/json" } - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(sigPath), []byte(h.API.Credentials.Secret)) + + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, + []byte(sigPath), + []byte(h.API.Credentials.Secret)) + if err != nil { + return nil, err + } sigValues := url.Values{} sigValues.Add("Signature", crypto.Base64Encode(hmac)) urlPath := diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index f69fa962e2a..3a0f11b1ca8 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -1840,7 +1840,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - h.GetFeeByType(feeBuilder) + _, err := h.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/huobi/huobi_websocket.go b/exchanges/huobi/huobi_websocket.go index 5369f120cbd..be4155dec6e 100644 --- a/exchanges/huobi/huobi_websocket.go +++ b/exchanges/huobi/huobi_websocket.go @@ -564,7 +564,7 @@ func (h *HUOBI) Unsubscribe(channelsToUnsubscribe []stream.ChannelSubscription) return nil } -func (h *HUOBI) wsGenerateSignature(timestamp, endpoint string) []byte { +func (h *HUOBI) wsGenerateSignature(timestamp, endpoint string) ([]byte, error) { values := url.Values{} values.Set("AccessKeyId", h.API.Credentials.Key) values.Set("SignatureMethod", signatureMethod) @@ -589,9 +589,12 @@ func (h *HUOBI) wsLogin() error { SignatureVersion: signatureVersion, Timestamp: timestamp, } - hmac := h.wsGenerateSignature(timestamp, wsAccountsOrdersEndPoint) + hmac, err := h.wsGenerateSignature(timestamp, wsAccountsOrdersEndPoint) + if err != nil { + return err + } request.Signature = crypto.Base64Encode(hmac) - err := h.Websocket.AuthConn.SendJSONMessage(request) + err = h.Websocket.AuthConn.SendJSONMessage(request) if err != nil { h.Websocket.SetCanUseAuthenticatedEndpoints(false) return err @@ -611,7 +614,10 @@ func (h *HUOBI) wsAuthenticatedSubscribe(operation, endpoint, topic string) erro Timestamp: timestamp, Topic: topic, } - hmac := h.wsGenerateSignature(timestamp, endpoint) + hmac, err := h.wsGenerateSignature(timestamp, endpoint) + if err != nil { + return err + } request.Signature = crypto.Base64Encode(hmac) return h.Websocket.AuthConn.SendJSONMessage(request) } @@ -629,7 +635,10 @@ func (h *HUOBI) wsGetAccountsList() (*WsAuthenticatedAccountsListResponse, error Timestamp: timestamp, Topic: wsAccountsList, } - hmac := h.wsGenerateSignature(timestamp, wsAccountListEndpoint) + hmac, err := h.wsGenerateSignature(timestamp, wsAccountListEndpoint) + if err != nil { + return nil, err + } request.Signature = crypto.Base64Encode(hmac) request.ClientID = h.Websocket.AuthConn.GenerateMessageID(true) resp, err := h.Websocket.AuthConn.SendMessageReturnResponse(request.ClientID, request) @@ -672,7 +681,10 @@ func (h *HUOBI) wsGetOrdersList(accountID int64, pair currency.Pair) (*WsAuthent States: "submitted,partial-filled", } - hmac := h.wsGenerateSignature(timestamp, wsOrdersListEndpoint) + hmac, err := h.wsGenerateSignature(timestamp, wsOrdersListEndpoint) + if err != nil { + return nil, err + } request.Signature = crypto.Base64Encode(hmac) request.ClientID = h.Websocket.AuthConn.GenerateMessageID(true) @@ -708,7 +720,10 @@ func (h *HUOBI) wsGetOrderDetails(orderID string) (*WsAuthenticatedOrderDetailRe Topic: wsOrdersDetail, OrderID: orderID, } - hmac := h.wsGenerateSignature(timestamp, wsOrdersDetailEndpoint) + hmac, err := h.wsGenerateSignature(timestamp, wsOrdersDetailEndpoint) + if err != nil { + return nil, err + } request.Signature = crypto.Base64Encode(hmac) request.ClientID = h.Websocket.AuthConn.GenerateMessageID(true) resp, err := h.Websocket.AuthConn.SendMessageReturnResponse(request.ClientID, request) diff --git a/exchanges/itbit/itbit.go b/exchanges/itbit/itbit.go index 717992457ea..b4793f3a3a4 100644 --- a/exchanges/itbit/itbit.go +++ b/exchanges/itbit/itbit.go @@ -332,8 +332,18 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path strin return nil, err } - hash := crypto.GetSHA256([]byte(n + string(message))) - hmac := crypto.GetHMAC(crypto.HashSHA512, []byte(urlPath+string(hash)), []byte(i.API.Credentials.Secret)) + var hash []byte + hash, err = crypto.GetSHA256([]byte(n + string(message))) + if err != nil { + return nil, err + } + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA512, + []byte(urlPath+string(hash)), + []byte(i.API.Credentials.Secret)) + if err != nil { + return nil, err + } signature := crypto.Base64Encode(hmac) headers := make(map[string]string) diff --git a/exchanges/itbit/itbit_test.go b/exchanges/itbit/itbit_test.go index 9ba1b823682..a7f0f19a2e6 100644 --- a/exchanges/itbit/itbit_test.go +++ b/exchanges/itbit/itbit_test.go @@ -171,7 +171,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - i.GetFeeByType(feeBuilder) + _, err := i.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 164bea02650..70df0075cc3 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -988,10 +988,21 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(ep exchange.URL, method string, pa nonce := k.Requester.GetNonce(true).String() params.Set("nonce", nonce) encoded := params.Encode() - shasum := crypto.GetSHA256([]byte(nonce + encoded)) - signature := crypto.Base64Encode(crypto.GetHMAC(crypto.HashSHA512, + var shasum []byte + shasum, err = crypto.GetSHA256([]byte(nonce + encoded)) + if err != nil { + return nil, err + } + + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA512, append([]byte(path), shasum...), - []byte(k.API.Credentials.Secret))) + []byte(k.API.Credentials.Secret)) + if err != nil { + return nil, err + } + + signature := crypto.Base64Encode(hmac) headers := make(map[string]string) headers["API-Key"] = k.API.Credentials.Key diff --git a/exchanges/kraken/kraken_futures.go b/exchanges/kraken/kraken_futures.go index e5a6585e6e9..4b326d48c25 100644 --- a/exchanges/kraken/kraken_futures.go +++ b/exchanges/kraken/kraken_futures.go @@ -249,11 +249,19 @@ func (k *Kraken) GetFuturesAccountData() (FuturesAccountsData, error) { return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresAccountData, nil, nil, &resp) } -func (k *Kraken) signFuturesRequest(endpoint, nonce, data string) string { +func (k *Kraken) signFuturesRequest(endpoint, nonce, data string) (string, error) { message := data + nonce + endpoint - hash := crypto.GetSHA256([]byte(message)) - hc := crypto.GetHMAC(crypto.HashSHA512, hash, []byte(k.API.Credentials.Secret)) - return base64.StdEncoding.EncodeToString(hc) + hash, err := crypto.GetSHA256([]byte(message)) + if err != nil { + return "", err + } + hc, err := crypto.GetHMAC(crypto.HashSHA512, + hash, + []byte(k.API.Credentials.Secret)) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(hc), nil } // SendFuturesAuthRequest will send an auth req @@ -277,7 +285,10 @@ func (k *Kraken) SendFuturesAuthRequest(method, path string, postData url.Values postData.Set("json", string(temp)) reqData = "json=" + string(temp) } - sig := k.signFuturesRequest(path, nonce, reqData) + sig, err := k.signFuturesRequest(path, nonce, reqData) + if err != nil { + return nil, err + } headers := map[string]string{ "APIKey": k.API.Credentials.Key, "Authent": sig, diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index 15407e82055..704b61198f1 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -1,6 +1,7 @@ package kraken import ( + "fmt" "log" "net/http" "os" @@ -687,7 +688,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - k.GetFeeByType(feeBuilder) + _, err := k.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) @@ -1127,7 +1131,12 @@ func setupWsTests(t *testing.T) { go k.wsFunnelConnectionData(k.Websocket.Conn, comms) go k.wsFunnelConnectionData(k.Websocket.AuthConn, comms) go k.wsReadData(comms) - go k.wsPingHandler() + go func() { + err := k.wsPingHandler() + if err != nil { + fmt.Println("error:", err) + } + }() wsSetupRan = true } diff --git a/exchanges/lbank/lbank.go b/exchanges/lbank/lbank.go index d3b760f8287..b38d4d2b8f9 100644 --- a/exchanges/lbank/lbank.go +++ b/exchanges/lbank/lbank.go @@ -548,9 +548,15 @@ func (l *Lbank) sign(data string) (string, error) { if l.privateKey == nil { return "", errors.New("private key not loaded") } - md5hash := gctcrypto.GetMD5([]byte(data)) + md5hash, err := gctcrypto.GetMD5([]byte(data)) + if err != nil { + return "", err + } m := strings.ToUpper(gctcrypto.HexEncodeToString(md5hash)) - s := gctcrypto.GetSHA256([]byte(m)) + s, err := gctcrypto.GetSHA256([]byte(m)) + if err != nil { + return "", err + } r, err := rsa.SignPKCS1v15(rand.Reader, l.privateKey, crypto.SHA256, s) if err != nil { return "", err diff --git a/exchanges/lbank/lbank_test.go b/exchanges/lbank/lbank_test.go index 4f1bd941b1a..40cbd6cfeda 100644 --- a/exchanges/lbank/lbank_test.go +++ b/exchanges/lbank/lbank_test.go @@ -297,8 +297,11 @@ func TestSign(t *testing.T) { t.Skip("API keys required but not set, skipping test") } l.API.Credentials.Secret = testAPISecret - l.loadPrivKey() - _, err := l.sign("hello123") + err := l.loadPrivKey() + if err != nil { + t.Fatal(err) + } + _, err = l.sign("hello123") if err != nil { t.Error(err) } diff --git a/exchanges/localbitcoins/localbitcoins.go b/exchanges/localbitcoins/localbitcoins.go index 977ece9acaf..a8dc3309b26 100644 --- a/exchanges/localbitcoins/localbitcoins.go +++ b/exchanges/localbitcoins/localbitcoins.go @@ -761,7 +761,12 @@ func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(ep exchange.URL, method, pa fullPath := "/api/" + path encoded := params.Encode() message := n + l.API.Credentials.Key + fullPath + encoded - hmac := crypto.GetHMAC(crypto.HashSHA256, []byte(message), []byte(l.API.Credentials.Secret)) + hmac, err := crypto.GetHMAC(crypto.HashSHA256, + []byte(message), + []byte(l.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["Apiauth-Key"] = l.API.Credentials.Key headers["Apiauth-Nonce"] = n diff --git a/exchanges/localbitcoins/localbitcoins_test.go b/exchanges/localbitcoins/localbitcoins_test.go index 28ba9691f9a..996041cec0d 100644 --- a/exchanges/localbitcoins/localbitcoins_test.go +++ b/exchanges/localbitcoins/localbitcoins_test.go @@ -121,7 +121,10 @@ func TestGetOrderbook(t *testing.T) { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - l.GetFeeByType(feeBuilder) + _, err := l.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/mock/server.go b/exchanges/mock/server.go index 31c8d7f693b..dd7df16b240 100644 --- a/exchanges/mock/server.go +++ b/exchanges/mock/server.go @@ -228,7 +228,10 @@ func MessageWriteJSON(w http.ResponseWriter, status int, data interface{}) { err := json.NewEncoder(w).Encode(data) if err != nil { w.WriteHeader(http.StatusBadRequest) - w.Write([]byte(err.Error())) + _, wErr := w.Write([]byte(err.Error())) + if wErr != nil { + log.Println("Mock Test Failure - Writing to HTTP connection", wErr) + } log.Fatal("Mock Test Failure - JSON encode error", err) } } diff --git a/exchanges/okcoin/okcoin_test.go b/exchanges/okcoin/okcoin_test.go index 40d165a678e..ed1797ad1c9 100644 --- a/exchanges/okcoin/okcoin_test.go +++ b/exchanges/okcoin/okcoin_test.go @@ -879,7 +879,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - o.GetFeeByType(feeBuilder) + _, err := o.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index 098906d43a2..f68962c5390 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -58,7 +58,10 @@ func (o *OKCoin) SetDefaults() { requestFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter} configFmt := ¤cy.PairFormat{Uppercase: true, Delimiter: currency.DashDelimiter} - o.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot, asset.Margin) + err := o.SetGlobalPairsManager(requestFmt, configFmt, asset.Spot, asset.Margin) + if err != nil { + log.Errorln(log.ExchangeSys, err) + } o.Features = exchange.Features{ Supports: exchange.FeaturesSupported{ @@ -135,7 +138,7 @@ func (o *OKCoin) SetDefaults() { request.WithLimiter(request.NewBasicRateLimit(okCoinRateInterval, okCoinStandardRequestRate)), ) o.API.Endpoints = o.NewEndpoints() - err := o.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ + err = o.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{ exchange.RestSpot: okCoinAPIURL, exchange.WebsocketSpot: okCoinWebsocketURL, }) diff --git a/exchanges/okex/okex_test.go b/exchanges/okex/okex_test.go index 5ca7f08c8f6..474a298f41e 100644 --- a/exchanges/okex/okex_test.go +++ b/exchanges/okex/okex_test.go @@ -1699,7 +1699,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - o.GetFeeByType(feeBuilder) + _, err := o.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/okgroup/okgroup.go b/exchanges/okgroup/okgroup.go index 7cd4cc76a24..d023132c807 100644 --- a/exchanges/okgroup/okgroup.go +++ b/exchanges/okgroup/okgroup.go @@ -22,8 +22,6 @@ import ( ) const ( - okGroupAuthRate = 0 - okGroupUnauthRate = 0 // OKGroupAPIPath const to help with api url formatting OKGroupAPIPath = "api/" // API subsections @@ -83,8 +81,6 @@ const ( okGroupGetRepayment = "repayment" ) -var errMissValue = errors.New("warning - resp value is missing from exchange") - // OKGroup is the overaching type across the all of OKEx's exchange methods type OKGroup struct { exchange.Base @@ -596,9 +592,14 @@ func (o *OKGroup) SendHTTPRequest(ep exchange.URL, httpMethod, requestType, requ if authenticated { signPath := fmt.Sprintf("/%v%v%v%v", OKGroupAPIPath, requestType, o.APIVersion, requestPath) - hmac := crypto.GetHMAC(crypto.HashSHA256, + + var hmac []byte + hmac, err = crypto.GetHMAC(crypto.HashSHA256, []byte(utcTime+httpMethod+signPath+string(payload)), []byte(o.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers["OK-ACCESS-KEY"] = o.API.Credentials.Key headers["OK-ACCESS-SIGN"] = crypto.Base64Encode(hmac) headers["OK-ACCESS-TIMESTAMP"] = utcTime diff --git a/exchanges/okgroup/okgroup_websocket.go b/exchanges/okgroup/okgroup_websocket.go index a5b11dfd2ac..59400976fca 100644 --- a/exchanges/okgroup/okgroup_websocket.go +++ b/exchanges/okgroup/okgroup_websocket.go @@ -211,10 +211,13 @@ func (o *OKGroup) WsLogin() error { o.Websocket.SetCanUseAuthenticatedEndpoints(true) unixTime := time.Now().UTC().Unix() signPath := "/users/self/verify" - hmac := crypto.GetHMAC(crypto.HashSHA256, + hmac, err := crypto.GetHMAC(crypto.HashSHA256, []byte(strconv.FormatInt(unixTime, 10)+http.MethodGet+signPath), []byte(o.API.Credentials.Secret), ) + if err != nil { + return err + } base64 := crypto.Base64Encode(hmac) request := WebsocketEventRequest{ Operation: "login", @@ -225,7 +228,7 @@ func (o *OKGroup) WsLogin() error { base64, }, } - _, err := o.Websocket.Conn.SendMessageReturnResponse("login", request) + _, err = o.Websocket.Conn.SendMessageReturnResponse("login", request) if err != nil { o.Websocket.SetCanUseAuthenticatedEndpoints(false) return err diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 398f2950d4b..6f254c82fcb 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -866,9 +866,12 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoin values.Set("nonce", strconv.FormatInt(time.Now().UnixNano(), 10)) values.Set("command", endpoint) - hmac := crypto.GetHMAC(crypto.HashSHA512, + hmac, err := crypto.GetHMAC(crypto.HashSHA512, []byte(values.Encode()), []byte(p.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers["Sign"] = crypto.HexEncodeToString(hmac) path := fmt.Sprintf("%s/%s", ePoint, poloniexAPITradingEndpoint) diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index ff93857b9a1..63f4d5f064a 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -108,7 +108,10 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - p.GetFeeByType(feeBuilder) + _, err := p.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", diff --git a/exchanges/poloniex/poloniex_websocket.go b/exchanges/poloniex/poloniex_websocket.go index aba4a50ae91..c3cf2771f1b 100644 --- a/exchanges/poloniex/poloniex_websocket.go +++ b/exchanges/poloniex/poloniex_websocket.go @@ -616,9 +616,12 @@ channels: func (p *Poloniex) wsSendAuthorisedCommand(command string) error { nonce := fmt.Sprintf("nonce=%v", time.Now().UnixNano()) - hmac := crypto.GetHMAC(crypto.HashSHA512, + hmac, err := crypto.GetHMAC(crypto.HashSHA512, []byte(nonce), []byte(p.API.Credentials.Secret)) + if err != nil { + return err + } request := WsAuthorisationRequest{ Command: command, Channel: 1000, diff --git a/exchanges/request/request_test.go b/exchanges/request/request_test.go index e6041a4a38f..e7b396c5f25 100644 --- a/exchanges/request/request_test.go +++ b/exchanges/request/request_test.go @@ -33,11 +33,17 @@ func TestMain(m *testing.M) { sm := http.NewServeMux() sm.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "application/json") - io.WriteString(w, `{"response":true}`) + _, err := io.WriteString(w, `{"response":true}`) + if err != nil { + log.Fatal(err) + } }) sm.HandleFunc("/error", func(w http.ResponseWriter, req *http.Request) { w.WriteHeader(http.StatusBadRequest) - io.WriteString(w, `{"error":true}`) + _, err := io.WriteString(w, `{"error":true}`) + if err != nil { + log.Fatal(err) + } }) sm.HandleFunc("/timeout", func(w http.ResponseWriter, req *http.Request) { time.Sleep(time.Millisecond * 100) @@ -48,10 +54,16 @@ func TestMain(m *testing.M) { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) - io.WriteString(w, `{"response":false}`) + _, err := io.WriteString(w, `{"response":false}`) + if err != nil { + log.Fatal(err) + } return } - io.WriteString(w, `{"response":true}`) + _, err := io.WriteString(w, `{"response":true}`) + if err != nil { + log.Fatal(err) + } }) sm.HandleFunc("/rate-retry", func(w http.ResponseWriter, req *http.Request) { if !serverLimitRetry.Allow() { @@ -59,15 +71,24 @@ func TestMain(m *testing.M) { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) - io.WriteString(w, `{"response":false}`) + _, err := io.WriteString(w, `{"response":false}`) + if err != nil { + log.Fatal(err) + } return } - io.WriteString(w, `{"response":true}`) + _, err := io.WriteString(w, `{"response":true}`) + if err != nil { + log.Fatal(err) + } }) sm.HandleFunc("/always-retry", func(w http.ResponseWriter, req *http.Request) { w.Header().Add("Retry-After", time.Now().Format(time.RFC1123)) w.WriteHeader(http.StatusTooManyRequests) - io.WriteString(w, `{"response":false}`) + _, err := io.WriteString(w, `{"response":false}`) + if err != nil { + log.Fatal(err) + } }) server := httptest.NewServer(sm) diff --git a/exchanges/stats/stats_test.go b/exchanges/stats/stats_test.go index ad8c80a2131..96ce135da2e 100644 --- a/exchanges/stats/stats_test.go +++ b/exchanges/stats/stats_test.go @@ -150,7 +150,11 @@ func TestAdd(t *testing.T) { if err != nil { t.Fatal(err) } - Add(testExchange, p, asset.Spot, 300, 1000) + + err = Add(testExchange, p, asset.Spot, 300, 1000) + if err != nil { + t.Fatal(err) + } if Items[2].Pair.String() != "ETHUSD" { t.Fatal("stats Add did not add exchange info.") diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index 623c35ecfc6..1e7cf86b8e7 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -303,7 +303,12 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, param params.Set("method", path) encoded := params.Encode() - hmac := crypto.GetHMAC(crypto.HashSHA512, []byte(encoded), []byte(y.API.Credentials.Secret)) + hmac, err := crypto.GetHMAC(crypto.HashSHA512, + []byte(encoded), + []byte(y.API.Credentials.Secret)) + if err != nil { + return nil, err + } headers := make(map[string]string) headers["Key"] = y.API.Credentials.Key diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index 4f660c0a4a2..f4d4bf486c5 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -169,7 +169,10 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - y.GetFeeByType(feeBuilder) + _, err := y.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !areTestAPIKeysSet() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/zb/zb.go b/exchanges/zb/zb.go index 7b004b281fd..c306717f760 100644 --- a/exchanges/zb/zb.go +++ b/exchanges/zb/zb.go @@ -311,9 +311,17 @@ func (z *ZB) SendAuthenticatedHTTPRequest(ep exchange.URL, httpMethod string, pa } params.Set("accesskey", z.API.Credentials.Key) - hmac := crypto.GetHMAC(crypto.HashMD5, + hex, err := crypto.Sha1ToHex(z.API.Credentials.Secret) + if err != nil { + return err + } + + hmac, err := crypto.GetHMAC(crypto.HashMD5, []byte(params.Encode()), - []byte(crypto.Sha1ToHex(z.API.Credentials.Secret))) + []byte(hex)) + if err != nil { + return err + } var intermediary json.RawMessage newRequest := func() (*request.Item, error) { diff --git a/exchanges/zb/zb_test.go b/exchanges/zb/zb_test.go index 8ed23fe18ee..6771a361e55 100644 --- a/exchanges/zb/zb_test.go +++ b/exchanges/zb/zb_test.go @@ -141,7 +141,10 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - z.GetFeeByType(feeBuilder) + _, err := z.GetFeeByType(feeBuilder) + if err != nil { + t.Fatal(err) + } if !z.ValidateAPICredentials() { if feeBuilder.FeeType != exchange.OfflineTradeFee { t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType) diff --git a/exchanges/zb/zb_websocket.go b/exchanges/zb/zb_websocket.go index 42a69538832..d842df09c9f 100644 --- a/exchanges/zb/zb_websocket.go +++ b/exchanges/zb/zb_websocket.go @@ -21,7 +21,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/exchanges/stream" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" "github.com/thrasher-corp/gocryptotrader/exchanges/trade" - "github.com/thrasher-corp/gocryptotrader/log" ) const ( @@ -301,16 +300,22 @@ func (z *ZB) Subscribe(channelsToSubscribe []stream.ChannelSubscription) error { return nil } -func (z *ZB) wsGenerateSignature(request interface{}) string { +func (z *ZB) wsGenerateSignature(request interface{}) (string, error) { jsonResponse, err := json.Marshal(request) if err != nil { - log.Error(log.ExchangeSys, err) - return "" + return "", err } - hmac := crypto.GetHMAC(crypto.HashMD5, + hex, err := crypto.Sha1ToHex(z.API.Credentials.Secret) + if err != nil { + return "", err + } + hmac, err := crypto.GetHMAC(crypto.HashMD5, jsonResponse, - []byte(crypto.Sha1ToHex(z.API.Credentials.Secret))) - return fmt.Sprintf("%x", hmac) + []byte(hex)) + if err != nil { + return "", err + } + return fmt.Sprintf("%x", hmac), nil } func (z *ZB) wsFixInvalidJSON(json []byte) []byte { @@ -340,7 +345,12 @@ func (z *ZB) wsAddSubUser(username, password string) (*WsGetSubUserListResponse, request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key request.No = z.Websocket.Conn.GenerateMessageID(true) - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { return nil, err @@ -375,7 +385,12 @@ func (z *ZB) wsGetSubUserList() (*WsGetSubUserListResponse, error) { request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key request.No = z.Websocket.Conn.GenerateMessageID(true) - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -411,7 +426,12 @@ func (z *ZB) wsDoTransferFunds(pair currency.Code, amount float64, fromUserName, request.Channel = "doTransferFunds" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -449,7 +469,12 @@ func (z *ZB) wsCreateSubUserKey(assetPerm, entrustPerm, leverPerm, moneyPerm boo request.Channel = "createSubUserKey" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -484,7 +509,12 @@ func (z *ZB) wsSubmitOrder(pair currency.Pair, amount, price float64, tradeType request.Channel = pair.String() + "_order" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -517,7 +547,12 @@ func (z *ZB) wsCancelOrder(pair currency.Pair, orderID int64) (*WsCancelOrderRes request.Channel = pair.String() + "_cancelorder" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -550,7 +585,12 @@ func (z *ZB) wsGetOrder(pair currency.Pair, orderID int64) (*WsGetOrderResponse, request.Channel = pair.String() + "_getorder" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -584,7 +624,13 @@ func (z *ZB) wsGetOrders(pair currency.Pair, pageIndex, tradeType int64) (*WsGet request.Channel = pair.String() + "_getorders" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } + resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { return nil, err @@ -617,7 +663,12 @@ func (z *ZB) wsGetOrdersIgnoreTradeType(pair currency.Pair, pageIndex, pageSize request.Channel = pair.String() + "_getordersignoretradetype" request.Event = zWebsocketAddChannel request.Accesskey = z.API.Credentials.Key - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { @@ -649,7 +700,12 @@ func (z *ZB) wsGetAccountInfoRequest() (*WsGetAccountInfoResponse, error) { Accesskey: z.API.Credentials.Key, No: z.Websocket.Conn.GenerateMessageID(true), } - request.Sign = z.wsGenerateSignature(request) + + var err error + request.Sign, err = z.wsGenerateSignature(request) + if err != nil { + return nil, err + } resp, err := z.Websocket.Conn.SendMessageReturnResponse(request.No, request) if err != nil { diff --git a/gctscript/vm/vm.go b/gctscript/vm/vm.go index 6b345c531ff..923619445d8 100644 --- a/gctscript/vm/vm.go +++ b/gctscript/vm/vm.go @@ -288,7 +288,11 @@ func (vm *VM) getHash() string { log.Errorln(log.GCTScriptMgr, err) } contents = append(contents, vm.ShortName()...) - return hex.EncodeToString(crypto.GetSHA256(contents)) + hash, err := crypto.GetSHA256(contents) + if err != nil { + log.Errorln(log.GCTScriptMgr, err) + } + return hex.EncodeToString(hash) } func (vmc *vmscount) add() { diff --git a/gctscript/vm/vm_test.go b/gctscript/vm/vm_test.go index 50768caea37..1062c8e5278 100644 --- a/gctscript/vm/vm_test.go +++ b/gctscript/vm/vm_test.go @@ -25,8 +25,8 @@ var ( testBrokenScript = filepath.Join("..", "..", "testdata", "gctscript", "broken.gct") testScriptRunner = filepath.Join("..", "..", "testdata", "gctscript", "timer.gct") testScriptRunner1s = filepath.Join("..", "..", "testdata", "gctscript", "1s_timer.gct") - testScriptRunnerInvalid = filepath.Join("..", "..", "testdata", "gctscript", "invalid_timer.gct") testScriptRunnerNegative = filepath.Join("..", "..", "testdata", "gctscript", "negative_timer.gct") + testScriptRunnerInvalid = filepath.Join("..", "..", "testdata", "gctscript", "invalid_timer.gct") ) func TestMain(m *testing.M) { @@ -325,6 +325,34 @@ func TestVMWithRunnerNegativeTimer(t *testing.T) { } } +func TestVMWithRunnerInvalidTimer(t *testing.T) { + manager := GctScriptManager{ + config: configHelper(true, true, maxTestVirtualMachines), + started: 1, + } + vmCount := VMSCount.Len() + VM := manager.New() + if VM == nil { + t.Fatal("Failed to allocate new VM exiting") + } + err := VM.Load(testScriptRunnerInvalid) + if err != nil { + t.Fatal(err) + } + if VMSCount.Len() == vmCount { + t.Fatal("expected VM count to increase") + } + VM.CompileAndRun() + err = VM.Shutdown() + if err == nil { + t.Fatal("VM should not be running with invalid timer") + } + + if VMSCount.Len() == vmCount-1 { + t.Fatal("expected VM count to decrease") + } +} + func TestShutdownAll(t *testing.T) { manager := GctScriptManager{ config: configHelper(true, true, maxTestVirtualMachines), diff --git a/log/logger_test.go b/log/logger_test.go index 22b0299a7eb..c4c8c1fc1b6 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -210,13 +210,16 @@ func BenchmarkInfoln(b *testing.B) { func TestNewLogEvent(t *testing.T) { w := &bytes.Buffer{} - logger.newLogEvent("out", "header", "SUBLOGGER", w) + err := logger.newLogEvent("out", "header", "SUBLOGGER", w) + if err != nil { + t.Fatal(err) + } if w.String() == "" { t.Error("newLogEvent() failed expected output got empty string") } - err := logger.newLogEvent("out", "header", "SUBLOGGER", nil) + err = logger.newLogEvent("out", "header", "SUBLOGGER", nil) if err == nil { t.Error("Error expected with output is set to nil") } @@ -225,23 +228,24 @@ func TestNewLogEvent(t *testing.T) { func TestInfo(t *testing.T) { w := &bytes.Buffer{} - tempSL := SubLogger{ - "TESTYMCTESTALOT", - splitLevel("INFO|WARN|DEBUG|ERROR"), - w, - } + sl := registerNewSubLogger("TESTYMCTESTALOT") + sl.Levels = splitLevel("INFO|WARN|DEBUG|ERROR") + sl.output = w - Info(&tempSL, "Hello") + Info(sl, "Hello") if w.String() == "" { t.Error("expected Info() to write output to buffer") } - tempSL.output = nil + sl.output = nil w.Reset() - SetLevel("TESTYMCTESTALOT", "INFO") - Debug(&tempSL, "HelloHello") + _, err := SetLevel("TESTYMCTESTALOT", "INFO") + if err != nil { + t.Fatal(err) + } + Debug(sl, "HelloHello") if w.String() != "" { t.Error("Expected output buffer to be empty but Debug wrote to output") @@ -251,14 +255,20 @@ func TestInfo(t *testing.T) { func TestSubLoggerName(t *testing.T) { w := &bytes.Buffer{} registerNewSubLogger("sublogger") - logger.newLogEvent("out", "header", "SUBLOGGER", w) + err := logger.newLogEvent("out", "header", "SUBLOGGER", w) + if err != nil { + t.Fatal(err) + } if !strings.Contains(w.String(), "SUBLOGGER") { t.Error("Expected SUBLOGGER in output") } logger.ShowLogSystemName = false w.Reset() - logger.newLogEvent("out", "header", "SUBLOGGER", w) + err = logger.newLogEvent("out", "header", "SUBLOGGER", w) + if err != nil { + t.Fatal(err) + } if strings.Contains(w.String(), "SUBLOGGER") { t.Error("Unexpected SUBLOGGER in output") }