npm package: @pythiasport/bet-builder-sdk
Description: TypeScript SDK for embedding RMG betbuilder widget
Latest version: 1.2.7

# RMG SDK

A modern, framework-agnostic TypeScript SDK for embedding **RMG widgets** (Betbuilder, Banners, Pre-built Bets) into any
web application.

## Installation

```bash
npm install @pythiasport/bet-builder-sdk
# or
yarn add @pythiasport/bet-builder-sdk
# or
pnpm add @pythiasport/bet-builder-sdk
```

---

## Quick Start (multi-widget)

### 1) Add containers to your HTML

```html

<div id="rmg-banners-widget-container"></div>
<div id="rmg-pre-built-bets-widget-container"></div>
<div id="rmg-widget-container"></div>
```

### 2) Mount widgets and subscribe to events

```ts
import {RmgSdk} from '@pythiasport/bet-builder-sdk';

const sdk = new RmgSdk();

// Creating a Bet Builder widget
const betBuilderContainer = document.getElementById('rmg-widget-container')!;
const betBuilderWidget = sdk.createWidget('betbuilder', betBuilderContainer, {
  tenantId: 'demo',
  style: 'width: 100%; height: 600px; border: none;',
});


// Creating a Pre-built Bets widget
const prebuiltContainer = document.getElementById('rmg-pre-built-bets-widget-container')!;
const prebuiltWidget = sdk.createWidget('prebuiltBets', prebuiltContainer, {
  tenantId: 'demo',
  style: 'width: 100%; height: 400px; border: none;',
});

const bannersContainer = document.getElementById('rmg-banners-widget-container')!;
const bannersWidget = sdk.createWidget('banners', bannersContainer, {
  tenantId: 'demo',
  style: 'width: 100%; height: 200px; border: none;',
});

```

---

## Receiving Data from Widgets

Widgets emit **typed payload events** that your app can consume directly.

### Generic (TypeScript)

| Widget         | Event Name             | Payload Type                  |
|----------------|------------------------|-------------------------------|
| `betbuilder`   | `betbuilder:sentences` | `string[]`                    |
| `betbuilder`   | `betbuilder:shareLink` | `string`                      |
| `prebuiltBets` | `prebuilt:sentences`   | `string[]`                    |
| All Widgets    | `*`                    | `{ type: string; data: any }` |
| All Widgets    | `ready`                | `void`                        |

```ts
// Example: Bet Builder widget

const betBuilderWidget = sdk.createWidget('betbuilder', betBuilderContainer, {
  tenantId: 'demo',
  style: 'width: 100%; height: 600px; border: none;',
});

betBuilderWidget.on('ready', () => {
  console.log('Bet Builder widget is ready');
});

betBuilderWidget.on('betbuilder:sentences', (sentences) => {
  console.log('Received sentences from Bet Builder widget:', sentences);
});

betBuilderWidget.on('betbuilder:shareLink', (shareLink) => {
  console.log('Received share link from Bet Builder widget:', shareLink);
});

betBuilderWidget.on('*', ({type, data}) => {
  console.log(`Received event: ${type} with data:`, data);
});

```

## Framework Integration

### React

```tsx
import React, {useEffect, useRef} from 'react';
import {RmgSdk} from '@pythiasport/bet-builder-sdk';

const sdk = new RmgSdk();

export const RmgWidgets: React.FC = () => {
  const betBuilderRef = useRef<HTMLDivElement>(null);
  const prebuiltRef = useRef<HTMLDivElement>(null);
  const bannersRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!betBuilderRef.current || !prebuiltRef.current || !bannersRef.current) return;

    const betBuilderWidget = sdk.createWidget('betbuilder', betBuilderRef.current, {
      tenantId: 'demo',
      style: 'width: 100%; height: 600px; border: none;',
    });

    const prebuiltWidget = sdk.createWidget('prebuiltBets', prebuiltRef.current, {
      tenantId: 'demo',
      style: 'width: 100%; height: 400px; border: none;',
    });

    const bannersWidget = sdk.createWidget('banners', bannersRef.current, {
      tenantId: 'demo',
      style: 'width: 100%; height: 200px; border: none;',
    });

    // Subscribe to events
    betBuilderWidget.on('ready', () => console.log('Bet Builder ready'));
    betBuilderWidget.on('betbuilder:sentences', (data) => console.log('Betbuilder sentences', data));

    prebuiltWidget.on('ready', () => console.log('Prebuilt Bets ready'));
    bannersWidget.on('ready', () => console.log('Banners ready'));

    // Cleanup on unmount
    return () => {
      betBuilderWidget.destroy();
      prebuiltWidget.destroy();
      bannersWidget.destroy();
    };
  }, []);

  return (
    <div>
      <div ref={betBuilderRef}/>
      <div ref={prebuiltRef}/>
      <div ref={bannersRef}/>
    </div>
  );
};
```

### Vue 3 - Composition API

```vue

<template>
  <div>
    <div ref="betBuilderRef"></div>
    <div ref="prebuiltRef"></div>
    <div ref="bannersRef"></div>
  </div>
</template>

<script setup lang="ts">
  import {onMounted, onBeforeUnmount, ref} from 'vue';
  import {RmgSdk} from '@pythiasport/bet-builder-sdk';

  const sdk = new RmgSdk();

  const betBuilderRef = ref<HTMLDivElement | null>(null);
  const prebuiltRef = ref<HTMLDivElement | null>(null);
  const bannersRef = ref<HTMLDivElement | null>(null);

  let betBuilderWidget: any;
  let prebuiltWidget: any;
  let bannersWidget: any;

  onMounted(() => {
    if (!betBuilderRef.value || !prebuiltRef.value || !bannersRef.value) return;

    betBuilderWidget = sdk.createWidget('betbuilder', betBuilderRef.value, {
      tenantId: 'demo',
      style: 'width: 100%; height: 600px; border: none;',
    });

    prebuiltWidget = sdk.createWidget('prebuiltBets', prebuiltRef.value, {
      tenantId: 'demo',
      style: 'width: 100%; height: 400px; border: none;',
    });

    bannersWidget = sdk.createWidget('banners', bannersRef.value, {
      tenantId: 'demo',
      style: 'width: 100%; height: 200px; border: none;',
    });

    betBuilderWidget.on('ready', () => console.log('Bet Builder ready'));
    prebuiltWidget.on('ready', () => console.log('Prebuilt ready'));
    bannersWidget.on('ready', () => console.log('Banners ready'));
  });

  onBeforeUnmount(() => {
    betBuilderWidget?.destroy();
    prebuiltWidget?.destroy();
    bannersWidget?.destroy();
  });
</script>
```

### Angular

```ts
// app.component.ts
import {Component, ElementRef, OnDestroy, AfterViewInit, ViewChild} from '@angular/core';
import {RmgSdk} from '@pythiasport/bet-builder-sdk';

@Component({
  selector: 'app-root',
  template: `
    <div #rmgWidgetContainer></div>
    <div #rmgBannersWidgetContainer></div>
    <div #rmgPreBuiltBetsWidgetContainer></div>`,
})
})

export class AppComponent implements AfterViewInit, OnDestroy {
  @ViewChild('rmgWidgetContainer', {static: false}) betBuilderRef!: ElementRef<HTMLDivElement>;
  @ViewChild('rmgPreBuiltBetsWidgetContainer', {static: false}) prebuiltRef!: ElementRef<HTMLDivElement>;
  @ViewChild('rmgBannersWidgetContainer', {static: false}) bannersRef!: ElementRef<HTMLDivElement>;

  private sdk = new RmgSdk();
  private widgets: any[] = [];

  ngAfterViewInit(): void {
    const betBuilderWidget = this.sdk.createWidget('betbuilder', this.betBuilderRef.nativeElement, {
      tenantId: 'demo',
      style: 'width: 100%; height: 800px; border: none;',
    });

    const prebuiltWidget = this.sdk.createWidget('prebuiltBets', this.prebuiltRef.nativeElement, {
      tenantId: 'demo',
      style: 'width: 100%; height: 400px; border: none;',
    });

    const bannersWidget = this.sdk.createWidget('banners', this.bannersRef.nativeElement, {
      tenantId: 'demo',
      style: 'width: 100%; height: 200px; border: none;',
    });

    betBuilderWidget.on('ready', () => console.log('Bet Builder ready'));
    prebuiltWidget.on('ready', () => console.log('Prebuilt Bets ready'));
    bannersWidget.on('ready', () => console.log('Banners ready'));

    this.widgets = [betBuilderWidget, prebuiltWidget, bannersWidget];
  }

  ngOnDestroy(): void {
    this.widgets.forEach((w) => w.destroy());
  }
}
```

---

## Logging / Diagnostics

You can provide a **custom logger** to capture SDK diagnostics. Either pass it to the constructor or set it later via
`setLogger(...)`.

### Angular example (set at runtime)

```ts
this.sdk.setLogger({
  info: (m, meta) => console.log('[RMG]', m, meta ?? ''),
  warn: (m, meta) => console.warn('[RMG]', m, meta ?? ''),
  error: (e, meta) => console.error('[RMG]', e, meta ?? ''),
  // debug?: (...) => {} // optional
});
```

### Using the built-in console adapter

```ts
import {createConsoleRmgLogger} from '@pythiasport/bet-builder-sdk/utils';

const sdk = new RmgSdk(createConsoleRmgLogger('RMG'));
```

> The logger interface is flexible (`debug/info/warn/error` are optional).  
> Avoid logging sensitive data in production environments.

---

## IIFE / No Bundler (CDN)

The IIFE build exposes the facade on `window.Pythiasport`.

```html
<!doctype html>
<html>
<head>
  <meta charset="utf-8"/>
  <script src="https://unpkg.com/@pythiasport/bet-builder-sdk@^1/dist/index.global.js"></script>
</head>
<body>
<div id="rmg-banners-widget-container"></div>
<div id="rmg-pre-built-bets-widget-container"></div>
<div id="rmg-widget-container"></div>

<script>
  const {RmgSdk} = window.Pythiasport;
  const sdk = new RmgSdk();

  // Creating a Bet Builder widget
  const betBuilderContainer = document.getElementById('rmg-widget-container');
  const betBuilderWidget = sdk.createWidget('betbuilder', betBuilderContainer, {
    tenantId: 'demo',
    style: 'width: 100%; height: 600px; border: none;',
  });


  // Creating a Pre-built Bets widget
  const prebuiltContainer = document.getElementById('rmg-pre-built-bets-widget-container');
  const prebuiltWidget = sdk.createWidget('prebuiltBets', prebuiltContainer, {
    tenantId: 'demo',
    style: 'width: 100%; height: 400px; border: none;',
  });

  const bannersContainer = document.getElementById('rmg-banners-widget-container');
  const bannersWidget = sdk.createWidget('banners', bannersContainer, {
    tenantId: 'demo',
    style: 'width: 100%; height: 200px; border: none;',
  });
</script>
</body>
</html>
```

## Browser Support

- Chrome (latest), Firefox (latest), Safari (latest), Edge (latest)

---

## License

MIT