Keywave

Verify & Stamp (Solana + optional EVM mirror)

This guide shows the full Keywave proof flow:

  1. Get phrase (anti-spoof challenge)
  2. Record & upload user audio
  3. Verify voice (speaker match + checks)
  4. Stamp on Solana (always included)
  5. (Optional — Production & Scale) Mirror to EVM via EAS

Prerequisites


  1. 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.