エンジニアの頭の中

知識と技術で「お金稼ぎの自動化」を実現するため、日々奮闘するエンジニアのブログです。

Quoine ExchangeのPrivate APIの認証をGoから実行する

f:id:mitsu3204:20181014135327j:plain 今作っているツールをGoで書いていて、Quoine ExchangeのPrivate APIを呼び出す必要があったので、API認証について調べていました。

仮想通貨の自動トレードにはPythonを使っている人が多いと思いますが、ccxtやAPIクライントのライブラリを使用している場合は、APIの認証方法なんて意識する必要もないと思います。

www.hacky.xyz

Quoine ExchangeのAPI認証

Quoine Exchange のAPIドキュメントに認証方法についての説明とサンプルコードが掲載されています。

f:id:mitsu3204:20181014124542p:plain

Quoine ExchangeのAPI認証には、JWT (JSON Web Token)という認証方法が使用されています。

サンプルコードが提示されているのはRubyのコードのみですが、他の言語で認証コードを実装する場合も同じ事をやれば良いだけです。

認証するにあたり、自分のアカウントのAPIトークンID(数字)とAPIシークレット(長ったらしい文字列)を用意する必要があります。 これらは取引所のサイトから発行可能です。

読んでみる

サンプルコードは、product_id=1というパラメータ(たぶんBTCUSD)を指定して、自分の注文情報の一覧を取得するordersというプライベートAPIを実行しています。

認証に必要な情報の準備

サンプルコードを見ると、認証に必要な情報は以下のとおりであることがわかります。

これらの情報をキー、バリュー形式で格納したauth_payloadを作成しています。

token_id = 'YOUR_API_TOKEN_ID'
user_secret = 'YOUR_API_SECRET'
path = '/orders?product_id=1'

auth_payload = {
  path: path,
  nonce: DateTime.now.strftime('%Q'),
  token_id: token_id
}

nonceは、DateTime.now.strftime('%Q')の部分で、現在時刻のタイムスタンプ文字列を生成しています。

呼び出すAPIが注文情報一覧取得API(orders)でない場合は、pathの部分は変更する必要があります。

署名を作成

必要な情報を格納したauth_payloadというオブジェクトを作成したら、その内容をJWTのライブラリを使ってエンコードしています。

その際に、アカウントのAPIシークレット(user_secret)を使用しています。

signature = JWT.encode(auth_payload, user_secret, 'HS256')

HTTPヘッダに署名情報を追加

JWT.encodeによって作成した署名情報は、X-Quoine-Authと言う名前でHTTPヘッダに追加しています。

request.add_field('X-Quoine-Auth', signature)

Goで実装する

GoにもJWTのライブラリはあります。

github.com

まずは、jwt-goを入手します。

go get github.com/dgrijalva/jwt-go

import

import文にjwt-goを追加します。

import (
    ...
    
    jwt "github.com/dgrijalva/jwt-go"
)

認証に必要な情報の準備

サンプルコードと同じ様に、認証のためのペイロードを作成します。jwtのMapClaimsとして作成します。

nonceは、現在時刻のタイムスタンプです。(API実行ごとに値が変わりさえすれば何でも良いですが)

token := jwt.New(jwt.GetSigningMethod("HS256"))
token.Claims = jwt.MapClaims{
    "path":  path,
    "nonce": strconv.FormatInt(time.Now().Unix(), 10),
    "token_id": "APIキー",
}

署名を作成

作成したtokenを介して署名作成用の関数を呼び出します。その際にAPIシークレットを使用します。

signature, err := token.SignedString([]byte("APIシークレット"))

HTTPヘッダに署名情報を追加

作成した署名はサンプルのとおり、X-Quoine-Authの名前でHTTPヘッダにセットするだけです。

req, _ := http.NewRequest(strings.ToUpper(method), "https://api.liquid.com"+path, nil)
req.Header.Set("X-Quoine-Auth", signature)
req.Header.Set("X-Quoine-API-Version", "2")
req.Header.Set("Content-Type", "application/json")

あとはこのリクエストを送信すればOKです。

client := new(http.Client)
res, err := client.Do(req)

以上