I am trying to do a request to Gate.io cryptocurrency market and getting this error. {"label":"INVALID_SIGNATURE","message":"Signature mismatch"}
C++ code:
std::string hmac_sha512(const std::string& key, const std::string& data) {
unsigned char* digest = HMAC(EVP_sha512(), key.c_str(), key.length(),
reinterpret_cast<const unsigned char*>(data.c_str()), data.length(), nullptr, nullptr);
std::stringstream ss;
for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill('0') << (int)digest[i];
}
return ss.str();
}
CreateOrder(){
std::string host = "api.gateio.ws";
std::string prefix = "/api/v4";
std::string path = "/spot/orders";
std::string method = "POST";
//https://api.gateio.ws/api/v4/spot/orders
std::string payload = "{\"text\":\"t-123456\",\"currency_pair\":\"ETH_BTC\",\"type\":\"limit\",\"account\":\"spot\",\"side\":\"buy\",\"iceberg\":\"0\",\"amount\":\"1\",\"price\":\"5.00032\",\"time_in_force\":\"gtc\",\"auto_borrow\":false,\"stp_act\":\"cn\"}";
std::string hashJsonPayload = hmac_sha512(secretKey, payload);
std::string timestamp_seconds= std::to_string(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count());
std::string queryParam = "";
std::string sign_string = method + "\n" + "/api/v4/spot/orders" + "\n" + queryParam + "\n" + hashJsonPayload + "\n" + timestamp_seconds;
std::string signHash = hmac_sha512(secretKey, sign_string);
req_.method(boost::beast::http::verb::post);
req_.target(r.target);
req_.version(11);
req_.set(boost::beast::http::field::host, r.host);
req_.set(boost::beast::http::field::accept, "application/json");
req_.set(boost::beast::http::field::content_type, "application/json");
req_.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING);
req_.set("KEY", api_key); // API anahtarı ekleniyor
req_.set("Timestamp", timestamp_seconds);
req_.set("SIGN", signHash);
..
}
I am trying change payload but not working std::string payload1 = "{"text":"t-123456","currency_pair":"ETH_BTC","type":"limit","account":"spot","side":"buy","iceberg":"0","amount":"1","price":"5.00032","time_in_force":"gtc","auto_borrow":false,"stp_act":"cn"}";
std::string payload2 = R"(
{
"text": "t-123456",
"currency_pair": "ETH_BTC",
"type": "limit",
"account": "spot",
"side": "buy",
"iceberg": "0",
"amount": "1",
"price": "5.00032",
"time_in_force": "gtc",
"auto_borrow": false,
"stp_act": "cn"
}
)";
std::string payload3= "{"account":"spot","currency_pair":"" + currencyPair + "","type":"market","side":"" + side + "","amount":"" + amount + ""}";
The documentation here:
Note that you need
HexEncode(SHA512(Request Payload)), you used hmac_sha512 which is a key-based encryption based on SHA512, but not the same. This is easily proven by the fact that the hash for the empty payload is given.DEMO
Attempted fix:
Live On Coliru
Demo: