Authentication

You'll need to authenticate your requests to access any of the endpoints in the Fystack API. In this guide, we'll look at how authentication works. Fystack uses HMAC-based authentication to securely verify the authenticity of your API requests.

HMAC Authentication

Fystack API uses a secure HMAC-based authentication system that requires you to sign your requests with your API secret. Each request needs three authentication headers:

Required authentication headers

ACCESS-API-KEY: your_api_key
ACCESS-TIMESTAMP: current_unix_timestamp
ACCESS-SIGN: base64_encoded_hmac_signature

The HMAC signature is generated by combining the HTTP method, request path, timestamp, and request body (if applicable), then signing it with your API secret.

Example Request with Authentication Headers

Here's an example of how to make an authenticated request to the Fystack API:

Example authenticated request

curl https://api.fystack.io/api/v1/wallets \
-H "ACCESS-API-KEY: your_api_key" \
-H "ACCESS-TIMESTAMP: 1667836889" \
-H "ACCESS-SIGN: YourBase64EncodedSignature=="

Computing the ACCESS-SIGN

To compute the HMAC signature, you'll need to:

  1. Create a query string from your parameters (sorted by key)
  2. Sign this string with your API secret using HMAC-SHA256
  3. Encode the result in hexadecimal format

Here's how to compute the signature in JavaScript:

Computing the HMAC signature

const crypto = require('crypto');

function computeHMAC(apiSecret, params) {
  // Sort parameters by key
  const sortedParams = Object.keys(params)
    .sort()
    .reduce((acc, key) => {
      acc[key] = params[key];
      return acc;
    }, {});
  
  // Create query string
  const queryString = Object.entries(sortedParams)
    .map(([key, value]) => `${key}=${value}`)
    .join('&');
  
  // Create HMAC-SHA256 signature
  const hmac = crypto.createHmac('sha256', apiSecret);
  hmac.update(queryString);
  
  // Get digest and encode in hex
  return hmac.digest('hex');
}

// Example for GET request
const timestamp = Math.floor(Date.now() / 1000).toString();
const getParams = {
  method: 'GET',
  path: '/api/v1/wallets',
  timestamp: timestamp
};

const signature = computeHMAC('your_api_secret', getParams);

console.log('GET Request Headers:');
console.log('ACCESS-API-KEY:', 'your_api_key');
console.log('ACCESS-TIMESTAMP:', timestamp);
console.log('ACCESS-SIGN:', signature);

// Example for POST request with a body
const postBody = {
  name: "My New Wallet",
  wallet_type: "mpc"
};

const postParams = {
  method: 'POST',
  path: '/api/v1/wallets',
  timestamp: timestamp,
  body: JSON.stringify(postBody)
};

const postSignature = computeHMAC('your_api_secret', postParams);

console.log('\nPOST Request Headers:');
console.log('ACCESS-API-KEY:', 'your_api_key');
console.log('ACCESS-TIMESTAMP:', timestamp);
console.log('ACCESS-SIGN:', postSignature);

Always keep your API secret safe and reset it if you suspect it has been compromised.

Computing signatures

import CryptoJS from 'crypto-js'

export async function computeHMAC(
  apiSecret: string,
  params: Record<string, string>
): Promise<string> {
  const encodedParams = Object.entries(params)
    .map(([key, value]) => `${key}=${value}`)
    .join('&')

  const digest = CryptoJS.HmacSHA256(encodedParams, apiSecret)
  return digest.toString(CryptoJS.enc.Hex)
}

// Example usage
const timestamp = Math.floor(Date.now() / 1000).toString()
const signature = await computeHMAC('your_api_secret', {
  method: 'GET',
  path: '/api/v1/wallets',
  timestamp: timestamp
})

const headers = {
  'ACCESS-API-KEY': 'your_api_key',
  'ACCESS-TIMESTAMP': timestamp,
  'ACCESS-SIGN': signature
}

Request signing process

  1. Create a parameter dictionary containing:

    • HTTP method (uppercase)
    • Request path (including query string)
    • UNIX timestamp (seconds)
    • Request body (if POST/PUT/PATCH)
  2. Create HMAC SHA256 signature:

    • Sort parameters by key
    • Convert parameters to query string format (key1=value1&key2=value2)
    • Sign the query string with your API secret
    • Encode the result in hexadecimal format
  3. Add required headers:

    • ACCESS-API-KEY: Your API key
    • ACCESS-TIMESTAMP: The timestamp used in signature
    • ACCESS-SIGN: The computed signature

Keep your API secret secure and never share it. The API key can be shared but the secret should remain private.