Verify & Stamp (Solana + optional EVM mirror)
This guide shows the full Keywave proof flow:
- Get phrase (anti-spoof challenge)
- Record & upload user audio
- Verify voice (speaker match + checks)
- Stamp on Solana (always included)
- (Optional — Production & Scale) Mirror to EVM via EAS
Prerequisites
- A Keywave API key with the correct scope
- For testing, send
x-keywave-env: sandbox - Configure Allowed Upload Host Prefixes and VOICE_UPLOAD_HMAC_SECRET in your backend
- Get a phrase
Request a short, per-session phrase for the user to speak.
curl -s https://api.keywave.io/api/v1/phrase \
-H "Content-Type: application/json" \
-H "x-api-key: <YOUR_API_KEY>" \
-H "x-keywave-env: sandbox" \
-d '{"wallet":"<WALLET_ID>"}' | jq
Response (example)
{
"ok": true,
"phrase_id": "ph_123",
"prompt": "blue galaxies shimmer tonight",
"expires_at": "2025-10-07T12:34:56Z"
}
2) Record & upload audio
Record the user reading the phrase. Upload to your signed URL (recommended) or a public URL you control.
// Browser (TypeScript) example — upload helper
export async function recordAndUpload(blob: Blob) {
// 1) Ask your backend for a signed URL
const signed = await fetch("/api/uploads/signed", { method: "POST" }).then(r => r.json());
// 2) Upload file (PUT or POST based on your signer)
await fetch(signed.url, { method: "PUT", body: blob });
// 3) Return public URL you will pass to Keywave
return { fileUrl: signed.publicUrl, sha256: signed.sha256 };
}
Tip: Keep files small for mobile. We support common web formats (e.g., .m4a/AAC, .webm, .wav, .mp3).
3) Verify voice (speaker match + checks)
Submit the phrase_id, the uploaded audioUrl, and a user identifier (e.g., wallet).
curl -s https://api.keywave.io/api/v1/verify \
-H "Content-Type: application/json" \
-H "x-api-key: <YOUR_API_KEY>" \
-H "x-keywave-env: sandbox" \
-d '{
"phrase_id": "ph_123",
"wallet": "wallet:solana:YourUserWallet",
"audioUrl": "https://cdn.yourapp.com/u/abc123.m4a",
"projection_id":"p0",
"params_version":"v1"
}' | jq
Response (example)
{
"ok": true,
"success": true,
"wallet": "wallet:solana:YourUserWallet",
"gates": {
"phrase_match": true,
"speaker_score": 0.82,
"speaker_min": 0.75,
"spoof_score": 0.93,
"aasist_min": 0.75,
"is_spoofed": false,
"all_passed": true
},
"verification_id": "ver_789"
}
If gates.all_passed is true, proceed to stamping.
4) Stamp on Solana (always included)
Stamps are part of every successful proof; Solana network fees are included.
curl -s https://api.keywave.io/api/v1/stamp \
-H "Content-Type: application/json" \
-H "x-api-key: <YOUR_API_KEY>" \
-H "x-keywave-env: sandbox" \
-d '{ "verification_id": "ver_789" }' | jq
Response (example)
{
"ok": true,
"chain": "solana",
"tx_signature": "5aQ...ZpH",
"explorer_url": "https://explorer.solana.com/tx/5aQ...ZpH?cluster=devnet"
}
5) (Optional) EVM mirror via EAS
Available by request for Production & Scale. Your Solana stamp can be mirrored to EVM using the Ethereum Attestation Service (EAS).
Enable by passing a query flag at stamp time:
curl -s "https://api.keywave.io/api/v1/stamp?mirror=evm" \
-H "Content-Type: application/json" \
-H "x-api-key: <YOUR_API_KEY>" \
-H "x-keywave-env: sandbox" \
-d '{ "verification_id": "ver_789" }' | jq
Response (example)
{
"ok": true,
"solana": { "tx_signature": "5aQ...ZpH" },
"evm": {
"chain_id": 8453,
"eas_uid": "0xabc...def",
"explorer_url": "https://basescan.org/attestation/0xabc...def"
}
}
Learn more in EVM Mirroring (EAS)
.
Rate limits & retries
Use Retry-After and exponential backoff on 429 responses.
export async function withBackoff<T>(fn: () => Promise<T>) {
let delay = 500;
for (let i = 0; i < 5; i++) {
try { return await fn(); }
catch (e: any) {
const retryAfter = Number(e?.response?.headers?.get?.("Retry-After")) || 0;
const wait = Math.max(retryAfter * 1000, delay);
await new Promise(r => setTimeout(r, wait));
delay *= 2;
}
}
throw new Error("Max retries reached");
}
Sandbox defaults (typical): 30 RPM (Pilot), 250 RPM (Production). Bursts/contracts can raise limits.
Errors
Common error shapes:
{ "ok": false, "code": "INVALID_API_KEY", "message": "…" }
{ "ok": false, "code": "RATE_LIMITED", "message": "…", "retry_after": 3 }
{ "ok": false, "code": "PHRASE_EXPIRED", "message": "…" }
{ "ok": false, "code": "AUDIO_UNAVAILABLE", "message": "…" }
Security tips
Only accept uploads from allowed host prefixes
HMAC-sign uploads with VOICE_UPLOAD_HMAC_SECRET
Never expose server secrets in the browser
FAQs
Do you include Solana fees?
Yes. All proof stamps include Solana network fees.
Do you support EVM stamping?
Yes. Keywave can optionally mirror Solana attestations to EVM chains using the Ethereum Attestation Service (EAS). This is available by request for Production and Scale users.
Do retries count as proofs?
Each API call is a proof. Use Retry-After + backoff to avoid unnecessary retries.