@zoza/sign
v0.1.0
Published
Zoza Sign SDK. Decode raw blockchain transactions (EVM, Solana, Tron, Bitcoin, USDT-TRC20), verify they match user intent before an exchange relays them, and issue cryptographic receipts that prove the check was run. Catches multi-billion-dollar heist pat
Maintainers
Readme
@zoza/sign
Exchange + custodian transaction safety. Decode raw blockchain bytes, verify they match the user's declared intent, issue Ed25519 receipts that prove the check was run. Catches the multi-billion-dollar heist pattern where a "routine withdrawal" is actually a calldata drain.
Install
npm install @zoza/signWho uses this
- Exchanges (custodial + self-custody hybrids) running
verify()on every outbound raw transaction before it's broadcast. Bybit, WazirX, Grinex-class heists all hinged on calldata that didn't match the withdrawal UI — the pattern Sign detects. - Custodians + treasuries verifying each signed withdrawal matches the approval ticket.
- Auditors consuming
verifyReceipt()against archived receipts to prove the check happened, without trusting the live Sign API.
Quick start
import { SignClient } from '@zoza/sign';
const sign = new SignClient({ apiKey: process.env.ZOZA_SIGN_KEY! });
// 1. Decode what the signed bytes actually do
const decoded = await sign.decode({ raw_tx: '0xf86c...' });
// → { chain: 'eth', tx_type: 'legacy', to: '0x...', value: '0x0',
// function: 'approve', token: '0x...', amount: 'MAX_UINT256', risk_flags: [...] }
// 2. Verify it matches the intent your exchange UI declared
const verdict = await sign.verify({
intent: { chain: 'eth', to: '0xCustomerWithdrawAddr', token: 'USDT', amount: '10000' },
raw_tx: '0xf86c...',
});
if (!verdict.match) {
// DO NOT BROADCAST. Archive the attempt for audit.
// verdict.diff explains every field that diverged.
return logAndReject(verdict);
}
// verdict.receipt is Ed25519-signed by Zoza Sign's authority key.
// Archive it. Any auditor can later offline-verify it without us.
await archive(verdict.receipt);Offline verification of archived receipts
// Months later, an auditor validates an archived receipt:
const { public_key } = await sign.getAuthority(); // pin this once
const r = await sign.verifyReceipt({ receipt: archivedReceiptJSON });
// → { valid: true, authority: 'current', signed_at: '...' }The authority key is rotated quarterly; getAuthorityHistory() returns the full chain so old receipts remain verifiable forever.
API
new SignClient({ apiKey, apiUrl?, fetch? })
| Option | Type | Notes |
|---|---|---|
| apiKey | string (required) | Issued at zoza.world/developers/sign. Format sgn_<base64>. |
| apiUrl | string | Default https://sign-api.zoza.world. |
| fetch | typeof fetch | Optional — Node <18 or custom signers. |
Methods
| Method | Auth | Purpose |
|---|---|---|
| decode({ raw_tx }) | public | Decode raw transaction bytes |
| verify({ intent, raw_tx }) | API key | Compare decoded TX to intent, issue signed receipt |
| verifyReceipt({ receipt, public_key? }) | public | Offline verify an archived receipt |
| getAuthority() | public | Current Ed25519 authority pub key |
| getAuthorityHistory() | public | All historical keys (post-rotation) |
| getVerification(id) | public | Retrieve a specific verification by ID |
Chain coverage
EVM (full RLP incl. EIP-1559/2930/4844/7702), Solana, Tron (TRX + TRC-20), Bitcoin (legacy + SegWit + Taproot + BIP-70 PSBTs).
Tests
npm install
npm testLicense
MIT © Zoza
