Webhooks
Signature Verification

Signature Verification

Every request includes a hash field. You must verify this signature to ensure the request originates from the system and has not been tampered with.

Algorithm

  1. Collect all fields from the request body except hash
  2. Filter out fields whose value is empty, null, or undefinedincluding the literal strings "null" / "undefined". (The body is form-urlencoded, so a field that was null at the source arrives as the string "null"; you must drop it or the signature won't match — this matters for native deposits where contractAddress is null.)
  3. Sort the remaining fields alphabetically by key
  4. Join them as key=value pairs separated by &
  5. Append the shared secret key to the end of the string (no separator)
  6. Compute the MD5 hex digest of the resulting string

Example

import { createHash } from 'crypto';
 
function verifySignature(params: Record<string, string>, secretKey: string): boolean {
  const hash = params.hash;
  if (!hash) return false;
 
  const canonical = Object.entries(params)
    .filter(([k, v]) => k !== 'hash' && v != null && v !== 'null' && v !== 'undefined' && `${v}` !== '')
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([k, v]) => `${k}=${v}`)
    .join('&');
 
  const expected = createHash('md5')
    .update(canonical + secretKey, 'utf8')
    .digest('hex');
 
  return expected === hash;
}