Cex.io est un site d’achat et de vente de possibilités de générer des Bitcoins. Il permet d’acheter ou de vendre des GH/s. Le GH/s correspond à la capacité de calcul nécessaire à générer des Bitcoins.
Le site Cex.io propose les API pour les langages suivants : Php, Node.js et Python. Malheureusement, certaines de ces API ne me conviennent pas ou sont incomplètes.
Le projet qui nécessite d’utiliser une telle API est un projet réalisé en langage Go. J’ai donc essayé de développer une API dans ce langage pour le site Cex.io et pour les besoins du projet.
La partie du code source la plus intéressante est celle qui concerne l’authentification. La description des contraintes d’authentification est détaillée sur la page dédiée à l’API du site Cex.io.
“Nonce” est un nombre entier arbitraire. Il doit être incrémenté à chaque requête. J’utilise ici le temps Unix retourné en nanoseconde.
“Signature” est un message chiffré avec l’algorithme HMAC-SHA256. Ce message contient : le nombre entier (Nonce), le nom de l’utilisateur (client id) et la clé de l’API. Le code HMAC-SHA256 doit être généré en utilisant une clé secrète qui est générée avec la clé de l’API. Le code doit être converti dans sa représentation hexadécimale en majuscule.
Le code de l’authentification qui résout ces contraintes :
// Key structure
type CexKey struct {
Username string
Api_key string
Api_secret string
}
// Return Unix time in nano
func (cexapi *CexKey) Nonce() string {
return strconv.FormatInt(time.Now().UnixNano(), 10)
}
// Return sha256 hashing
func (cexapi *CexKey) ToHmac256(message string, secret string) string {
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
// Return formatted signature
func (cexapi *CexKey) Signature() (string, string) {
nonce := cexapi.Nonce()
message := nonce + cexapi.Username + cexapi.Api_key
signature := cexapi.ToHmac256(message, cexapi.Api_secret)
return signature, nonce
}
L’API est disponible à cette adresse : https://github.com/jhautefeuille/go-cexio-api.
L’API s’utilise de la façon suivante :
package main
import (
"github.com/jhautefeuille/go-cexio-api"
"fmt"
)
func main() {
cexapi := cexio.CexKey{
Username:"your_username",
Api_key:"your_api_key",
Api_secret:"your_api_secret"}
// Public
fmt.Printf("Ticker => %s\n", cexapi.Ticker("GHS/BTC"))
//fmt.Printf("Order Book => %s\n", cexapi.OrderBook("GHS/BTC"))
//fmt.Printf("Trade History => %s\n", cexapi.TradeHistory("GHS/BTC"))
// Private
fmt.Printf("Balance => %s\n", cexapi.Balance())
fmt.Printf("Open Orders => %s\n", cexapi.OpenOrders("GHS/BTC"))
// Trading orders
//fmt.Printf("Place Order => %s\n", cexapi.PlaceOrder("buy", "0.001", "0.017", "GHS/BTC"))
//fmt.Printf("Cancel Order => %s\n", cexapi.CancelOrder("477571539"))
// Workers
fmt.Printf("Hashrate => %s\n", cexapi.Hashrate())
fmt.Printf("Workers => %s\n", cexapi.Workers())
}
Dans une application, on peut également profiter du package “encoding/json” :
package main
import (
"go-cexio-api"
"fmt"
"encoding/json"
)
type Ticker_ struct {
Timestamp string
Bid float64
Ask float64
Low string
High string
Last string
Volume string
}
func main() {
cexapi := cexio.CexKey{
Username:"your_username",
Api_key:"your_api_key",
Api_secret:"your_api_secret"}
my_json := cexapi.Ticker("GHS/BTC")
var myticker Ticker_
json.Unmarshal([]byte(my_json), &myticker)
fmt.Println("ticker", myticker.Bid)
}
La conversion du JSON vers la structure est une fonction très puissante dans le langage Go :
json.Unmarshal([]byte(my_json), &myticker)
Un utilisateur m’a contacté au sujet de cette API. D’autres versions améliorées sont à prévoir. Le développement de cette application m’a permis d’appréhender le langage Go que je n’avais pas encore utilisé.