SOLEX

Integration Docs

Everything you need to embed Solex games into your casino platform — Prediction Markets and TraderHero.

Two Integration Modes

Both games support two modes of operation. The mode is determined by whether you pass a JWT token to the iframe.

Demo Mode (Unauthenticated)
  • • No JWT token passed
  • • Simulated balance managed by the host page
  • • No webhooks fired — balance changes via postMessage only
  • • Great for previews and try-before-you-buy
Authenticated Mode (JWT)
  • • Host passes JWT token to iframe
  • • Backend verifies JWT against partner config
  • • Real balance managed server-side via webhooks
  • • All transactions tracked with unique IDs

Prediction Markets — Iframe Setup

Prediction Markets are embedded via an iframe. The host page communicates with the iframe using the postMessage API through our SDK.

<iframe id="solex-frame"
  src="https://solex-integration-demo-production.up.railway.app/embed/embed/markets"
  style="width:100%;aspect-ratio:16/9;border:none;">
</iframe>

<script src="/solex-casino-sdk.js"></script>
<script>
  const sdk = new SolexCasinoSDK(
    document.getElementById('solex-frame'),
    {
      casinoId: 'your-partner-uuid',
      apiKey: 'sk_your_api_key',
      user: { id: 'player_123', displayName: 'Player' },
      balance: { available: 1500, reserved: 0,
                 currency: 'USD', currencySymbol: '$' },
    }
  );
  sdk.initialize();
</script>

TraderHero — Iframe Setup

TraderHero uses a simpler postMessage protocol (no SDK wrapper needed). The host page communicates directly with jackpot_* messages.

<iframe id="traderhero-frame"
  src="https://solex-integration-demo-production.up.railway.app/jackpot/"
  style="width:100%;aspect-ratio:4/3;border:none;">
</iframe>

<script>
  const iframe = document.getElementById('traderhero-frame');

  // Send initial balance when iframe loads
  iframe.onload = () => {
    iframe.contentWindow.postMessage(
      { type: 'jackpot_balance_response', balance: 1500 },
      '*'
    );
  };

  // Listen for iframe messages
  window.addEventListener('message', (e) => {
    const { type, amount } = e.data;
    if (type === 'jackpot_balance_deduct') {
      // Player bet — deduct balance, confirm
      balance -= amount;
      iframe.contentWindow.postMessage(
        { type: 'jackpot_balance_response', balance },
        '*'
      );
    }
    if (type === 'jackpot_balance_credit') {
      // Player won — credit balance, confirm
      balance += amount;
      iframe.contentWindow.postMessage(
        { type: 'jackpot_balance_response', balance },
        '*'
      );
    }
  });
</script>
API Key Required

TraderHero backend endpoints (POST /jackpot/rounds, POST /jackpot/rounds/:id/settle) require the X-Casino-Key header. The iframe calls these directly — ensure your API key is configured.

Prediction Markets — SDK Messages

MessageDirectionDescription
CASINO_INITHost → IframeInitialize session with user, balance, theme, currency
CASINO_BALANCE_UPDATEHost → IframeUpdate player balance (after webhook confirmation)
CASINO_THEME_UPDATEHost → IframeChange CSS variables for white-label theming
CASINO_BANNER_UPDATEHost → IframeSet image or HTML banner at 3 positions
CASINO_AD_SLOTS_UPDATEHost → IframeInject inline ad cards into the feed
CASINO_BET_RESPONSEHost → IframeApprove or reject a bet request
CASINO_SESSION_REFRESHHost → IframePass new JWT token for re-authentication
SOLX_READYIframe → HostIframe loaded and ready for messages
SOLX_BET_REQUESTIframe → HostPlayer wants to place a bet
SOLX_BET_CONFIRMEDIframe → HostBet confirmed by backend
SOLX_PAYOUT_DUEIframe → HostMarket resolved, winnings ready for payout
SOLX_AUTH_REQUIREDIframe → HostJWT authentication needed to continue

TraderHero — PostMessage Protocol

TraderHero uses a separate, non-versioned protocol. Messages are plain objects without the version: "1.0" wrapper.

MessageDirectionDescription
jackpot_balance_responseHost → IframeSend/confirm balance (on load, after debit/credit)
jackpot_settingsHost → IframeConfigure RTP (50–99) for the game session
jackpot_theme_updateHost → IframeApply CSS variables for white-label theming
jackpot_banner_updateHost → IframeSet banner ads (bottom/left/right, image or HTML)
jackpot_balance_requestIframe → HostRequest current balance (sent on iframe load)
jackpot_balance_deductIframe → HostDeduct bet amount from player balance
jackpot_balance_creditIframe → HostCredit payout to player balance

Webhook Integration

When webhook mode is enabled, Solex sends HTTP POST requests to your configured webhook URL for every financial event. This applies to both Prediction Markets and TraderHero.

Webhook Events

EventWhenGame Types
depositPlayer places a bet — deduct from balanceBoth
winPlayer wins — credit the payoutBoth
refundMarket cancelled or event voided — return the betPrediction Markets

Webhook Payload

{
  "event": "deposit" | "win" | "refund",
  "transaction_id": "uuid-v4",       // Unique per webhook — use for idempotency
  "timestamp": "2026-03-02T12:00:00Z",
  "casino_id": "partner-uuid",
  "user_id": "external-user-id",
  "amount": 100.00,
  "currency": "USD",                  // Currency from partner config
  "metadata": {
    // Prediction Markets:
    "market_id": "uuid",
    "market_title": "...",
    "bet_id": "uuid",
    "outcome": "YES",

    // TraderHero:
    "game_type": "jackpot",
    "round_id": "uuid",
    "bet_amount": 25,
    "payout_amount": 50,
    "target_rtp": 90
  }
}

Expected Response

{
  "status": "success" | "failure",
  "balance": 1400.00,              // Updated balance after operation
  "reason": "insufficient_balance" // Only on failure
}
Idempotency

Every webhook includes a unique transaction_id. Your server should use this to ensure idempotent processing — if you receive the same transaction_id twice (e.g. due to retries), return the same response without double-processing.

Security Headers

X-Solex-Signature: sha256=<hmac-hex>
X-Solex-Timestamp: <unix-seconds>
X-Solex-Event: deposit | win | refund
X-Solex-Transaction-Id: <uuid>

Verify signatures using HMAC-SHA256: HMAC(secret, "{timestamp}.{body}"). The signing key is your webhook_signing_key (or api_secret as fallback).

Retry Policy

Failed webhooks are retried up to 4 times with exponential backoff: 5s, 30s, 2min. Each retry uses the same transaction_id but a fresh signature.

Currency Support

Currency is configured per partner. All bets, payouts, and webhook amounts use the partner's configured currency.

// Set during partner registration
POST /api/v1/casino/auth/register
{
  "name": "My Casino",
  "defaultCurrency": "EUR",    // USD, EUR, GBP, BTC, etc.
  ...
}

// Or update later
PATCH /api/v1/casino/admin/config
Headers: X-Casino-Key: your_key
{
  "defaultCurrency": "BTC"
}

// Currency flows through to:
// - Webhook payloads (currency field)
// - Transaction records
// - Prediction Markets SDK (CASINO_INIT balance.currency)
// - TraderHero (jackpot round currency field)

JWT Authentication

JWT tokens authenticate players for the webhook flow. The same JWT system works for both Prediction Markets and TraderHero. Configure either a shared HMAC secret or a verification URL on your partner settings.

JWT Payload

{
  "sub": "external_user_id",       // Required: your user ID
  "name": "Player Display Name",   // Optional: shown in UI
  "iat": 1709400000,
  "exp": 1709403600,
  "casino_id": "partner-uuid"      // Your partner ID
}

Verification Endpoint

POST /api/v1/casino/auth/verify-jwt
Content-Type: application/json

{
  "jwt": "<token>",
  "casinoId": "<partner-uuid>"
}

// Success response
{
  "valid": true,
  "user": {
    "id": "internal-uuid",
    "displayName": "Test Player",
    "externalUserId": "external_user_id"
  },
  "session": {
    "token": "solex_session_...",
    "expiresAt": "2026-03-02T13:00:00Z"
  }
}

Passing JWT to Iframes

Prediction Markets
sdk.refreshSession(jwtToken)

Sends CASINO_SESSION_REFRESH message to iframe

TraderHero
iframe.postMessage({ type: 'jackpot_settings', jwt: token }, '*')

JWT passed alongside balance/settings messages

Transaction Ledger

All financial activity is tracked in the transaction ledger. Each transaction has a unique ID and links back to the originating bet or jackpot round.

TypeDirectionGameWhen
bet_placedDebitPrediction MarketsPlayer places a market bet
payoutCreditPrediction MarketsMarket resolves in player's favor
bet_refundCreditPrediction MarketsMarket cancelled, bet returned
fee_collectionDebitPrediction MarketsCasino/platform fees collected
jackpot_betDebitTraderHeroPlayer enters a jackpot round
jackpot_payoutCreditTraderHeroPlayer wins a jackpot round

Query the ledger via GET /api/v1/casino/admin/reports/transactions with your API key. Both game types appear in the same ledger.

API Endpoints

Prediction Markets

GET  /api/v1/markets — List all markets
GET  /api/v1/markets/:id — Get market details + prices
POST /api/v1/betting/calculate — Calculate bet (shares, cost, fees)
POST /api/v1/betting/place — Place a bet (requires X-Casino-Key)

TraderHero Jackpot

GET  /api/v1/jackpot/config — Get game config (public)
POST /api/v1/jackpot/rounds — Create round (requires X-Casino-Key)
POST /api/v1/jackpot/rounds/:id/settle — Settle round (requires X-Casino-Key)

Casino Admin

POST  /api/v1/casino/auth/register — Register partner
POST  /api/v1/casino/auth/verify-jwt — Verify JWT token
GET   /api/v1/casino/admin/config — Get partner config
PATCH /api/v1/casino/admin/config — Update config (fees, webhook, currency)
GET   /api/v1/casino/admin/reports/summary — Financial summary
GET   /api/v1/casino/admin/reports/monthly — Monthly report
GET   /api/v1/casino/admin/reports/transactions — Transaction ledger

User Data (Public)

GET /api/v1/casino/users/:userId/bets — Prediction market bet history
GET /api/v1/casino/users/:userId/positions — Market positions
GET /api/v1/casino/users/:userId/jackpot-rounds — Jackpot round history