> ## Documentation Index
> Fetch the complete documentation index at: https://docs-en.basswallet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Signature Authentication

* Except for general-purpose APIs, all other APIs require signature verification to ensure that request data has not been maliciously tampered with.
* If a signature is required, it must be included in the HTTP request header using the `Signature` field.
* APIs that require signatures must include the `timestamp` parameter. The value should be the UNIX timestamp (in milliseconds) at the time of the request. The server will validate the timestamp, and requests sent more than `10` seconds prior will be considered invalid.

***

## Steps to Sign a Request

<Steps>
  <Step title="Build the Payload">
    Arrange the parameter list into a string, separating each parameter with `&`. For example:
    `tokenName=USDT&amount=500&chainName=Ethereum&toAddress=0x9C903Cc6233ea0E9275452C13efe967a04EBe58b&timestamp=1724985575933`
  </Step>

  <Step title="Sign the Payload Using HMAC SHA-256">
    ```bash theme={null}
    echo -n "tokenName=USDT&amount=500&chainName=Ethereum&toAddress=0x9C903Cc6233ea0E9275452C13efe967a04EBe58b&timestamp=1724985575933" \
    | openssl dgst -sha256 -hmac "9qsua3vT6TWVFrWBqzwym2brU0fCXMOwPgF0gzGFwgJBheikFC3LX7lZ9LFTZIQ1"
    ```
  </Step>

  <Step title="Encode the Signature in Hexadecimal Format">
    `966174f21ae551a832a4830231e3d3dacf4ad326dc437d391ec525dd4fdaab44`
  </Step>
</Steps>

***

## Signature Examples

Below are examples in different programming languages for generating the signature.

<CodeGroup>
  ```python PYTHON theme={null}
  import hmac
  import hashlib
  import requests
  import time

  # Authentication details
  access_key = 'ReplaceWithYourAccessKey'
  secret_key = 'ReplaceWithYourSecretKey'

  # Request parameters
  params = {
      'tokenName': 'USDT',
      'toAddress': '0x9C903Cc6233ea0E9275452C13efe967a04EBe58b',
      'chainName': 'Ethereum',
      'amount': '500.88',
  }

  # Add timestamp
  timestamp = int(time.time() * 1000)  # UNIX timestamp in milliseconds
  params['timestamp'] = timestamp

  # Generate signature
  payload = '&'.join([f'{param}={value}' for param, value in params.items()])
  signature = hmac.new(secret_key.encode("utf-8"), payload.encode("ASCII"), hashlib.sha256).hexdigest()

  # Make the request
  headers = {
      'API-Access-Key': access_key,
      'Signature': signature
  }
  response = requests.post(
      'https://api.basswallet.com/api/v1/account/withdraw',
      headers=headers,
      data=params,
  )
  print(response.json())
  ```

  ```json JAVA theme={null}
  import java.io.OutputStream;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.util.Map;
  import java.util.TreeMap;
  import java.nio.charset.StandardCharsets;
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
  import java.util.Base64;

  public class ApiRequestDemo {
      public static void main(String[] args) {
          try {
              // Authentication details
              String accessKey = "ReplaceWithYourAccessKey";
              String secretKey = "ReplaceWithYourSecretKey";

              // Request parameters
              Map<String, String> params = new TreeMap<>();
              params.put("tokenName", "USDT");
              params.put("toAddress", "0x9C903Cc6233ea0E9275452C13efe967a04EBe58b");
              params.put("chainName", "Ethereum");
              params.put("amount", "500.66");
              long timestamp = System.currentTimeMillis();
              params.put("timestamp", String.valueOf(timestamp));

              // Build payload
              StringBuilder payload = new StringBuilder();
              for (Map.Entry<String, String> entry : params.entrySet()) {
                  if (payload.length() > 0) payload.append("&");
                  payload.append(entry.getKey()).append("=").append(entry.getValue());
              }

              // Generate signature
              Mac hmacSha256 = Mac.getInstance("HmacSHA256");
              SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
              hmacSha256.init(secretKeySpec);
              byte[] hash = hmacSha256.doFinal(payload.toString().getBytes(StandardCharsets.UTF_8));
              String signature = Base64.getEncoder().encodeToString(hash);

              // Send request
              URL url = new URL("https://api.basswallet.com/api/v1/account/withdraw");
              HttpURLConnection connection = (HttpURLConnection) url.openConnection();
              connection.setRequestMethod("POST");
              connection.setRequestProperty("API-Access-Key", accessKey);
              connection.setRequestProperty("Signature", signature);
              connection.setDoOutput(true);

              String postData = payload.toString();
              byte[] postDataBytes = postData.getBytes(StandardCharsets.UTF_8);
              OutputStream os = connection.getOutputStream();
              os.write(postDataBytes);
              os.flush();
              os.close();

              int responseCode = connection.getResponseCode();
              if (responseCode == 200) {
                  java.util.Scanner s = new java.util.Scanner(connection.getInputStream()).useDelimiter("\\A");
                  System.out.println(s.hasNext() ? s.next() : "");
              } else {
                  System.out.println("Error: " + responseCode);
              }
              connection.disconnect();

          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  ```

  ```php PHP theme={null}
    <?php

  // Authentication details
  $accessKey = "ReplaceWithYourAccessKey";
  $secretKey = "ReplaceWithYourSecretKey";

  // Request parameters
  $params = [
      "tokenName" => "USDT",
      "toAddress" => "0x9C903Cc6233ea0E9275452C13efe967a04EBe58b",
      "chainName" => "Ethereum",
      "amount" => "500.66",
      "timestamp" => round(microtime(true) * 1000)
  ];

  // Generate signature
  ksort($params);
  $payload = http_build_query($params);
  $signature = hash_hmac('sha256', $payload, $secretKey);

  // Send request
  $headers = [
      "API-Access-Key: $accessKey",
      "Signature: $signature"
  ];

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, "https://api.basswallet.com/api/v1/account/withdraw");
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($httpCode === 200) {
      echo $response;
  } else {
      echo "Error: HTTP $httpCode\n$response";
  }
  ?>
  ```
</CodeGroup>
