数字货币各个交易所认证方式
1. Deribit
首先产生access_token,此后的有关私有信息的rest和websocket请求中,都要加上此参数。
(1)产生access_token
http_client restclient(m_curcfg.resturl); // https://test.deribit.com
uri_builder builder(m_authentication_url); // "/api/v2/public/auth"
http_request request(methods::GET); builder.append_query("grant_type", "client_credentials"); builder.append_query("client_id", m_curcfg.api_key); builder.append_query("client_secret", m_curcfg.secret_key); request.set_request_uri(builder.to_string()); std::cout << builder.to_string() << std::endl; restclient.request(request) .then([](http_response response) -> pplx::task<json::value> { if(response.status_code() == status_codes::OK) { return response.extract_json(); } LOG_DEBUG("Retrieve Oauth access token response: '%s' ", response.to_string().c_str()); // return an empty JSON value return pplx::task_from_result(json::value()); }) // continue when the JSON value is available .then([&](pplx::task<json::value> previousTask) { // get the JSON value from the task and display content from it try { json::value const& v = previousTask.get(); if (v.has_field("result")) { json::value const & result = v.at("result"); if (result.has_field("access_token")) { m_accessToken = result.at("access_token").as_string(); std::cout << m_accessToken << std::endl; } std::cout << "------------" << std::endl; if (result.has_field("refresh_token")) { m_refreshToken = result.at("refresh_token").as_string(); std::cout << m_refreshToken << std::endl; } std::cout << "------------" << std::endl; if (result.has_field("expires_in")) { m_expiresIn = result.at("expires_in").as_integer(); std::cout << m_expiresIn << std::endl; } } } catch (http_exception const & e) { printf("Error exception:%s\n", e.what()); } }) .wait();
(2) 更新access_token
http_client restclient(m_curcfg.resturl); uri_builder builder(m_authentication_url); http_request request(methods::GET); builder.append_query("grant_type", "refresh_token"); builder.append_query("refresh_token", m_refreshToken.c_str()); request.set_request_uri(builder.to_string()); restclient.request(request) .then([](http_response response) -> pplx::task<json::value> { if(response.status_code() == status_codes::OK) { return response.extract_json(); } LOG_DEBUG("Refresh Oauth access token response: '%s' ", response.to_string().c_str()); // return an empty JSON value return pplx::task_from_result(json::value()); }) // continue when the JSON value is available .then([&](pplx::task<json::value> previousTask) { // get the JSON value from the task and display content from it try { json::value const& v = previousTask.get(); if (v.has_field("result")) { json::value const & result = v.at("result"); if (result.has_field("access_token")) { m_accessToken = result.at("access_token").as_string(); std::cout << m_accessToken << std::endl; } std::cout << "------------" << std::endl; if (result.has_field("refresh_token")) { m_refreshToken = result.at("refresh_token").as_string(); std::cout << m_refreshToken << std::endl; } std::cout << "------------" << std::endl; if (result.has_field("expires_in")) { m_expiresIn = result.at("expires_in").as_integer(); std::cout << m_expiresIn << std::endl; } } LOG_DEBUG("accid: '%d' access_token: '%s' refresh_token: '%s' express_in: '%d'", m_curcfg.accountid, m_accessToken.c_str(), m_refreshToken.c_str(), m_expiresIn); } catch (http_exception const & e) { printf("Error exception:%s\n", e.what()); } }) .wait();
(3)下单
http_client restclient(m_curcfg.resturl); http_request request(methods::GET); request.headers().add("Authorization", "Bearer " + m_accessToken); request.headers().add("Content-Type", "application/json"); if (strcmp(ord.side,"buy") == 0) { m_ord_url = "/api/v2/private/buy"; } else if (strcmp(ord.side, "sell") == 0) { m_ord_url = "/api/v2/private/cancel"; } uri_builder builder(m_ord_url); builder.append_query("price", 40000); builder.append_query("amount", 1); builder.append_query("label", "ttt"); builder.append_query("instrument_name", "BTC-PERPETUAL"); builder.append_query("type", "limit"); request.set_request_uri(builder.to_string()); std::cout << builder.to_string() << std::endl; restclient.request(request) .then([](http_response response) -> pplx::task<json::value> { // if the status is OK extract the body of the response into a JSON value // works only when the content type is application\json auto code = response.status_code(); //400, 401, 418, 429 if(code == status_codes::OK || code == status_codes::BadRequest || code == status_codes::TooManyRequests || code == status_codes::Unauthorized) { //std::cout << "response headers:" << response.headers().content_type() << "\n"; return response.extract_json(); } throw exception(); // return an empty JSON value return pplx::task_from_result(json::value()); }) // continue when the JSON value is available .then([&](pplx::task<json::value> previousTask) { // get the JSON value from the task and display content from it try { //{"code":-1013,"msg":"Filter failure: MIN_NOTIONAL"} json::value const & v = previousTask.get(); if (v.has_field("error")) { json::value const & errMsg = v.at("error"); if (errMsg.has_field("code")) { int err_code = v.at("code").as_integer(); string msg = errMsg.at("message").as_string(); } } else { // if (v.has_field("orderID")); } } catch (http_exception const & e) { throw exception(); } }) .wait();
(4) websocket连接,初始化连接时,不需要传入access_token
uri_builder builder(m_curcfg.wsurl); // wss://test.deribit.com builder.append_path(m_wssb_url.to_string()); // /ws/api/v2 // builder.append_query("access_token", m_accessToken.c_str()); 请求头中不需要加token,在订阅的时候需要加上token std::cout << builder.to_string() << std::endl; m_wsclient.close(); m_wsclient.connect(builder.to_string()) .then([&]() { std::function<void (const websocket_incoming_message &msg)> f; f = std::bind(&DeribitAdapterApi::On_WebSocketMsg, this, placeholders::_1); m_wsclient.set_message_handler(f); std::function<void (websocket_close_status close_status, const utility::string_t& reason, const std::error_code& error)> c; c = std::bind(&DeribitAdapterApi::On_CloseMsg, this, placeholders::_1, placeholders::_2, placeholders::_3); m_wsclient.set_close_handler(c); }) .wait();
(5)订阅公共和用户信息
websocket_outgoing_message out_msg; json::value msg; //msg["method"] = json::value::string("public/subscribe"); msg["method"] = json::value::string("private/subscribe"); //json::value channel = json::value::string("ticker.BTC-11MAR22-30000-C.100ms"); json::value channel = json::value::string("user.orders.BTC-PERPETUAL.100ms"); vector<json::value> v; v.push_back(channel); json::value params; params["channels"] = json::value::array(v); params["access_token"] = json::value::string(m_accessToken); // 私有信息需要传入 msg["params"] = channels; std::cout << msg.to_string() << std::endl; std::cout << "----------------" << std::endl; out_msg.set_utf8_message(msg.serialize()); m_wsclient.send(out_msg);