Plugins
The @kalamba/sdk/plugins entry point defines the interface between a wrapper and its plugins. The SDK does not ship plugin implementations — every wrapper application provides its own casino, RGS and telemetry plugins by subclassing these base classes.
import { CasinoPlugin, RgsPlugin, TelemetryPlugin, Tracker } from '@kalamba/sdk/plugins'
Plugins are registered as classes in the KalambaSdkWrapper constructor (see Building a Wrapper); the wrapper instantiates them and injects its config (WrapperConfig), sdkConfig (SdkConfig) and state (WrapperState), which are available as instance fields.
How messages reach plugins
The wrapper forwards a fixed set of messages to each plugin domain by re-posting them as kalamba:wrapper-<domain>:<name> (e.g. kalamba:wrapper-rgs:play). Each base class exposes a protected on(message, listener, options?) that matches both these forwarded messages and the wrapper's own kalamba:wrapper:<name> broadcasts, and returns an unsubscribe function. A protected send(message, payload?) posts a message in the plugin's own domain (kalamba:rgs:*, kalamba:casino:*), which the wrapper then routes onward. See Message Protocol for the full routing tables.
RgsPlugin
Implements the transport to the game server. Constructor: (config: WrapperConfig, sdkConfig: SdkConfig, state: WrapperState).
The base class wires everything in its constructor — it subscribes to openGame, play, freeRounds, getBalance and history and calls the corresponding method. For openGame, play and freeRounds, the resolved value is sent as openGameResponse / playResponse / freeRoundsResponse and a thrown error (of type RgsErrorWithType) as openGameError / playError / freeRoundsError; the last error is kept on this.error. A resolved getBalance is sent as balance and its errors are ignored. showHistory handles the history UI itself and sends nothing.
Override the methods for the requests your RGS supports (defaults throw Not implemented):
async openGame(payload: OpenGameRequest): Promise<OpenGameResponse>
async play(payload: PlayRequestEnhanced): Promise<PlayResponse>
async freeRounds(payload: FreeRoundsRequest): Promise<FreeRoundsResponse>
async getBalance(): Promise<GetBalanceResponse>
async showHistory(): Promise<void>
import { RgsPlugin } from '@kalamba/sdk/plugins'
import type { OpenGameRequest, OpenGameResponse, PlayRequestEnhanced, PlayResponse } from '@kalamba/sdk'
class MyRgsPlugin extends RgsPlugin {
async openGame(payload: OpenGameRequest): Promise<OpenGameResponse> {
return await api.openGame(this.sdkConfig.api, payload)
}
async play(payload: PlayRequestEnhanced): Promise<PlayResponse> {
// payload.payloadToInject contains data merged in by injectPayload
return await api.play(payload)
}
}
CasinoPlugin
Integrates the wrapper with a specific casino/operator platform. Constructor: (config: WrapperConfig, sdkConfig: SdkConfig, state: WrapperState, injectPayload) — injectPayload is the wrapper's payload injection function, letting the plugin add operator data to outgoing play requests.
There are no abstract methods to implement; a casino plugin is driven entirely by subscribing to messages in its own constructor. It also gets an i18n instance for translated operator-facing texts. Typical uses: pushing balance and bet updates from the casino UI (send('balance', ...), send('bet', ...)), toggling help/paytable/settings panels, answering choice prompts, or handling close/cashier navigation.
import { CasinoPlugin } from '@kalamba/sdk/plugins'
class MyCasinoPlugin extends CasinoPlugin {
constructor(...args: ConstructorParameters<typeof CasinoPlugin>) {
super(...args)
this.on('configure', () => {
this.injectPayload('myCasino', { operatorToken: getToken() })
})
this.on('playCycleEnd', () => {
operatorApi.notifyRoundEnd(this.state.lastPlayResponse)
})
operatorApi.onBalanceChange(balance => this.send('balance', { balance }))
}
}
TelemetryPlugin and Tracker
Telemetry is split in two: a TelemetryPlugin subscribes to game events and maps them to analytics events, and one or more Trackers deliver those events to a concrete backend. Registration in the wrapper pairs them: telemetry: [{ plugin: MyTelemetryPlugin, trackers: [MyTracker] }].
TelemetryPluginconstructor:(trackers: Tracker[], config: WrapperConfig, sdkConfig: SdkConfig). Its protectedtrack(event, data)fans the event out to every tracker.Trackerconstructor:(config: WrapperConfig, sdkConfig: SdkConfig). It has one abstract method:track(event: unknown, data: Record<string, unknown>): void.
import { TelemetryPlugin, Tracker } from '@kalamba/sdk/plugins'
class MyTelemetryPlugin extends TelemetryPlugin {
constructor(...args: ConstructorParameters<typeof TelemetryPlugin>) {
super(...args)
this.on('playCycleStart', payload => {
this.track('spin', { bet: payload.bet })
})
}
}
class MyTracker extends Tracker {
track(event: unknown, data: Record<string, unknown>): void {
analytics.send(String(event), { game: this.config.gameName, ...data })
}
}