【AWS】bitbank 新規注文
1. 使用するサービス
(AWS)
- Lambda
- IAM
- SSM
(外部サービス)
- bitbank API
2. 概要
bitbank Apiを使用して、自作の注文サイトを作成します。
基本的な仕組みはbitflyer Lightning Apiで実装したものと同じでURLを叩くのが最終的なゴールです。
buffalokusojima.hatenablog.com
3. 実装
今回はバックエンド側を実装します。フロントは特にbitflyerと違いはなく、渡すパラメータが異なるのみなので省略します。
大まかな違いとしては、ヘッダの中身とパラメータくらいです。
const ssm = new (require('aws-sdk/clients/ssm'))(); const request = require('request'); const crypto = require('crypto'); exports.handler = function(event, context, callback) { var apikey; var sercretKey; var body = JSON.parse(event.body); if(!body){ console.log("body empty"); callback(null, { statusCode: 400, body: JSON.stringify({message: "body empty"}), headers: {"Content-type": "application/json"} }); return; } const COIN_PAIR = body.coin_pair; const PRICE = body.price; const SIDE = body.side; const SIZE = body.size; const TYPE = body.type; const PARAMETERS = body.parameters; const ORDER_METHOD = body.order_method; if(!TYPE && !PARAMETERS){ console.log("invalid order:",body); callback(null, { statusCode: 400, body: JSON.stringify({message: "invalid order"}), headers: {"Content-type": "application/json"} }); return; } if(COIN_PAIR != 'xrp_jpy'){ console.log("invalid coin pair"); callback(null, { statusCode: 400, body: JSON.stringify({message: "invalid order"}), headers: {"Content-type": "application/json"} }); return; } if(!checkElement(body)){ console.log("Bad body:", body); callback(null, { statusCode: 400, body: JSON.stringify({message: "invalid order"}), headers: {"Content-type": "application/json"} }); return; } body = { pair: body.coin_pair, amount: body.size, price: body.price, side: body.side, type: body.type } getParameterFromSystemManager('bitbank-keys',callback) .then(function(data){ apikey = data.split(",")[0]; sercretKey = data.split(",")[1]; var timestamp = Date.now().toString(); var method = 'POST'; var path = '/v1/user/spot/order'; body = JSON.stringify(body); console.log(body) var text = timestamp + body; var sign = crypto.createHmac('sha256', sercretKey).update(text).digest('hex'); var option = { url: 'https://api.bitbank.cc' + path, method: method, headers: { 'ACCESS-KEY': apikey, 'ACCESS-NONCE': timestamp, 'ACCESS-SIGNATURE': sign, 'Content-Type': 'application/json' }, body: body } return sendRequest(option, callback); }).then(function(data){ data = JSON.parse(data.body) console.log(data) callback(null, { statusCode: 200, body: JSON.stringify({message: data.data}), headers: {"Content-type": "application/json"} }); return; }); function checkElement(element){ if(element.type == 'market' || element.type == 'limit' || element.type == 'stop'){ if(element.side != 'buy' && element.side != 'sell'){ console.log("invalid side"); return false; } element.price = Number(element.price); element.size = Number(element.size); if(isNaN(element.price) && element.type != 'market'){ console.log("number invalid:", element.price); return false; } if(isNaN(element.size)){ console.log("number invalid:", element.size); return false; } return true; } return false; } function getParameterFromSystemManager(apikey_name, callback) { return new Promise(function (resolve) { var apikey = process.env[apikey_name]; if(!apikey || typeof apikey == undefined){ // Fetches a parameter called REPO_NAME from SSM parameter store. // Requires a policy for SSM:GetParameter on the parameter being read. var params = { Name: apikey_name, /* required */ WithDecryption:true }; ssm.getParameter(params, function(err, apikey) { if (err){ console.error(err.stack); callback(null,{ statusCode: 500, body: JSON.stringify({message: err.toString()}), headers: {"Content-type": "application/json"} }); resolve(null); return; } process.env[apikey_name] = apikey.Parameter.Value; resolve(apikey.Parameter.Value); }); }else resolve(apikey); }); } function sendRequest(option, callback){ return new Promise(function (resolve) { request(option, function(error, response, body){ if(error){ console.error(error); callback(null,{ statusCode: 500, body: JSON.stringify({message: error.toString()}), headers: {"Content-type": "application/json"} }); resolve(null); } var data = {response, body} resolve(data); }); }); } }
4. おわりに
AWS開発再開しているのでまた何か発見があれば載せます。