Skip to content

Commit

Permalink
Add nonce package for exchanges
Browse files Browse the repository at this point in the history
  • Loading branch information
thrasher- committed Aug 21, 2017
1 parent 0fea988 commit f3c1f48
Show file tree
Hide file tree
Showing 20 changed files with 256 additions and 61 deletions.
12 changes: 8 additions & 4 deletions exchanges/alphapoint/alphapoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,17 @@ func (a *Alphapoint) SendAuthenticatedHTTPRequest(method, path string, data map[
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, a.Name)
}

if a.Nonce.Get() == 0 {
a.Nonce.Set(time.Now().UnixNano())
} else {
a.Nonce.Inc()
}

headers := make(map[string]string)
headers["Content-Type"] = "application/json"
data["apiKey"] = a.APIKey
nonce := time.Now().UnixNano()
nonceStr := strconv.FormatInt(nonce, 10)
data["apiNonce"] = nonce
hmac := common.GetHMAC(common.HashSHA256, []byte(nonceStr+a.ClientID+a.APIKey), []byte(a.APISecret))
data["apiNonce"] = a.Nonce.Get()
hmac := common.GetHMAC(common.HashSHA256, []byte(a.Nonce.String()+a.ClientID+a.APIKey), []byte(a.APISecret))
data["apiSig"] = common.StringToUpper(common.HexEncodeToString(hmac))
path = fmt.Sprintf("%s/ajax/v%s/%s", a.APIUrl, ALPHAPOINT_API_VERSION, path)
PayloadJSON, err := common.JSONEncode(data)
Expand Down
16 changes: 11 additions & 5 deletions exchanges/anx/anx.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,14 @@ func (a *ANX) SendAuthenticatedHTTPRequest(path string, params map[string]interf
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, a.Name)
}

if a.Nonce.Get() == 0 {
a.Nonce.Set(time.Now().UnixNano())
} else {
a.Nonce.Inc()
}

request := make(map[string]interface{})
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)[0:13]
request["nonce"] = a.Nonce.String()[0:13]
path = fmt.Sprintf("api/%s/%s", ANX_API_VERSION, path)

if params != nil {
Expand All @@ -300,23 +306,23 @@ func (a *ANX) SendAuthenticatedHTTPRequest(path string, params map[string]interf
}
}

PayloadJson, err := common.JSONEncode(request)
PayloadJSON, err := common.JSONEncode(request)

if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}

if a.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
log.Printf("Request JSON: %s\n", PayloadJSON)
}

hmac := common.GetHMAC(common.HashSHA512, []byte(path+string("\x00")+string(PayloadJson)), []byte(a.APISecret))
hmac := common.GetHMAC(common.HashSHA512, []byte(path+string("\x00")+string(PayloadJSON)), []byte(a.APISecret))
headers := make(map[string]string)
headers["Rest-Key"] = a.APIKey
headers["Rest-Sign"] = common.Base64Encode([]byte(hmac))
headers["Content-Type"] = "application/json"

resp, err := common.SendHTTPRequest("POST", ANX_API_URL+path, headers, bytes.NewBuffer(PayloadJson))
resp, err := common.SendHTTPRequest("POST", ANX_API_URL+path, headers, bytes.NewBuffer(PayloadJSON))

if a.Verbose {
log.Printf("Received raw: \n%s\n", resp)
Expand Down
14 changes: 10 additions & 4 deletions exchanges/bitfinex/bitfinex.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,26 +593,32 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().UnixNano())
} else {
b.Nonce.Inc()
}

request := make(map[string]interface{})
request["request"] = fmt.Sprintf("/v%s/%s", BITFINEX_API_VERSION, path)
request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10)
request["nonce"] = b.Nonce.String()

if params != nil {
for key, value := range params {
request[key] = value
}
}

PayloadJson, err := common.JSONEncode(request)
PayloadJSON, err := common.JSONEncode(request)
if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}

if b.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
log.Printf("Request JSON: %s\n", PayloadJSON)
}

PayloadBase64 := common.Base64Encode(PayloadJson)
PayloadBase64 := common.Base64Encode(PayloadJSON)
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(b.APISecret))
headers := make(map[string]string)
headers["X-BFX-APIKEY"] = b.APIKey
Expand Down
10 changes: 7 additions & 3 deletions exchanges/bitstamp/bitstamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,15 +472,19 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().UnixNano())
} else {
b.Nonce.Inc()
}

if values == nil {
values = url.Values{}
}

values.Set("key", b.APIKey)
values.Set("nonce", nonce)
hmac := common.GetHMAC(common.HashSHA256, []byte(nonce+b.ClientID+b.APIKey), []byte(b.APISecret))
values.Set("nonce", b.Nonce.String())
hmac := common.GetHMAC(common.HashSHA256, []byte(b.Nonce.String()+b.ClientID+b.APIKey), []byte(b.APISecret))
values.Set("signature", common.StringToUpper(common.HexEncodeToString(hmac)))

if v2 {
Expand Down
8 changes: 6 additions & 2 deletions exchanges/bittrex/bittrex.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,14 @@ func (b *Bittrex) SendAuthenticatedHTTPRequest(path string, values url.Values, r
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

nonce := strconv.FormatInt(time.Now().UnixNano(), 10)
if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().UnixNano())
} else {
b.Nonce.Inc()
}
values.Set("apikey", b.APIKey)
values.Set("apisecret", b.APISecret)
values.Set("nonce", nonce)
values.Set("nonce", b.Nonce.String())
rawQuery := path + "?" + values.Encode()
hmac := common.GetHMAC(
common.HashSHA512, []byte(rawQuery), []byte(b.APISecret),
Expand Down
10 changes: 7 additions & 3 deletions exchanges/btcc/btcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,12 @@ func (b *BTCC) SendAuthenticatedHTTPRequest(method string, params []interface{})
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

nonce := strconv.FormatInt(time.Now().UnixNano(), 10)[0:16]
encoded := fmt.Sprintf("tonce=%s&accesskey=%s&requestmethod=post&id=%d&method=%s&params=", nonce, b.APIKey, 1, method)
if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().UnixNano())
} else {
b.Nonce.Inc()
}
encoded := fmt.Sprintf("tonce=%s&accesskey=%s&requestmethod=post&id=%d&method=%s&params=", b.Nonce.String()[0:16], b.APIKey, 1, method)

if len(params) == 0 {
params = make([]interface{}, 0)
Expand Down Expand Up @@ -581,7 +585,7 @@ func (b *BTCC) SendAuthenticatedHTTPRequest(method string, params []interface{})
headers := make(map[string]string)
headers["Content-type"] = "application/json-rpc"
headers["Authorization"] = "Basic " + common.Base64Encode([]byte(b.APIKey+":"+common.HexEncodeToString(hmac)))
headers["Json-Rpc-Tonce"] = nonce
headers["Json-Rpc-Tonce"] = b.Nonce.String()

resp, err := common.SendHTTPRequest("POST", apiURL, headers, strings.NewReader(string(data)))

Expand Down
8 changes: 6 additions & 2 deletions exchanges/btce/btce.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,12 @@ func (b *BTCE) SendAuthenticatedHTTPRequest(method string, values url.Values, re
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

nonce := strconv.FormatInt(time.Now().Unix(), 10)
values.Set("nonce", nonce)
if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().Unix())
} else {
b.Nonce.Inc()
}
values.Set("nonce", b.Nonce.String())
values.Set("method", method)

encoded := values.Encode()
Expand Down
13 changes: 8 additions & 5 deletions exchanges/btcmarkets/btcmarkets.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"fmt"
"log"
"net/url"
"strconv"
"time"

"github.com/thrasher-/gocryptotrader/common"
Expand Down Expand Up @@ -285,7 +284,11 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interfa
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, b.Name)
}

nonce := strconv.FormatInt(time.Now().UnixNano(), 10)[0:13]
if b.Nonce.Get() == 0 {
b.Nonce.Set(time.Now().UnixNano())
} else {
b.Nonce.Inc()
}
request := ""
payload := []byte("")

Expand All @@ -294,9 +297,9 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interfa
if err != nil {
return err
}
request = path + "\n" + nonce + "\n" + string(payload)
request = path + "\n" + b.Nonce.String()[0:13] + "\n" + string(payload)
} else {
request = path + "\n" + nonce + "\n"
request = path + "\n" + b.Nonce.String()[0:13] + "\n"
}

hmac := common.GetHMAC(common.HashSHA512, []byte(request), []byte(b.APISecret))
Expand All @@ -310,7 +313,7 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data interfa
headers["Accept-Charset"] = "UTF-8"
headers["Content-Type"] = "application/json"
headers["apikey"] = b.APIKey
headers["timestamp"] = nonce
headers["timestamp"] = b.Nonce.String()[0:13]
headers["signature"] = common.Base64Encode(hmac)

resp, err := common.SendHTTPRequest(reqType, BTCMARKETS_API_URL+path, headers, bytes.NewBuffer(payload))
Expand Down
8 changes: 6 additions & 2 deletions exchanges/coinut/coinut.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,17 @@ func (c *COINUT) SendAuthenticatedHTTPRequest(apiRequest string, params map[stri
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, c.Name)
}

timestamp := time.Now().Unix()
if c.Nonce.Get() == 0 {
c.Nonce.Set(time.Now().Unix())
} else {
c.Nonce.Inc()
}
payload := []byte("")

if params == nil {
params = map[string]interface{}{}
}
params["nonce"] = timestamp
params["nonce"] = c.Nonce.Get()
params["request"] = apiRequest

payload, err = common.JSONEncode(params)
Expand Down
2 changes: 2 additions & 0 deletions exchanges/exchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/thrasher-/gocryptotrader/common"
"github.com/thrasher-/gocryptotrader/config"
"github.com/thrasher-/gocryptotrader/currency/pair"
"github.com/thrasher-/gocryptotrader/exchanges/nonce"
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-/gocryptotrader/exchanges/ticker"
)
Expand Down Expand Up @@ -43,6 +44,7 @@ type Base struct {
RESTPollingDelay time.Duration
AuthenticatedAPISupport bool
APISecret, APIKey, ClientID string
Nonce nonce.Nonce
TakerFee, MakerFee, Fee float64
BaseCurrencies []string
AvailablePairs []string
Expand Down
11 changes: 8 additions & 3 deletions exchanges/gdax/gdax.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,12 @@ func (g *GDAX) SendAuthenticatedHTTPRequest(method, path string, params map[stri
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, g.Name)
}

timestamp := strconv.FormatInt(time.Now().Unix(), 10)
if g.Nonce.Get() == 0 {
g.Nonce.Set(time.Now().Unix())
} else {
g.Nonce.Inc()
}

payload := []byte("")

if params != nil {
Expand All @@ -389,11 +394,11 @@ func (g *GDAX) SendAuthenticatedHTTPRequest(method, path string, params map[stri
}
}

message := timestamp + method + "/" + path + string(payload)
message := g.Nonce.String() + method + "/" + path + string(payload)
hmac := common.GetHMAC(common.HashSHA256, []byte(message), []byte(g.APISecret))
headers := make(map[string]string)
headers["CB-ACCESS-SIGN"] = common.Base64Encode([]byte(hmac))
headers["CB-ACCESS-TIMESTAMP"] = timestamp
headers["CB-ACCESS-TIMESTAMP"] = g.Nonce.String()
headers["CB-ACCESS-KEY"] = g.APIKey
headers["CB-ACCESS-PASSPHRASE"] = g.ClientID
headers["Content-Type"] = "application/json"
Expand Down
14 changes: 10 additions & 4 deletions exchanges/gemini/gemini.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,27 +249,33 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, g.Name)
}

if g.Nonce.Get() == 0 {
g.Nonce.Set(time.Now().UnixNano())
} else {
g.Nonce.Inc()
}

request := make(map[string]interface{})
request["request"] = fmt.Sprintf("/v%s/%s", GEMINI_API_VERSION, path)
request["nonce"] = time.Now().UnixNano()
request["nonce"] = g.Nonce.Get()

if params != nil {
for key, value := range params {
request[key] = value
}
}

PayloadJson, err := common.JSONEncode(request)
PayloadJSON, err := common.JSONEncode(request)

if err != nil {
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
}

if g.Verbose {
log.Printf("Request JSON: %s\n", PayloadJson)
log.Printf("Request JSON: %s\n", PayloadJSON)
}

PayloadBase64 := common.Base64Encode(PayloadJson)
PayloadBase64 := common.Base64Encode(PayloadJSON)
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(g.APISecret))
headers := make(map[string]string)
headers["X-GEMINI-APIKEY"] = g.APIKey
Expand Down
19 changes: 8 additions & 11 deletions exchanges/itbit/itbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,12 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, i.Name)
}

timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)[0:13]
nonce, err := strconv.Atoi(timestamp)

if err != nil {
return err
if i.Nonce.Get() == 0 {
i.Nonce.Set(time.Now().UnixNano())
} else {
i.Nonce.Inc()
}

nonce--
request := make(map[string]interface{})
url := ITBIT_API_URL + path

Expand All @@ -262,21 +260,20 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method string, path string, params
}
}

nonceStr := strconv.Itoa(nonce)
message, err := common.JSONEncode([]string{method, url, string(PayloadJSON), nonceStr, timestamp})
message, err := common.JSONEncode([]string{method, url, string(PayloadJSON), i.Nonce.String(), i.Nonce.String()[0:13]})
if err != nil {
log.Println(err)
return
}

hash := common.GetSHA256([]byte(nonceStr + string(message)))
hash := common.GetSHA256([]byte(i.Nonce.String() + string(message)))
hmac := common.GetHMAC(common.HashSHA512, []byte(url+string(hash)), []byte(i.APISecret))
signature := common.Base64Encode(hmac)

headers := make(map[string]string)
headers["Authorization"] = i.ClientID + ":" + signature
headers["X-Auth-Timestamp"] = timestamp
headers["X-Auth-Nonce"] = nonceStr
headers["X-Auth-Timestamp"] = i.Nonce.String()[0:13]
headers["X-Auth-Nonce"] = i.Nonce.String()
headers["Content-Type"] = "application/json"

resp, err := common.SendHTTPRequest(method, url, headers, bytes.NewBuffer([]byte(PayloadJSON)))
Expand Down
8 changes: 7 additions & 1 deletion exchanges/kraken/kraken.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,13 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(method string, values url.Values)
}

path := fmt.Sprintf("/%s/private/%s", KRAKEN_API_VERSION, method)
values.Set("nonce", strconv.FormatInt(time.Now().UnixNano(), 10))
if k.Nonce.Get() == 0 {
k.Nonce.Set(time.Now().UnixNano())
} else {
k.Nonce.Inc()
}

values.Set("nonce", k.Nonce.String())
secret, err := common.Base64Decode(k.APISecret)

if err != nil {
Expand Down
Loading

0 comments on commit f3c1f48

Please sign in to comment.