# DeBets Client App integration

This page explains how to integrate DeBets Client App into a gambling website in order to use Debets as a payment solution. As already explained, for this use case you are also requested to integrate DeBets Seamless Server.

For the other use case of DeBets, which consists in listing and letting users play your games on DeBets website, the integration of DeBets Client App does not apply. You are instead required to integrate your games with DeBets.

DeBets Client App is made of two UI elements that will appear on your website:

  • a CONNECT WALLET button that allows the user to connect his Web3 wallet to your website. Once a wallet is connected the button turns into a wallet widget that displays the address of the connected wallet and the balance of the active deposit, if any. The wallet widget also contains a dropdown that let's the user switch cryptocurrency. Clicking on the wallet address in the widget hides/shows the app.

  • the client app itself: this is a typical mobile potrait app that shows on top of your website. On desktop it appears centered on the screen, while on mobile it takes the full screen. The app can be toggled by the user at any time. Once hidden, it can be shown again by clicking on the wallet widget

In order to demonstrate how DeBets Client App can be integrated into an existing website DeBets has published a Proof-Of-Concept site at the following URL:

https://poc.debets.io

Here below is a screenshot that shows the app running in the POC website. The wallet widget appears on the top-right corner and the Client App is centered on the screen and displays itself over the game list.

When games are played on mobile you may choose not to show the wallet widget and render the games in fullscreen. To show/hide the app when the wallet widget isn't displayed the app provides you with a toggler button that can be positioned over the game on one side of the screen (you can use the setToggler API to control the behvaiour of the toggler button).

game rendered fullscreen on mobile with the toggler button on the right side
game rendered fullscreen on mobile with
the toggler button on the right side

In what follows we will describe in detail the interaction between the app and the website that embeds it. Feel free to visit the POC in order to understand how the app is integrated by looking at the source code.

# Loading the App

To load the app in your website you need to use a <script> tag like the following:

<script src="https://app.debets.io/debets-app.js" id="debets" 
    data-site-name="debets_poc" 
    data-integration-mode="site" 
    data-game-elem-id="gameIFrame"
    data-wallet-elem-id="wallet" 
    data-wallet-elem-style="background :#5e35a3; border: 1px solid #ffb6dc99; color: white"
>
</script>

The value for data-site-name attribute must be set to the username that DeBets as assigned to you. You will receive your username after enrolling, it will be communicated to you in the dedicated Signal group that DeBets will create.

What follows is the complete list of attributes that can be specified in the <script> tag and their meaning:

attribute name required description
data-site-name username that uniquely identifies the gaming operator and its website in DeBets
data-integration-mode the value must be set to "site"
data-wallet-elem-id the ID of the DOM element that the app will use to render its wallet widget. The element must exist in the DOM and should be positioned in the top-right corner of the website
data-game-elem-id the ID of the DOM element that the website uses as a container for the games that are launched. When provided the app uses it to positoin its toggle button on mobile.
If omitted you can control how the app toggle button is shown by using the setToggler API
data-wallet-elem-style the CSS used to style the wallet widget
data-hide-blockchain when set to "false" it prevents the wallet widget from showing the blockchain logo next to currency logo

# App initialization

Once loaded the app initializes itself.
During the initialization the app first connects via WebSockets to DeBets Server and then it tries to automatically re-connect the user wallet in case a wallet was previously connected.
At the end of the initialization the app dispatches an event called DeBets.onInitialized on the current window object, from this point the app instance is installed in the window.$DeBets.
As for all other events dispatched by the app that will be described later, DeBets.onInitialized has a context which can be taken from the detail property of the disaptched event:


window.addEventListener('DeBets.onInitialized', e => {
    console.log(`DeBets Client App loaded: ${window.$DeBets}`);
    console.log(`Event context: ${JSON.stringify(e.detail)}`);
});

The context of DeBets.onInitialized is an object that contains information about the gaming accounts that are available to play the games, the underyling currencies and blockchains:

Example context of DeBets.onInitialized

{
    "connectingWalletAddress": "0x4838B106FCe9647Bdf1E7877BF73cE8B0BAD5f97",
    "accounts": [
        {
            "currency": "mBNB",
            "chainId": 97,
            "externalId": "20000002",
            "accountId": 19,
            "publicKey": "0xF8902FbEa6bD76C10a35A56F8d2562a5D2058a4a",
            "balance": {
                "valInCurrency": 15750.45,
                "valInUSD": 8701.65
            },
            "playerDeposits": [
                {
                    "id": "0xd2733b1384b16a917b3fdfeb81de0ec550ca3829781035b2d68dd9026bbabf32",
                    "balance": {
                        "valInUSD": 4,
                        "valInCurrency": 7.19
                    }
                }
            ],
            "playerBalance": {
                "valInUSD": 17,
                "valInCurrency": 27
            }
        },
        {
            "currency": "mETH",
            "chainId": 1,
            "externalId": "20000003",
            "accountId": 21,
            "publicKey": "0x2C1A8C8D32c394Bb097bd51a4aa0150EFf97A1Ad",
            "balance": {
                "valInCurrency": 5020.25,
                "valInUSD": 12173.12
            },
            "playerDeposits": [
                {
                    "id": "0xd2733b1384b16a917b3fdfeb81de0ec550ca3829781035b2d68dd9026bbabf32",
                    "balance": {
                        "valInUSD": 4,
                        "valInCurrency": 7.19
                    }
                }
            ],
            "playerBalance": {
                "valInUSD": 17,
                "valInCurrency": 27
            }
        },
        {
            "currency": "USDT",
            "chainId": 97,
            "externalId": "20000001",
            "accountId": 20,
            "publicKey": "0x3F9baA44a3c7EED1546B8eed5457939636e0a661",
            "balance": {
                "valInCurrency": 8750.00,
                "valInUSD": 8750.00
            },
            "playerDeposits": [
                {
                    "id": "0xd2733b1384b16a917b3fdfeb81de0ec550ca3829781035b2d68dd9026bbabf32",
                    "balance": {
                        "valInUSD": 4,
                        "valInCurrency": 7.19
                    }
                }
            ],
            "playerBalance": {
                "valInUSD": 17,
                "valInCurrency": 27
            }
        },
        {
            "currency": "USDT",
            "chainId": 1,
            "externalId": "20000004",
            "accountId": 22,
            "publicKey": "0x356B4147d898C9ec32B7c03532b34E1710497a89",            
            "balance": {
                "valInCurrency": 4170.10,
                "valInUSD": 4170.10
            },
            "playerDeposits": [
                {
                    "id": "0xd2733b1384b16a917b3fdfeb81de0ec550ca3829781035b2d68dd9026bbabf32",
                    "balance": {
                        "valInUSD": 4,
                        "valInCurrency": 7.19
                    }
                }
            ],
            "playerBalance": {
                "valInUSD": 17,
                "valInCurrency": 27
            }
        }			
    ],
    "chains": [
        {
            "chainId": 97,
            "logo": "https://d3tukt58upyaos.cloudfront.net/blockchains/97/2.svg",
            "name": "BSC",
            "httpPublicUrl": "https://data-seed-prebsc-1-s1.binance.org:8545/",
            "contractAddress": "0xcDA81681CAC43958ab3d1C485FE6B7908ebb163F",
            "coins": [{
                "coin": "USDT",
                "createdAt": 1716799599,
                    "config": {
                        "decimals": 18,
                        "contractAddr": "0x7ef95a0FEE0Dd31b22626fA2e10Ee6A223F8a684"
                    }
                },
                {
                    "coin": "BNB",
                    "createdAt": 1716799701,
                    "config": {
                        "decimals": 18
                    }
            }]
        },
        {
            "chainId": 1,
            "logo": "https://d3tukt58upyaos.cloudfront.net/blockchains/97/2.svg",
            "name": "Ethereum",
            "httpPublicUrl": "https://ethereum-sepolia-rpc.publicnode.com",
            "contractAddress": "0xDC219271d5090b1cD591C1B89B0bf995D78f6113",
            "coins": [{
                "coin": "ETH",
                "config": {
                    "decimals": 18
                },
                "createdAt": 1727039995
                },
                {
                    "coin": "USDT",
                    "config": {
                        "decimals": 6,
                        "contractAddr": "0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0"
                    },
                    "createdAt": 1727040047
            }]
        }			
    ],
    "currencies": [
        {
            "currency": "mBNB",
            "coin": "BNB",
            "logo": "https://d3tukt58upyaos.cloudfront.net/currencies/mBNB/1.svg",
            "exRate": 0.58732,
            "factor": 0.001,
            "fractionDigits": 2
        },
        {
            "currency": "mETH",
            "coin": "ETH",
            "logo": "https://d3tukt58upyaos.cloudfront.net/currencies/mETH/1.svg",
            "exRate": 2.58617,
            "factor": 0.001,
            "fractionDigits": 2
        },
        {
            "currency": "USDT",
            "coin": "USDT",
            "logo": "https://d3tukt58upyaos.cloudfront.net/currencies/USDT/1.svg",
            "exRate": 1.00018,
            "factor": 1,
            "fractionDigits": 2
        }
    ]
}

The accounts in the context of DeBets.onInitialized contain important information such as the balance in the user wallet in playerBalance, the balance of the gaming account in the Smart Contract in balance and the list of active deposits of the user in playerDeposits. This latter information is not always available in the list of accounts returned by DeBets.onInitialized but it is guaranteed to be available in the account list from DeBets.onReady event (see below).

When the app is loaded for the first time, or when no previously connected wallet is found (or when the app fails to re-connect a wallet) at the end of the initialization the app will stay hidden and it will display the CONNECT WALLET button, waiting for the user to connect his wallet. In this case the app isn't ready and it is waiting for the user to connect his wallet.

# App ready

As soon as the user wallet is successfully connected the app looks for an existing deposit that belongs to the address of the connected wallet. If an active deposit is found the app selects the gaming account that corresponds to it and then it displays the balance of the deposit and the underlying currency in the wallet widget.
If no active deposit is found then the app selects the first gaming account and displays a zero balance in the wallet widget.

After selecting a gaming account and showing the user balance the app becomes ready and it dispatches an event called DeBets.onReady

The context of DeBets.onReady is an object that represents the status of the Client App, it contains the following information:

  • activeDepositId: ID of the active deposit (null when no deposit is active)
  • gameId: ID of the currently runnig game (null if no game is open)
  • selectedAccountId: ID of the currently selected gaming account
  • sessionId: ID of the WebSocket connection to DeBets Server
  • walletAddress: address of the wallet that the user has connected

In addition to the above properties the context object also contains a property called accounts that contains the list of gaming accounts with updated balance and deposit information.

The following example prints the number of available player deposits, the balance in the player wallet and the account balance for each gaming account:


window.addEventListener('DeBets.onReady', e => {
    e.detail.accounts.map(a => {
        console.log(`Account ${a.accountId}/${a.currency}`);
        console.log(`\tplayer deposits: ${a.playerDeposits.length}`);
        console.log(`\tplayer wallet balance: ${a.playerBalance.valInUSD.toFixed(2)}$`);
        console.log(`\taccount balance: ${a.balance.valInUSD.toFixed(2)}$`);
    })
});

# App events

Besides DeBets.onLoadingComplete and DeBets.onReady thete are other events dispatched by the app that you may want to listen. The following table lists all the available events:

event context dispatched when
DeBets.onInitialized {accounts, chains, currencies} the app has completed its initialization
DeBets.onReady {accounts, selectedAccountId, walletAddress, activeDepositId, gameId, sessionId} the player has connected a wallet and the app has activated a deposit if any available deposit is found
DeBets.onAccountChanged {selectedAccountId, walletAddress, activeDepositId, gameId, sessionId} the user has selected a different account from the cryptocurrency dropdown in the wallet widget
DeBets.onWalletAddressChanged {selectedAccountId, walletAddress, activeDepositId, gameId, sessionId} anytime an account in the user's wallet is connected to the app
DeBets.onDepositActivated {selectedAccountId, walletAddress, activeDepositId, gameId, sessionId} anytime a deposit is activated in the app
DeBets.onAccountBalanceUpdate {accounts} anytime the balance of an account in the Smart Contract chanages
DeBets.onWalletBalanceUpdate {accounts} anytime the player balance for the token in one of the accounts changes
DeBets.onDepositBalanceUpdate {accounts, depositId, balance, type} anytime the balance of the active deposit changes as a result of:
  • bet or win taking place in the game
  • free credits being awarded to the user
  • additional funds added to the current deposit
Type is one of "WIN", "BET", "ADD_FUNDS"
DeBets.onDepositCreated {accounts, depositId, depositAmount} anytime a new deposit is created
DeBets.onDepositClosed {accounts, depositId} anytime one of the two parties has requested to close the deposit

The context of the event is the value of the detail property in the dispatched event. As an example the following code prints the address of the connected user wallet:


window.addEventListener('DeBets.onWalletAddressChanged', e => {
    console.log(`Account connected in user's wallet: ${e.detail.walletAddress}`);
});

# Launching games

The way games are launched is totally under your control.
You know what is the gaming account active in the app by listening to the events dispatched by it (the cryptocurrency and blockchain that correspond to the active gaming acccount are also shown to the user in the wallet widget) and you get the list of available gaming accounts from the DeBets.onReady event.

For launching games there are two possible flows:

  • you launch the game using the counterpart of the active gaming account in your gaming platform. This means that when the user launches the game he will be playing it under the cryptocurrency and blockchain of the active gaming account in the app.

  • you display a dialog where the user can choose on which cryptocurrency and blockchain to play the game. The list of available options corresponds to the gaming accounts from the DeBets.onReady event. Once the user has made a selection in the dialog you must notify the app of the newly selected account and then launch the game with the currency that corresponds to the selected gaming account in your gaming platform.

For the app to hook into the newly launched game you have to call the notifyGameSessionReady API, passing it two parameters: sessionId and gameId. Where sessionId is the session token that correponds to the newly created session to play the game in your gaming platform and gameId is the ID of the game. You should call notifyGameSessionReady right after having obtained the new session ID to open the game, before launching it.

window.$DeBets.notifyGameSessionReady(sessionId, gameId);

 It is crucial that you call notifyGameSessionReady every time a game is launched. Failing to do so will prevent the app from hooking into the game and the user will not be able to play.

# Enabling Provably Fair

To enable Provably Fair on the game that is being launched add a third parameter when calling notifyGameSessionReady which must be an object with the provablyFair property set to true:

window.$DeBets.notifyGameSessionReady(sessionId, gameId, {provablyFair: true});

# Switching account

If you are using a dialog to let the player choose on which cryptocurrency and blockchain to play when he launches a game then in the call to notifyGameSessionReady you need to add a third parameter which is an object with the accountId property set to the ID of the gaming account that corresponds to the cryptocurrency and blockchain that he has selected.

window.$DeBets.notifyGameSessionReady(sessionId, gameId, {accountId: 2});

# List of available API

Besides notifyGameSessionReady the app provides other API that you may want to use. Here is the complete list:

API name arguments description
getConfig returns the current config object (see App initialization)
getState returns the current state object (see App ready)
setExitGameButtonClickCallback callback function sets a callback that is invoked by the app when the user clicks on the exit button in the app
openWalletConnectionModal calling this to shows an alert in the middle that asks the user to connect his wallet.
You can use this if the user tries to launch a game before you have received the DeBets.onReady event
setToggler options let's you control the position and appearance of the app toggler
show accountId shows the app. If an accountId is provided then the app switches to that accountId and then shows itself
hide hides the app
changeWalletElemStyle options let's you control the style of the wallet widget

The options argument of the setToggler API must be an object that can contain the following attributes:

  • visible: boolean used to show/hide the toggler
  • position: specifies the position of the toggler with respect to data-game-elem-id (if provided in the <script> tag when embedding the app) or containerElem (if given). Must be one of "tl", "lt", "tr", "rt", "bl", "lb", "br", "rb". For instance "tl" positions the toggler on the left-top corner
  • offset: on object that specifies the x and y offsets with respect to the position. The x and y can be expressed either in pixels or as a percentage of containerElem size
  • containerElem: when provided the toggler position is relative to this DOM element ID or DOM element object
  • attachToElem: allows you to provide the ID of a DOM element or a DOM element object in order to render the toggler inside it (must be used alternatively to position and containerElem)
Example setToggler call

window.$DeBets.setToggler({
    visibility: true,
    position: 'rt',
    offset: {
        y: '50%',
        x: '-5px'
    },
    containerElem: 'myGameIframe'
});

The options argument of the changeWalletElemStyle API must contain valid style properties.

Consider the following example:

Example changeWalletElemStyle call

window.$DeBets.changeWalletElemStyle({
    background :"#5e35a3",
    border: "1px solid #ffb6dc99",
    color: "white",
    fontSize :"13px",
    fontWeight: "400px"    
});

It will result in a wallet widget looking like this: