I have coded as below, but I get the error: "{\"code\":-1022,\"msg\":\"Signature for this request is not valid.\"}"
I have check my api-key/secret
and they are ok; now I don't know where is wrong?
I have confirmed the 'signature' is also ok and I think maybe there is something wrong in the last step which I don't confirm how to pass parameters with signature together.
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let (symbol, side, trade_type, quantity, price, time_inforce, api_key, api_secret) = (
"BTCUSDT",
"BUY",
"LIMIT",
"0.1",
"20000.0",
"GTC",
"my-key",
"my-secret",
);
let client = reqwest::Client::new();
let mut headers_map = reqwest::header::HeaderMap::new();
headers_map.insert("Content-Type", "application/json".parse().unwrap());
headers_map.insert("X-MBX-APIKEY", api_key.parse().unwrap());
let mut param_map = std::collections::HashMap::new();
param_map.insert("symbol", symbol);
param_map.insert("side", side);
param_map.insert("type", trade_type);
param_map.insert("quantity", quantity);
let current_timestamp = chrono::Utc::now().timestamp_millis().to_string();
param_map.insert("timestamp", current_timestamp.as_str());
if trade_type == "LIMIT" {
param_map.insert("price", price);
param_map.insert("timeInForce", time_inforce);
}
let mut query = String::new();
for (key, value) in ¶m_map {
query.push_str(&format!("{}={}&", key, value));
}
query.pop(); // remove trailing '&'
let signature = {
type HmacSha256 = hmac::Hmac<sha2::Sha256>;
let mut mac = HmacSha256::new_from_slice(api_secret.as_bytes())
.expect("HMAC can take key of any size");
mac.update(query.as_bytes());
hex::encode(mac.finalize().into_bytes())
// format!("{:02x}", mac.finalize().into_bytes())
};
let res = client
.post("https://fapi.binance.com/fapi/v1/order") // fapi/v1/order/test: for test orders
.headers(headers_map)
.body(query)
.query(&[("timestamp", ¤t_timestamp), ("signature", &signature)])
.send()
.await?
.text()
.await?;
Ok(())
}
Parameters in the query string need to be sorted in alphabetical order before generating the signature in Binance API. You could try sorting the param_map before generating the query string and see if that fixes the issue.
let mut param_map = std::collections::BTreeMap::new();
Or just try reversing the order of timestamp and signature in client query line
.query(&[("timestamp", ¤t_timestamp), ("signature", &signature)])