Go言語でbitFlyerLightningのPrivateAPIにリクエストを出す方法


Go言語でbitFlyerLightningのPrivateAPIにリクエストを出す方法

bitFlyerLightningAPIの公式ドキュメント上に、Go言語でリクエストを出す場合のサンプルコードがなかったため、調査結果をメモした。

本記事では、childOrderを出す場合の手順について解説する。

概要

基本的に、Go言語でのbitFlyerLightningAPIへのPrivateリクエストは、下記の手順にて実施する。

1. bitFlyerにログインして、アクセスキー、シークレットキーを取得する。
2. SHA256でデジタル署名を作成する。UNIXタイムスタンプ、メソッド、apiのパス、リクエストボディを文字列として連結し、それらの文字列をシークレットキーを利用して、SHA256でハッシュ化したものをデジタル署名としている。
3. アクセスキーとデジタル署名とタイムスタンプを利用してリクエストヘッダを作成する。
4. 独自リクエストを送信する関数を利用して、リクエストを送信する。(httpパッケージ内に含まれる関数では実施できない?)

サンプルコード

sample.go
// 独自headerとbodyでPOSTリクエストを送るための関数
// httpパッケージで対応できないリクエストはこの関数を使う
func NewRequest(method, url string, header map[string]string, body []byte) (*http.Request, error) {
    req, err := http.NewRequest(method, url, bytes.NewReader(body))
    if err != nil {
        return nil, err
    }
    for key, value := range header {
        req.Header.Set(key, value)
    }
    return req, nil
}

// SHA256でデジタル署名を作成するための関数
// 連結した文字列とシークレットキーを引数とし、戻り値をデジタル署名とする
func MakeHMAC(text, secretKey string) string {
    key := secretKey
    mac := hmac.New(sha256.New, []byte(key))
    mac.Write([]byte(text))
    return hex.EncodeToString(mac.Sum(nil))
}

//map型をstring型へ変換するための関数
func MapToString(bytes map[string]interface{}) string {
    b, err := json.Marshal(bytes)
    if err != nil {
        fmt.Println("JSON marshal error: ", err)
        return "error"
    }
    string := string(b)
    return string
}

// 子注文を出すための関数。
func POSTChildOrder(){
    // 自ら取得したアクセスキーとシークレットキーを記載してください。
    accessKey := XXXX
    secretKey := YYYY

    //UNIXタイムスタンプを取得する。
    timestamp := strconv.FormatInt(time.Now().Unix(), 10)

    //methodは基本的にGETかPOSTのみ。子注文を出す場合はPOSTを利用する。
    method := "POST"
    path := "/v1/me/sendchildorder"

    //リクエストボディ。必要に応じてkeyとvalueを変更してください。
    body := map[string]interface{}{
        "product_code":     "ETH_JPY",
        "child_order_type": "LIMIT",
        "side":             "BUY",
        "price":            10000,
        "size":             1,
        "minute_to_expire": 10000,
        "time_in_force":    "GTC",
    }
    //リクエストボディをstring型に変更する。
    sbody := MapToString(body)

    //sha256でデジタル署名を作成するための文字列を作成する。
    text := timestamp + method + path + sbody
    // デジタル署名を作成する。
    sign := MakeHMAC(text, secretKey)

    // リクエストヘッダを作成する
    header := map[string]string{
        "ACCESS-KEY":       accessKey,
        "ACCESS-TIMESTAMP": timestamp,
        "ACCESS-SIGN":      sign,
        "Content-Type":     "application/json",
    }

    // リクエストを送信する
    url := https://api.bitflyer.com” + path
    // POSTの場合は、独自のリクエスト送信関数にてリクエストを送信する。
    // GETの場合はhttpパッケージのリクエストを利用可能。
    req, err := NewRequest(method, url, header, []byte(sbody))
    if err != nil {
        fmt.Println(err.Error())
    }
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        fmt.Println(err.Error())
    }

補足

子注文以外のPrivateAPIの利用方法の詳細は、公式ドキュメントを参照してください。 (本記事に掲載したサンプルコード内の、method,path,bodyを変えることで他のAPIを利用できると思います。)