API Reference

Complete reference for the Lucky Spin backend API. All endpoints return JSON. Base URL: https://dice.ziesto.ca

Base URL & Rate Limiting

The API has no authentication. Rate limiting is applied at the server level:

  • General: 500 requests per 15 minutes per IP
  • House seed generation: 20 requests per minute per IP

All responses follow this format:

{
  "success": true | false,
  "data": { ... },        // present on success
  "error": "message"      // present on failure
}

Spin Endpoints

GET /api/spin/status

Get the current game status including contract balance, pending spins, and recent history.

Response:

{
  "success": true,
  "data": {
    "contractBalance": "1000000000",  // satoshis (10 QTUM)
    "pendingSpins": 1,
    "recentSpins": [
      {
        "spinId": 5,
        "player": "7926223070...",
        "segment": 3,
        "payout": "130000000",
        "resolvedAt": 1706123456789
      }
    ]
  }
}

GET /api/spin/house-seed

Generate a new house seed and return its keccak256 hash. The actual seed is stored on the backend for later reveal. Seeds expire after 2 hours.

Rate limit: 20 requests per minute per IP

Response:

{
  "success": true,
  "data": {
    "houseSeedHash": "0x3a7f8c...",   // bytes32 keccak256 hash
    "expiresAt": 1706130656789       // Unix timestamp (ms)
  }
}
Workflow

Call this endpoint before placing a spin. Pass the houseSeedHash to the smart contract's placeSpin() function. The backend will later reveal the original seed during revealAndResolve().

POST /api/spin/submit-player-seed

Submit the player's revealed seed after the spin is confirmed on-chain. This triggers the backend to call revealAndResolve() on the contract.

Request Body:

ParameterTypeDescription
spinIdnumberThe on-chain spin ID
playerSeedstringThe original seed (bytes32, 0x + 64 hex chars)

Request:

POST /api/spin/submit-player-seed
Content-Type: application/json

{
  "spinId": 5,
  "playerSeed": "0xabcdef0123456789..."
}

Response:

{
  "success": true,
  "data": {
    "spinId": 5,
    "playerSeedReceived": true,
    "revealTxid": "abc123..."  // or null if pending
  }
}

Errors:

CodeErrorCause
400Missing required fieldsspinId or playerSeed not provided
400Invalid player seed formatSeed not in bytes32 format
404Spin not found or not pendingspinId doesn't match a pending spin

GET /api/spin/:spinId

Get details of a specific spin by ID. Works for both pending and resolved spins.

ParameterTypeDescription
spinIdnumber (URL)The on-chain spin ID

Response (resolved):

{
  "success": true,
  "data": {
    "spinId": 5,
    "player": "7926223070...",
    "segment": 3,
    "payout": "130000000",
    "status": "resolved",
    "resolvedAt": 1706123456789
  }
}

Response (pending):

{
  "success": true,
  "data": {
    "spinId": 6,
    "player": "7926223070...",
    "hasPlayerSeed": false,
    "status": "pending"
  }
}

GET /api/spin/find/by-hash?houseSeedHash=0x...

Find a pending spin by its house seed hash. Used by the frontend to discover the on-chain spin ID after placing a transaction.

ParameterTypeDescription
houseSeedHashstring (query)The house seed hash used when placing the spin

Response:

{
  "success": true,
  "data": {
    "spinId": 5,
    "player": "7926223070...",
    "hasPlayerSeed": false
  }
}

GET /api/spin/history/recent?limit=20

Get recent resolved spins in reverse chronological order.

ParameterTypeDefaultDescription
limitnumber (query)20Max number of spins to return

Response:

{
  "success": true,
  "data": [
    {
      "spinId": 5,
      "player": "7926223...",
      "segment": 3,
      "payout": "130000000",
      "resolvedAt": 1706123456789
    }
  ]
}

GET /api/spin/prizes/info

Get the prize configuration including spin cost and all segment prizes.

Response:

{
  "success": true,
  "data": {
    "spinCost": "100000000",
    "prizes": [
      { "segment": 0, "amount": "40000000",  "color": "red",    "label": "0.4 QTUM" },
      { "segment": 1, "amount": "70000000",  "color": "orange", "label": "0.7 QTUM" },
      { "segment": 2, "amount": "110000000", "color": "green",  "label": "1.1 QTUM" },
      { "segment": 3, "amount": "130000000", "color": "blue",   "label": "1.3 QTUM" },
      { "segment": 4, "amount": "40000000",  "color": "red",    "label": "0.4 QTUM" },
      { "segment": 5, "amount": "70000000",  "color": "orange", "label": "0.7 QTUM" },
      { "segment": 6, "amount": "110000000", "color": "green",  "label": "1.1 QTUM" },
      { "segment": 7, "amount": "200000000", "color": "gold",   "label": "2.0 QTUM" }
    ]
  }
}

Error Handling

All error responses follow the standard format:

{
  "success": false,
  "error": "Human-readable error message"
}
HTTP CodeMeaningCommon Causes
400Bad RequestMissing or invalid parameters
404Not FoundSpin ID doesn't exist
429Too Many RequestsRate limit exceeded
500Internal ErrorQTUM node unreachable, contract call failed