Question: does anyone know how to make a post request from Coinspot API? The information of how to put the API key, secret and nonce is not very clear

---

All requests to the POST API requests will need to include the following security data.

Headers key - Your API key generated from the settings page sign - The POST data is to be signed using your secret key according to HMAC-SHA512 method. Post Params nonce - Any integer value which must always be greater than the previous requests nonce value.

---

I am trying to create a REST API, but I am getting a 401 request error. Not sure what I am doing wrong?

```html
const axios = require("axios");
var n = require("nonce")();
const crypto = require("crypto");

const api_key = process.env.COINSPOT_KEY;
const api_secret = process.env.COINSPOT_SECRET;

let nonce = n();
let postdata = { nonce: nonce };

function getSecurePassword(password, salt, algo) {
  const algoFormatted = algo.toLowerCase().replace("-", "");
  const hash = crypto.createHmac(algoFormatted, salt);
  hash.update(password);
  const res = hash.digest("hex");
  return res;
}

exports.orderHistory = async (req, res) => {
  let sign = getSecurePassword(api_secret, JSON.stringify(postdata), "SHA-512");
  try {
    await axios({
      baseURL: "https://www.coinspot.com.au/api/v2/ro",
      url: "my/orders/completed",
      port: 443,
      method: "post",
      data: postdata,
      headers: { key: api_key, sign: sign },
    }).then(function (response) {
      res.json(response);
    });
  } catch (error) {
    res.json(error);
  }
};
```

Answer: 
ExpandEnvironmentStrings expects a buffer already allocated. You can determine the size of the buffer if [you pass a buffer with a size too small to hold the string](https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsa#return-value), like 0.

So, here are two versions, UNICODE and ANSI, that will compute the size dynamically:

```
std::wstring expandWindowsString(const std::wstring& input)
{
    std::wstring output;
    do
    {
        auto size = ExpandEnvironmentStringsW(input.c_str(), (LPWSTR)output.c_str(), output.size());
        if (!size || size <= output.size())
            break;

        output.resize(size);
    } while (true);
    output = output.c_str();
    return output;
}

std::string expandWindowsString(const std::string& input)
{
    std::string output;
    do
    {
        auto size = ExpandEnvironmentStringsA(input.c_str(), (LPSTR)output.c_str(), output.size());
        if (!size || size <= output.size())
            break;

        output.resize(size);
    } while (true);
    output = output.c_str();
    return output;
}

```
If you read the [doc](https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsa)

> 
> `lpDst`
> 
> 
> A pointer to a buffer that receives the result of expanding the environment variable strings in the lpSrc buffer. Note that this buffer cannot be the same as the lpSrc buffer.
> 
> 
> 

> 
> `nSize`
> 
> 
> The maximum number of characters that can be stored in the buffer pointed to by the lpDst parameter. When using ANSI strings, the buffer size should be the string length, plus terminating null character, plus one. When using Unicode strings, the buffer size should be the string length plus the terminating null character.
> 
> 
> 

You will see you pass invalid parameter, you have to provide `buffer`, so:

```
void expandWindowsString(const std::string &input, std::string &output)
{
    char out[1024];
    ExpandEnvironmentStrings(input.c_str(), out, sizeof (out));
    output = out;
}

```

or avoiding output parameter:

```
std::string expandWindowsString(const std::string &input)
{
    char out[1024];
    ExpandEnvironmentStrings(input.c_str(), out, sizeof (out));
    return out;
}

```

Notice that you should probably check return value of `ExpandEnvironmentStrings`.