# ThrillTech Jackpots SDK

{% hint style="info" %}
To **access this SDK**, please **contact** your **Account Manager** or **Technical Operations Specialist** for configuration.
{% endhint %}

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.&#x20;

{% hint style="success" %}
For front-end UI ThrillTech provides a separate driver including **wheel spin and jackpot celebration animations.** This can be embedded in your Jackpot widget to improve player engagement during wins.

Access it through the CDN, available at <https://cdn.hub88.io/thrilltech-sdk/thrilltech-driver-v1.0.1.js> .
{% endhint %}

#### Communication Flow&#x20;

<div data-with-frame="true"><figure><img src="/files/S2XIV2WFJQSw90H6fRem" alt=""><figcaption><p>SDK key communication flow</p></figcaption></figure></div>

***

## Integration Steps

**Prerequisites**

* Node.js (v14 or later is recommended)
* npm or yarn&#x20;

{% hint style="info" %}
To **access this SDK**, please contact your **Account Manager** or **Technical Operations Specialist** for preliminary setup configuration.
{% endhint %}

{% hint style="info" %}
**Access the SDK library from:**\
[**https://cdn.hub88.io/thrilltech-sdk/hub88thrillconnect-0.0.10.js**](https://cdn.hub88.io/thrilltech-sdk/hub88thrillconnect-0.0.10.js)
{% endhint %}

#### 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:**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

**Sample Request:**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

**Sample Response:**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

Return this response securely to the frontend.

### Step 2: Initialise SDK Client

#### Client Initialisation

{% code overflow="wrap" lineNumbers="true" %}

```typescript
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)

```

{% endcode %}

#### 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               |

{% hint style="success" %}
After the client is initialised, opt-in, leaderboard, and other API calls become available.
{% endhint %}

### Step 3: Opt-in / Opt-out

{% code overflow="wrap" lineNumbers="true" %}

```typescript
// 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()
```

{% endcode %}

**Signature**

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

**Sample response**

{% code overflow="wrap" lineNumbers="true" %}

```json
{
  "status": "success"
}
```

{% endcode %}

### Step 4: Leaderboard and Jackpot Queries

{% code overflow="wrap" lineNumbers="true" %}

```typescript
// 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" }) 

```

{% endcode %}

**Signature**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

**Sample Leaderboard Response**

{% code overflow="wrap" lineNumbers="true" %}

```json
[
  {
    "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"
  }
]
```

{% endcode %}

***

### Step 5: Fetch Jackpot Metadata

#### **Get Source for Current Brand**

```typescript
client.request().getSources()
```

**Signature**

```typescript
getSources()
```

**Sample Response**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

#### **Get Currencies**

```typescript
client.request().getCurrencies()
```

**Signature**

```typescript
client.request().getCurrencies()
```

**Sample Response**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

#### **Get Jackpot for Default Source (Specific Player)**

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

**Signature**

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

**Sample Response**

{% code overflow="wrap" lineNumbers="true" %}

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

{% endcode %}

***

### Full Example

{% code overflow="wrap" lineNumbers="true" expandable="true" %}

```typescript
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()
}
```

{% endcode %}

***

## TypeScript Types

The SDK provides comprehensive TypeScript definitions for all features:

{% code overflow="wrap" lineNumbers="true" %}

```typescript
// 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
}
```

{% endcode %}

***

## Community Payouts (Batch Transactions)

ThrillTech Jackpots include **community payout** events, enabling distributions where a single triggering bet results in jackpot credits being awarded to many eligible players at once (for example, a Mega Pot win shared across opted-in users on a brand).&#x20;

To execute these efficiently and reliably, Hub88 integrates with the **ThrillTech batch transaction API** and orchestrates the resulting credits to operator wallets on ThrillTech's behalf.

{% hint style="info" %}
Operators do **not** need to implement a custom endpoint for community payouts. Payouts arrive on your existing **Wallet API** as standard `win` transactions, **distinguished by** the **metadata** fields described below.
{% endhint %}

#### How it works?

1. ThrillTech determines the list of winners for a community payout event and submits the batch to Hub88.
2. Hub88 splits the batch into individual transactions and delivers each one to the relevant operator using the standard Wallet API contract — the same endpoint already used for regular supplier wins.
3. Each transaction includes a `meta` block flagging it as a community payout and providing the context needed to reconcile it with the jackpot round and the bet that triggered it.
4. Hub88 handles retries, idempotency, and failure recovery internally, so the operator only needs to acknowledge the transaction the same way it acknowledges any other win.

#### Identifying a community payout

A community payout transaction is identified by `meta.is_community_payout = true`. Operators that wish to apply custom handling — separate ledger tagging, player notifications, accounting categorisation — can branch on this flag inside their wallet implementation.

{% hint style="warning" %}
**Do not validate the session for community payout transactions.** \
Community payouts are distributed by ThrillTech in batch — they are not tied to an active player session at the time of delivery. Applying standard session validation to these transactions will cause them to be rejected. Use `meta.is_community_payout = true` to identify these transactions and bypass session validation accordingly.
{% endhint %}

The `meta` block accompanying each community payout transaction has the following structure:

```json
{
  "meta": {
    "is_community_payout": true,
    "batch_transaction_id": "b8f4a5e2-9c3d-4f1a-8e7b-2a1c5d9f3e8b",
    "source_id": "thrilltech_jackpot_main",
    "source_variant": "Mega",
    "jackpot_amount": 50000,
    "reference_bet": {
      "round_id": "25008fed-6c46-4e97-92d4-22588b608bb8",
      "reference_bet_uuid": "00d95fda12b15989889f219475f8bfc3"
    }
  }
}
```

| Field                  | Description                                                                                                                                                                                         |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `is_community_payout`  | Always `true` for community payout transactions. Use this as the primary flag to identify the transaction type on your side.                                                                        |
| `batch_transaction_id` | Unique identifier of the parent batch. All individual transactions belonging to the same community payout share this id and can be grouped on the operator side for reconciliation and reporting.   |
| `source_id`            | Identifier of the jackpot source that produced the payout.                                                                                                                                          |
| `source_variant`       | Optional qualifier for the source. For jackpot transactions this carries the **Win Pot ID** (e.g. `Minor`, `Major`, `Mega`).                                                                        |
| `jackpot_amount`       | The amount awarded to this specific player as part of the community distribution.                                                                                                                   |
| `reference_bet`        | Metadata of the bet that triggered the community payout. This is the most important field for traceability — it links the payout back to the player and round whose bet caused the jackpot to fire. |

***

## 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**](/operator-backoffice/operator-backoffice-overview.md). You can view and filter these transactions by following the steps below.

1. Navigate to **Backoffice →** [**Transactions**](/operator-backoffice/transactions-management.md#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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hub88.io/developer-docs/operator-sdks/thrilltech-jackpots-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
