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: 
As the [documentation](https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsa) explains:

> 
> `lpDst`
> 
> 
> A pointer to a buffer that receives the result of expanding the environment variable strings in the *lpSrc* buffer.
> 
> 
> 

The buffer needs to be supplied by the caller, while the code simply passes an uninitialized pointer, alongside tricking the system into believing that it points at memory with a size of 1024 bytes.

A simple fix would be:

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

```

There's lots of room for improvement, e.g.

* Using the [Unicode version](https://learn.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-expandenvironmentstringsw)
* Handling errors (as explained in the documentation)
* Repeatedly growing the output buffer in case the API call returns a value larger than the provided buffer length
* Constructing a `std::string` using the [pointer and length](https://en.cppreference.com/w/cpp/string/basic_string/basic_string)
* Returning a value rather than using an out parameter

As for why it fails when being called a second time: That's a meaningless question. The code exhibits undefined behavior by writing through an uninitialized pointer. With that, **any** outcome is possible, including the code appearing to work as expected.
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`.