Phoenix Prediction Docs

Launch Tokens

Mint visitor and player JWTs for Phoenix Prediction iframe launch

Your backend mints Phoenix Prediction launch tokens. The browser receives a ready-to-use token, but it never sees your private signing key.

Phoenix Prediction launch tokens are EdDSA JWTs signed with your Ed25519 private key. Phoenix verifies them with the Ed25519 public key registered on your operator account.

Required Claims

ClaimRequiredDescription
issYesYour Phoenix Prediction operator code
typYesvisitor or player
audYesAudience value assigned for your Phoenix Prediction integration
iatYesIssued-at time, Unix seconds
expYesExpiry time, Unix seconds
subPlayer onlyYour player ID for this user
namePlayer onlyDisplay name Phoenix can show in player-facing UI
avatarPlayer onlyAvatar object

Use short-lived tokens. A practical starting point is minutes, not hours. Phoenix can confirm the exact TTL target for your environment.

Visitor Token

Use a visitor token when the user is not authenticated or should only browse.

{
  "iss": "acme",
  "typ": "visitor",
  "aud": "acme_phoenix_prediction",
  "iat": 1779100000,
  "exp": 1779100900
}

Visitor tokens must not include sub.

Player Token

Use a player token after your site has authenticated the user.

{
  "iss": "acme",
  "typ": "player",
  "sub": "operator-player-123",
  "aud": "acme_phoenix_prediction",
  "iat": 1779100000,
  "exp": 1779100300,
  "name": "Player Name",
  "avatar": { "kind": "none" }
}

sub is your stable player identifier. Your integration continues to use that ID when investigating wallet and support questions.

Avatar Values

Use none when you do not want to show an avatar:

{ "kind": "none" }

If image avatars are enabled for your operator, Phoenix will provide the accepted image shape and validation rules.

Node.js Example

import { SignJWT, importPKCS8 } from 'jose';

const privateKeyPem = process.env.PHOENIX_PREDICTION_OPERATOR_PRIVATE_KEY_PEM!;
const key = await importPKCS8(privateKeyPem, 'EdDSA');

const now = Math.floor(Date.now() / 1000);

export async function mintPlayerToken(player: {
  id: string;
  name: string;
}) {
  return new SignJWT({
    typ: 'player',
    sub: player.id,
    name: player.name,
    avatar: { kind: 'none' },
  })
    .setProtectedHeader({ alg: 'EdDSA' })
    .setIssuer('acme')
    .setAudience('acme_phoenix_prediction')
    .setIssuedAt(now)
    .setExpirationTime(now + 5 * 60)
    .sign(key);
}

Token Rotation

When a token is close to expiry, the iframe can ask the parent page for a replacement. Your site should mint a fresh token for the same visitor or player session and send it to the iframe with phoenix:setToken.

On this page