Security
Verify Phoenix signatures and protect wallet callbacks
Every Phoenix Prediction wallet callback is signed. Your backend must verify the signature before changing a player balance.
Platform Public Key
Fetch Phoenix's Ed25519 public key:
GET https://prediction.phoenixverse.io/.well-known/signing-key.pemCache the key, and refetch it if signature verification fails after a Phoenix key rotation notice.
Request Headers
Phoenix sends:
| Header | Description |
|---|---|
content-type: application/json | JSON request body |
signature | Base64url Ed25519 signature over the raw request body |
x-provider: phoenix-prediction-market | Provider identifier |
Verify the signature over the exact raw body bytes. Do not re-serialize JSON before verifying.
Node.js Verification Example
import { createPublicKey, verify } from 'node:crypto';
const publicKey = createPublicKey(process.env.PHOENIX_PREDICTION_PUBLIC_KEY_PEM!);
export function verifyPhoenixSignature(rawBody: Buffer, signature: string) {
const decoded = Buffer.from(signature, 'base64url');
return verify(null, rawBody, publicKey, decoded);
}For Ed25519, Node's verify algorithm argument is null.
Endpoint Protection
- Accept wallet calls only on HTTPS.
- Verify the signature before parsing business fields.
- Reject missing or invalid signatures with HTTP
401. - Keep a durable transaction table keyed by
tx_id. - Log request IDs, wallet response type, and signature verification result.
- Do not rely on client-side Phoenix events as proof that money moved.
Operator Launch Keys
You also provide Phoenix with an Ed25519 public key. Phoenix uses that key to verify:
- Launch JWTs minted by your backend
- Signed requests you make to the Operator API
Your private key must stay server-side. Rotate it if it is exposed.