ThrillTech Jackpots SDK

The ThrillTech Jackpots SDK is a TypeScript library that connects your casino frontend to Hub88’s ThrillTech Jackpot platform. ThrillTech jackpots are opt-in, player-funded side-bet jackpot systems designed to enhance player engagement and retention through real-time, customizable jackpot experiences. This SDK gives operators access to real-time jackpot functionality, player engagement tools, and seamless integration with existing game lobbies.

With this SDK, you can:

  • Authenticate players to participate in jackpots,

  • Subscribe to real-time jackpot events (updates, wins, opt-in changes),

  • Allow players to opt-in or opt-out of jackpots with optional contribution values,

  • Fetch leaderboards, sources, currencies, and jackpot metadata,

  • Display jackpots dynamically in your lobby and games,

  • Trigger animations for jackpot wins using the ThrillTech animation driver

The SDK lets operators focus on custom UI and player experience, while jackpot logic, event streaming, and payout handling are managed by Hub88 and ThrillTech.

Architecture

  • Hub88 provides authentication and event distribution via SDK init token.

  • ThrillTech (TT) manages jackpot creation, payout configuration, and animations.

  • Operator backend authenticates players and passes init payload to the frontend.

  • Casino frontend initialises SDK, listens to events, and updates UI accordingly.

Communication Flow

SDK key communication flow

Integration Steps

Prerequisites

  • Node.js (v14 or later is recommended)

  • npm or yarn

Architecture Overview

The SDK consists of the following main components:

  • Hub88 ThrillTech Connect: Core client class that handles WebSocket connections and event management;

  • Request Factory: Handles API requests for jackpot operations, opt-in/out, and leaderboard data

  • Event System: Pub/sub pattern for handling real-time events from the ThrillTech server.


Step 1: Authenticate Player (Backend)

Your backend must authenticate players with Hub88 before initialising the SDK.

Endpoint:

POST /operator/generic/v2/agnostic-jackpot/user/authenticate

Sample Request:

{
  "user": "john12345",
  "token": "f562a685-a160-4d17-876d-ab3363db331c",
  "operator_id": 10,
  "sub_partner_id": null,
  "currency": "EUR",
  "country": "EE"
}

Sample Response:

{
  "optin": false,
  "sdk_init_token": {
    "token": "QTEyOEdDTQ...", // encoded JSON string
    "attributes": "eyJ1c2VyIjoiMTc0OTYyNzk==" // base64 encoded JSON string
  }
}

Return this response securely to the frontend.

Step 2: Initialise SDK Client

Client Initialisation

import {
  Hub88ThrillConnect,
  Hub88ConnectArg,
  Connect,
  ConnectEvents
} from 'hub88-thrilltech-connect'

// Authenticate with the casino server -- The above is expected to run on your
// server and payload to be exposed to your casino frontend via API
const url = `${api_url}/operator/generic/agnostic-jackpot/user/authenticate`

const response = await fetch(url, {
  method: 'POST',
  body: JSON.stringify(gamesLauncherURLParams),
  headers: { 'Content-Type': 'application/json' }
})
const responseData: Hub88ConnectArg = await response.json()
return responseData

// On the Casino frontend, the responseData is expected to be available
// We can then create the client like so

// Very important to subscribe to the events; otherwise, the web socket will disconnect after a certain period
const events: ConnectEvents = [
  ConnectEvents.JackpotUpdateEvent,
  ConnectEvents.JackpotWinEvent,
  ConnectEvents.OptInEvent
]

// This ensures events are subscribed to
const settings = { ...responseData, events: events }

// Create client instance
// Client reconnection is handled by the client class
const client: Hub88ThrillConnect = Connect(settings)

Event Handling

Event
Description

ConnectEvents.Connected

Triggered when WebSocket connection is established

ConnectEvents.Disconnected

Triggered when WebSocket connection is closed

ConnectEvents.ConnectionFailed

Triggered when WebSocket connection fails

ConnectEvents.Message

Triggered when any message is received

ConnectEvents.JackpotUpdateEvent

Triggered when jackpot values are updated

ConnectEvents.JackpotWinEvent

Triggered when a jackpot is won

ConnectEvents.OptInEvent

Triggered when opt-in status changes

Step 3: Opt-in / Opt-out

// Opt-in with default contribution
await client.request().optIntoJackpot()

// Opt-in with contribution of 100
await client.request().optIntoJackpot(100)

// Opt-out
await client.request().optOutOfJackpot()

Signature

client.request().optIntoJackpot(contribution_value: number | undefined = undefined)
client.request().optOutOfJackpot(contribution_value: number | undefined = undefined)

Sample response

{
  "status": "success"
}

Step 4: Leaderboard and Jackpot Queries

// Get latest winners (default brand returned from the authenticated user)
await client.request().getLeaderboardinfo()

// Limit results to 10. Default value is 5. Value can range from 1-20.
await client.request().getLeaderboardinfo({ limit: 10 })

// Fetch across all brands
await client.request().getLeaderboardinfo({ all_brands: true })

// Fecth a specific brand
await client.request().getLeaderboardinfo({ brand_id: "test_brand" }) 

Signature

client.request().getLeaderboardinfo({
  all_brands?: boolean
  instance_id?: string
  brand_id?: string
  limit?: number
})

Sample Leaderboard Response

[
  {
    "win_pot_id": "Major", // 'Minor' | 'Major' | 'Mega'
    "win_amount": 500,
    "jackpot_currency": "USD",
    "player_id": "john12345", // operator_user
    "timestamp": 1748551660, // unix timestamp 
    "brand_id": "hub88:testing"
  }
]

Step 5: Fetch Jackpot Metadata

Get Source for Current Brand

client.request().getSources()

Signature

getSources()

Sample Response

[
  {
    "owner_id": "string",
    "source_name": "string",
    "source_id": "string",
    "jackpots": [
      {
        "priority": 0,
        "owner_id": "string",
        "instance_id": "string"
      }
    ]
  }
]

Get Currencies

client.request().getCurrencies()

Signature

client.request().getCurrencies()

Sample Response

[
  {
    "brand_id": "string",
    "base_currency": "string",
    "multipliers": {
      "property1": 0.1,
      "property2": 0.1
    }
  }
]

Get Jackpot for Default Source (Specific Player)

client.request().getJackpotInstance()
client.request().getJackpotInstance(player_id: 'john12345')

Signature

client.request().getJackpotInstance(player_id?: string)

Sample Response

[
  {
    "brand_id": "string",
    "base_currency": "string",
    "multipliers": {
      "property1": 0.1,
      "property2": 0.1
    }
  }
]

Full Example

import {
  Hub88ThrillConnect,
  Hub88ConnectArg,
  Connect,
  ConnectEvents
} from 'hub88-thrilltech-connect'

// Authenticate with the casino server -- The above is expected to run on your
// server and payload to be exposed to your casino frontend via API
const url = `${api_url}/operator/generic/agnostic-jackpot/user/authenticate`

const response = await fetch(url, {
  method: 'POST',
  body: JSON.stringify(gamesLauncherURLParams),
  headers: { 'Content-Type': 'application/json' }
})
const responseData: Hub88ConnectArg = await response.json()
return responseData

// On the Casino frontend, the responseData is expected to be available
// We can then create the client like so

// Very important to subscribe to the events; otherwise, the web socket will disconnect after a certain period
const events: ConnectEvents = [
  ConnectEvents.JackpotUpdateEvent,
  ConnectEvents.JackpotWinEvent,
  ConnectEvents.OptInEvent
]

// This ensures events are subscribed to
const settings = { ...responseData, events: events }

// Create client instance
// Client reconnection is handled by the client class
const client: Hub88ThrillConnect = Connect(settings)

// Event event handling
client.on(ConnectEvents.Connected, () => {
  console.log('WS Connected!')
})

client.on(ConnectEvents.Message, (data) => {
  console.log('Message received:', data)
})

client.on(ConnectEvents.JackpotUpdateEvent, (updateEvent) => {
  console.log('Jackpot update event:', updateEvent)
})
client.on(ConnectEvents.JackpotWinEvent, (winEvent) => {
  console.log('Jackpot win event:', winEvent)
})

// Handle one-time events
client.once(ConnectEvents.Disconnected, () => {
  console.log('Disconnected - this handler will only run once')
})

// Unsubscribe from events
const messageHandler = (data) => console.log(data)
client.on(ConnectEvents.Message, messageHandler)
client.off(ConnectEvents.Message, messageHandler) // Remove specific handler
client.off(ConnectEvents.Connected) // Remove all handlers for this event

// Clean up when done or when need to switch the player from demo mode to
// real mode
function cleanup() {
  client.destroy()
}

TypeScript Types

The SDK provides comprehensive TypeScript definitions for all features:

// Core interfaces
interface Hub88ConnectArg {
  sdk_init_token: {
    token: string
    attributes: string // base64 encoded JSON
  }
  events?: ConnectEvents[]
  dev?: {
    log?: boolean
    secure?: boolean
  }
}

// Event data types
interface JackpotUpdateEvent {
  instance_id: string
  tiers: {
    name: string
    value: number
  }[]
}

// Request parameters
interface LeaderboardFilterArgs {
  all_brands?: boolean
  operator_runtime_id?: string
  instance_id?: string
  limit?: number // 1-20, default: 5
}

Troubleshooting

WebSocket Connection Issues

If you're experiencing connection issues:

  1. Verify that the provided token is valid,

  2. Check that the player currency is properly set (cannot be 'XXX'),

  3. Ensure the WebSocket URL is accessible from your environment.

Opt-In Not Working

If player opt-in is failing:

  1. Verify the player is properly authenticated,

  2. Check that the source_id or instance_id is valid,

  3. Ensure the WebSocket connection is established before making opt-in requests.

Error Codes During Authentication

HTTP Code
Message
Potential Cause
Action

400

A parameter <param> is missing or invalid

A required request parameter is missing, empty, or invalid. Check: user, token, country, currency, platform (GPL_DESKTOP/GPL_MOBILE), operator_id (integer), jackpot_uuid.

Verify request payload includes all required fields with valid values.

400

Operator game is disabled

Operator game is disabled in configuration.

Enable the operator game in the system.

400

Agnostic jackpot with uuid <jackpot_uuid> is not allowed for this operator

Jackpot exists but not linked to operator.

Link jackpot to operator.

400

Agnostic jackpot with uuid <jackpot_uuid> is disabled

Jackpot is disabled.

Enable jackpot before requesting.

404

Operator was not found

Operator ID does not exist.

Check operator ID.

404

Operator game was not found

No game linked to operator.

Ensure operator is assigned the game.

404

Contract was not found

Contract ID missing or invalid.

Verify operator–contract mapping.

404

Currency was not found

Currency code not valid in Hub88.

Use valid ISO currency code.

404

Agnostic jackpot with uuid <jackpot_uuid> was not found

Jackpot UUID not recognized.

Confirm jackpot UUID is correct.

404

Country was not found

Country code not valid in Hub88.

Use valid ISO country code.

404

Supplier game was not found

Supplier game record missing.

Ensure supplier game exists and is configured.

500

Game code for agnostic jackpot should exist but is missing

Thrilltech game code could not be retrieved.

Confirm that a valid jackpot game code exists for the request.

500

Game code for agnostic jackpot is not valid

An invalid/unrecognized game code was supplied.

Ensure the game code matches an eligible Thrilltech game.

500

Game should exist but was not found

The requested game does not exist in cache or DB.

Verify game exists and is configured correctly.

500

Contract is improperly configured

Contract linked to operator/supplier is misconfigured.

Review Hub88 back office contract setup.

500

Invalid response from ThrillTech

Thrilltech backend returned invalid/unexpected response.

Retry or contact support if persistent.


Managing ThrillTech Jackpots in Operator Backoffice

Since Thrilltech operates as a Supplier within Hub88, all bets and wins related to Thrilltech Jackpots are logged and visible in the Backoffice. You can view and filter these transactions by following the steps below.

  1. Navigate to Backoffice → Transactions.

  2. Choose one of the following filtering options:

Option 1: Filter by User

  • Select a specific user to see all transactions linked to that player.

  • The Backoffice records both:

    • Supplier requests (bet and win), and

    • Thrilltech Jackpot requests (bet and win).

  • This means you’ll see paired logs for each transaction.

Option 2: Filter by Supplier / Product Code

  • Select Thrilltech as the supplier to view only Thrilltech Jackpot transactions.

  • For each transaction, you’ll see both the bet and win entries related to Thrilltech Jackpots.

Understanding Amount Values

In the Transactions view, the Amount column reflects Thrilltech’s jackpot bet and win logic:

  • Bet transaction → Shows the contribution amount defined during the Opt-In process.

  • Win transaction

    • Shows zero (0) indicating the player did not win the jackpot in this round.

    • Shows jackpot amount if the bet resulted in a win.

Last updated

Was this helpful?