For information on changes for our US clients, please visit our Support Center article.

Поиск
Example code for Go REST and WebSocket API

Introduction

Below is a Go example script that can be referenced for both the REST and WebSocket Implementation of the Kraken API.

It demo's the following functionality:
  • Public REST API Endpoints
  • Private REST API Endpoints
  • Public WebSocket API Subscriptions
  • Private WebSocket API Subscriptions

Installation

To run locally, you can copy/paste the code below.

Note that setting the if statement of 1 == 0 to 1 == 1 will execute the specific block of code.

Before running the script, you need to update the script with your Public and Private API Keys.

You can download this file here.

Go Code

package mainimport ("crypto/hmac""crypto/sha256""crypto/sha512""encoding/base64""encoding/json""fmt""io/ioutil""log""net/http""os""os/signal""strings""time""github.com/sacOO7/gowebsocket")type WsTokenJsonStruct struct {Error []interface{} `json:"error"`Result struct {Token string `json:"token"`Expires int `json:"expires"`} `json:"result"`}func main() {//TODO: Replace the Public and Private key with YOUR keys :)apiPublicKey := "YOUR_PUBLIC_KEY"apiPrivateKey := "YOUR_PRIVATE_KEY"fmt.Println("|==========================================|")fmt.Println("| KRAKEN.COM GOLANG TEST APP |")fmt.Println("|==========================================|")fmt.Println()/** PUBLIC REST API Examples*/if1 == 0 {publicEndpoint := "SystemStatus"publicInputParameters := ""/**MORE PUBLIC REST EXAMPLESpublicEndpoint := "AssetPairs"publicInputParameters := "pair=ethusd,xbtusd"publicEndpoint := "Ticker"publicInputParameters := "pair=ethusd"publicEndpoint := "Trades"publicInputParameters := "pair=ethusd&since=0"*/publicResponse := QueryPublicEndpoint(publicEndpoint, publicInputParameters)fmt.Println(publicResponse)}/** PRIVATE REST API Examples*/if0 == 0 {privateEndpoint := "Balance"privateInputParameters := ""/**MORE PRIVATE REST EXAMPLESprivateEndpoint := "AddOrder"privateInputParameters := "pair=xbteur&type=buy&ordertype=limit&price=1.00&volume=1"privateEndpoint := "AddOrder"privateInputParameters := "pair=xdgeur&type=sell&ordertype=limit&volume=3000&price=%2b10.0%" //Positive Percentage Example (%2 represtes +, which is a reseved character in HTTP)privateEndpoint := "AddOrder"privateInputParameters := "pair=xdgeur&type=sell&ordertype=limit&volume=3000&price=-10.0%" //Negative Percentage ExampleprivateEndpoint := "AddOrder"privateInputParameters := "pair=xdgeur&type=buy&ordertype=market&volume=3000&userref=789" //Userref ExampleprivateEndpoint := "Balance" //{"error":[]} IS SUCCESS, Means EMPTY BALANCEprivateInputParameters := ""privateEndpoint := "QueryOrders"privateInputParameters := "txid=OFUSL6-GXIIT-KZ2JDJ"privateEndpoint := "AddOrder"privateInputParameters := "pair=xdgusd&type=buy&ordertype=market&volume=5000"privateEndpoint := "DepositAddresses"privateInputParameters := "asset=xbt&method=Bitcoin"privateEndpoint := "DepositMethods"privateInputParameters := "asset=eth"privateEndpoint := "WalvarTransfer"privateInputParameters := "asset=xbt&to=Futures Walvar&from=Spot Walvar&amount=0.0045"privateEndpoint := "TradesHistory"privateInputParameters := "start=1577836800&end=1609459200"privateEndpoint := "GetWebSocketsToken"privateInputParameters := ""*/privateResponse := QueryPrivateEndpoint(privateEndpoint,privateInputParameters,apiPublicKey,apiPrivateKey)fmt.Println(privateResponse)}/** PUBLIC WEBSOCKET Examples*/if1 == 0 {publicWebSocketURL := "wss://ws.kraken.com/"publicWebSocketSubscriptionMsg := "{ \"event\":\"subscribe\", \"subscription\":{\"name\":\"trade\"},\"pair\":[\"XBT/USD\"] }"/**MORE PUBLIC WEBSOCKET EXAMPLESpublicWebSocketSubscriptionMsg := "{ \"event\": \"subscribe\", \"subscription\": { \"interval\": 1440, \"name\": \"ohlc\"}, \"pair\": [ \"XBT/EUR\"]}"publicWebSocketSubscriptionMsg := "{ \"event\": \"subscribe\", \"subscription\": { \"name\": \"spread\"}, \"pair\": [ \"XBT/EUR\",\"ETH/USD\" ]}"*/OpenAndStreamWebSocketSubscription(publicWebSocketURL, publicWebSocketSubscriptionMsg)}/** PRIVATE WEBSOCKET Examples*/if1 == 0 {privateWebSocketURL := "wss://ws-auth.kraken.com/"//GET THE WEBSOCKET TOKEN FORM THE JSON RESPONSEresponse := GetWebSocketToken("GetWebSocketsToken", "", apiPublicKey, apiPrivateKey)webSocketToken := response.Result.Token/**MORE PRIVATE WEBSOCKET EXAMPLESprivateWebSocketSubscriptionMsg := "{\"event\": \"subscribe\", \"subscription\": { \"name\": \"openOrders\", \"token\": \"" + webSocketToken + "\"}}"privateWebSocketSubscriptionMsg := "{\"event\": \"subscribe\", \"subscription\": { \"name\": \"balances\", \"token\": \"" + webSocketToken + "\"}}"privateWebSocketSubscriptionMsg := "{\"event\":\"addOrder\",\"reqid\":1234,\"ordertype\":\"limit\",\"pair\":\"XBT/EUR\",\"token\": \"" + webSocketToken + "\",\"type\":\"buy\",\"volume\":\"1\", \"price\":\"1.00\"}"*///REPLACE PLACEHOLDER WITH TOKENprivateWebSocketSubscriptionMsg := "{ \"event\": \"subscribe\", \"subscription\": { \"name\": \"ownTrades\", \"token\": \"" + webSocketToken + "\"}}"OpenAndStreamWebSocketSubscription(privateWebSocketURL, privateWebSocketSubscriptionMsg)}fmt.Println()fmt.Println("|=======================================|")fmt.Println("| END OF PROGRAM - HAVE A GOOD DAY :) |")fmt.Println("|=======================================|")fmt.Println("\n")}/** PUBLIC REST API Examples*/func QueryPublicEndpoint(endPointName, inputParameters string) string {baseDomain := "https://api.kraken.com"publicPath := "/0/public/"apiEndpointFullURL := baseDomain + publicPath + endPointName + "?" + inputParametersresp, err := http.Get(apiEndpointFullURL)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}returnstring(body)}/** Private REST API Endpoints*/func QueryPrivateEndpoint(endPointName,inputParameters,apiPublicKey,apiPrivateKey string) string {baseDomain := "https://api.kraken.com"privatePath := "/0/private/"apiEndpointFullURL := baseDomain + privatePath + endPointName + "?" + inputParametersnonce := fmt.Sprintf("%d", time.Now().Unix())apiPostBodyData := "nonce=" + nonce + "&" + inputParameterssignature := CreateAuthenticationSignature(apiPrivateKey,privatePath,endPointName,nonce,apiPostBodyData)httpOptions, err := http.NewRequest("POST", apiEndpointFullURL, strings.NewReader(apiPostBodyData))httpOptions.Header.Add("API-Key", apiPublicKey)httpOptions.Header.Add("API-Sign", signature)httpOptions.Header.Add("User-Agent", "GO Lang Client")if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}resp, err := http.DefaultClient.Do(httpOptions)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}jsonData := string(body)return jsonData}func GetWebSocketToken(endPointName,inputParameters,apiPublicKey,apiPrivateKey string) WsTokenJsonStruct {baseDomain := "https://api.kraken.com"privatePath := "/0/private/"apiEndpointFullURL := baseDomain + privatePath + endPointName + "?" + inputParametersnonce := fmt.Sprintf("%d", time.Now().Unix())apiPostBodyData := "nonce=" + nonce + "&" + inputParameterssignature := CreateAuthenticationSignature(apiPrivateKey,privatePath,endPointName,nonce,apiPostBodyData)httpOptions, err := http.NewRequest("POST", apiEndpointFullURL, strings.NewReader(apiPostBodyData))httpOptions.Header.Add("API-Key", apiPublicKey)httpOptions.Header.Add("API-Sign", signature)httpOptions.Header.Add("User-Agent", "GO Lang Client")if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}resp, err := http.DefaultClient.Do(httpOptions)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}defer resp.Body.Close()body, err := ioutil.ReadAll(resp.Body)if err != nil {fmt.Println("ERROR OCCURED: ", err)os.Exit(1)}varjsonData WsTokenJsonStructjson.Unmarshal(body, &jsonData)return jsonData}/** Authentication Algorithm*/func CreateAuthenticationSignature(apiPrivateKey,apiPath,endPointName,nonce,apiPostBodyData string) string {apiPost := nonce + apiPostBodyDatasecret, _ := base64.StdEncoding.DecodeString(apiPrivateKey)apiEndpointPath := apiPath + endPointNamesha := sha256.New()sha.Write([]byte(apiPost))shaSum := sha.Sum(nil)allBytes := append([]byte(apiEndpointPath), shaSum...)mac := hmac.New(sha512.New, secret)mac.Write(allBytes)macSum := mac.Sum(nil)signatureString := base64.StdEncoding.EncodeToString(macSum)return signatureString}/** WebSocket API*/func OpenAndStreamWebSocketSubscription(connectionURL, webSocketSubscription string) {interrupt := make(chan os.Signal, 1)signal.Notify(interrupt, os.Interrupt)webSocketClient := gowebsocket.New(connectionURL)webSocketClient.OnConnectError = func(err error, socket gowebsocket.Socket) {fmt.Println("Received connect error - ", err)}webSocketClient.OnConnected = func(socket gowebsocket.Socket) {fmt.Println("Connected to server")}webSocketClient.OnTextMessage = func(message string, socket gowebsocket.Socket) {fmt.Println(time.Now().Format("01-02-2006 15:04:05") + ": " + message)}webSocketClient.OnPingReceived = func(message string, socket gowebsocket.Socket) {fmt.Println("Received ping - " + message)}webSocketClient.OnPongReceived = func(message string, socket gowebsocket.Socket) {fmt.Println("Received pong - " + message)}webSocketClient.OnDisconnected = func(err error, socket gowebsocket.Socket) {fmt.Println("Socket Closed")fmt.Println("\n")}webSocketClient.Connect()webSocketClient.SendText(webSocketSubscription)for {select {case <-interrupt:log.Println("interrupt")webSocketClient.Close()return}}}