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
- Collect all fields from the request body except
hash - Filter out fields whose value is empty,
null, orundefined— including the literal strings"null"/"undefined". (The body is form-urlencoded, so a field that wasnullat the source arrives as the string"null"; you must drop it or the signature won't match — this matters for native deposits wherecontractAddressis null.) - Sort the remaining fields alphabetically by key
- Join them as
key=valuepairs separated by& - Append the shared secret key to the end of the string (no separator)
- 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;
}