# Token Generation
This section details the process for generating a security token for write (`set.*`) commands.
1. Call `get.device.info` to obtain the unique salt value for the device.
2. For each write command, you must provide the `ts` (timestamp), `token`, and `account` fields.
3. The token is a SHA256 hash derived from a concatenated string of `command + password + salt + timestamp`.
4. The resulting 32-byte SHA256 hash is then encoded in Base64.
5. The first 8 characters of the Base64 string serve as the token.
6. For commands that require encrypted parameters (e.g., `set.miner.pools`, `set.user.change_passwd`), the full 32-byte SHA256 hash is used as the AES encryption key.
7. The encrypted parameter value is then Base64 encoded and sent in the `param` field.
## Examples
### Token Generation (C Example)
```c
unsigned char sha256_data[32];
char tmp_buff[256];
const char *str_cmd = "set.miner.pools";
const char *str_salt = "QbVy1Ou3";
const char *str_password = "abcdefg";
time_t ts = time(NULL);
int str_len = snprintf(tmp_buff, sizeof(tmp_buff), "%s%s%s%d", str_cmd, str_password, str_salt, ts);
mbedtls_sha256((unsigned char *)tmp_buff, str_len, (unsigned char *)sha256_data, 0);
// sha256_data is the aes key if needed.
unsigned char dst_buff[2048];
size_t olen = 0;
mbedtls_base64_encode(dst_buff, sizeof(dst_buff), &olen, sha256_data, 32);
dst_buff[8] = 0;
strcpy(str_token, (char *)dst_buff);
// we get token info in str_token.
```
### Parameter Encryption Example (`set.miner.pools`)
Unencrypted param structure:
```json
{
"cmd": "set.miner.pools",
"ts": 2118015,
"token": "mvmqClRR",
"account": "super",
"param": [{
"pool": "stratum+tcp://192.168.2.3:3834",
"worker": "work1",
"passwd": "123"
}]
}
```
Encryption process:
```c
unsigned char sha256_data[32];
char tmp_buff[256];
const char *str_cmd = "set.miner.pools";
const char *str_salt = "QbVy1Ou3";
const char *str_password = "abcdefg";
time_t ts = time(NULL);
int str_len = snprintf(tmp_buff, sizeof(tmp_buff), "%s%s%s%d", str_cmd, str_password, str_salt, ts);
mbedtls_sha256((unsigned char *)tmp_buff, str_len, (unsigned char *)sha256_data, 0);
// sha256_data is the aes key if needed.
// Example sha256 data:
// 9A F9 AA 0A 54 51 14 32 22 45 95 4A 83 A1 3C DB
// BF D1 1C 0E F1 49 0B 13 D3 C3 83 43 6E 1A DC 9E
unsigned char dst_buff[2048];
size_t olen = 0;
mbedtls_base64_encode(dst_buff, sizeof(dst_buff), &olen, sha256_data, 32);
dst_buff[8] = 0;
strcpy(str_token, (char *)dst_buff); // we get token info in str_token.
// Then encrypt the 'param' info:
// '[{"pool":"stratum+tcp://192.168.2.3:3834","worker":"work1","passwd":"123"}]'
// And translate into base64 as:
// "ieq1bCRfvw7f/Xbiy5lRsa38H5IKuOlgkkhRk5ZoZXyDxG2u//kYjZ+Nt8WxH/oOkwt0ZvVNiUFIxWFYuYXXTNg2ZZ8h7SCq8BggIMkM8zn="
// Replace the 'param' item and then send into whatminer device.
```
Final encrypted request:
```json
{
"cmd": "set.miner.pools",
"ts": 2118015,
"token": "mvmqClRR",
"account": "super",
"param": "ieq1bCRfvw7f/Xbiy5lRsa38H5IKuOlgkkhRk5ZoZXyDxG2u//kYjZ+Nt8WxH/oOkwt0ZvVNiUFIxWFYuYXXTNg2ZZ8h7SCq8BggIMkM8zn="
}
```