Getting Started

Core Classes

Arbiter has 3 core classes that you will interact with as you develop your game. This 2-minute overview of the classes will help you understand what code you’ll need to write!

User

# Example User
'user': {
    'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f',
    'token': '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb',
    'claim_account_url': 'https://www.arbiter.me/api/v1/user/40628a4750f74b7a9e1827812e7af815/f80819ef573f699c2723b0c15f1c24bf704ae8a5ef5363083434831bed36c518',
    'is_verified': false,
    'username': 'anonymous'
}

Your users' devices interact directly with our server. The first time a player’s device connects with Arbiter, we create an anonymous User and return a unique ID for that user. This ID is what you will use to make requests on that user’s behalf in the future from your server. By default, all users are playing anonymously. At any point, they can create login credentials for their account to log back in with those credentials using our Login API.

Wallet

# Example Wallet
'wallet': {
    'deposit_address': '1JbbREwe8Vb9DAVzB2zWtNYvKDYLyjyV3C',
    'balance': '50',
    'pending_balance': '623'
}

Each Arbiter User is given an Arbiter Wallet. This request will occur directly between your players' device and the Arbiter server. The user can then deposit to this wallet using a Credit Card, PayPal, or with Bitcoin. At any point, a user can make a withdrawal from their Arbiter Wallet back to any Debit Card, PayPal account, or Bitcoin address.

Tournament

# Example Tournament
'tournament': {
    'id': '7b62cac5dd164104955468ff80ee6d26'
    'buy_in': '100',
    'balance': '100',
    'users': [{'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None}],
}

Tournaments are the core class handling all the betting interactions between your players. Your server will create a new Tournament for each betting interaction between the players in your game. Once a Tournament has been created, your users will be able to buy in to the Tournament. After your users have finished battling it out in your game, your server will report who won. Arbiter will then charge a transacaction fee (some for us, and some for you) and then release the remaining funds in the Tournament to the winning user’s Arbiter Wallet.

No backend required

Arbiter is flexible enough to work with multiple patterns

RESTful

The Arbiter API follows RESTful patterns, returns consistent JSON structures in every response, and relies on built-in HTTP features. As long as you are familiar with the standard HTTP features, the API should behave straight forward.

HTTP Status Codes

Our API uses HTTP status codes to help you track down an issue if the API is not working as you would expect.

Code Type Description
200 OK The requested action was successful.
400 Bad Request A required parameter was missing or invalid.
401 Unauthorized Missing or invalid access token in your Authorization Header.
404 Not Found Incorrect url or ID in a url.
500 Server Error Something went wrong on our end. We get notified every single time you see this and are looking into what caused the problem.

Response Objects

# Example response from https://www.arbiter.me/api/v1/wallet/
{
    'success': true,
    'wallet': {
        'deposit_address': '1Mdx1V81LJeyZk6yBizRny6KXxyMTXHGpw',
        'balance': '0'
    }
}

All APIs return json with the following keys:

Field Type Description
success Boolean Whether or not the requested action was performed.
OBJECT_NAME dictionary A dictionary containing the relavant object being queried or edited. This key will be the name of object type (ie: user, wallet, tournament, etc).
errors array An array of errors (if any errors occurred).

Before digging into the details below, spend 2 minutes reading the Core Classes section. It will get you familiar with the core classes you will be interacting with.

Authentication

# Example request with Authorization Header
import requests

USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'
GAME_API_KEY = 'd6416b1e9be84c53b07524e37f94499d'
headers = {
    'Authorization': 'Token '+USER_TOKEN+'::'+GAME_API_KEY
}
r = requests.post('https://www.arbiter.me/api/v1/user/details', headers=headers)

Authentication with Arbiter is two fold. Both your server and your users need the ability to make authenticated requests to Arbiter. To do so, all requests include both a game API key and a user token.

Game API Key

When you create a game using the Game Configuration Form, an API key is generated for that game. This key is required for all requests to identify which game the requests are for.

Developer Access Token

For request made between your server and Arbiter, your developer access token is required to authorize your access to the API. Your developer access token is available in your Account Settings.

User Access Token

The user token is used the same as your Developer Access Token except to authenticate your users' requests between their devices and the Arbiter server. User tokens are returned in the User Initialize and User Details responses. Once a user has been queried, save their token in their client for future requests.

Once you have all your keys and tokens and are ready to make a request, you’ll combine them into a single field in the Authorization Header of your requests.

headers = {
    'Authorization': 'Token <ACCESS_TOKEN>::<GAME_API_KEY>'
}

The format of the header is ‘Token ACCESS_TOKEN::GAME_API_KEY’. Depending on whether your server is making the request or if the request is coming from a user’s client, the ACCESS_TOKEN should be either your Developer Access Token or the USER ACCESS TOKEN.

Configure Your Game

Create an Arbiter developer account to configure your game and save your API Key.

Configuring your game In your dashboard, click the ‘Register new game’ button in the games tab.

Game Configuration Form

Field Description
name A label for your game.
rake amount The percentage of each player payout you want to charge. Valid range is 0 through 99. payout = balance - your rake % - Arbiter fee (5%).
matchmaking Will this game use Arbiter’s Matchmaking service to find similar skilled challengers when a user requests a match?

Once you have saved the configuration form, an API key will be generated for your game. Store this on your server for making authenticated calls. See Authentication for more on how to make authenticated requests.

User API

Initialize

import requests

r = requests.get('https://www.arbiter.me/api/v1/user/initialize')

r.json()
{
    'success': true,
    'user': {
        'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f',
        'token': '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb',
        'claim_account_url': 'https://www.arbiter.me/api/v1/user/40628a4750f74b7a9e1827812e7af815/f80819ef573f699c2723b0c15f1c24bf704ae8a5ef5363083434831bed36c518',
        'is_verified': false,
        'username': 'anonymous'
    }
}

The initialize call should be made at the beginning of every user’s session in your game. Arbiter creates an anonymous session for the user. The session is managed through the token returned in the first response.

Future requests made for this user require the token in the request headers. Store the user.id and user.token in your database or locally on the device for future requests.

Request URL

GET https://www.arbiter.me/api/v1/user/initialize

Returned User Object

Field Type Description
id string Unique Arbiter ID for this user. Save this in your DB for requests involving this users
token string Authentication token for this user. Save this in your DB and keep it private. This will be included in request headers in future requests to authenticate a request made on behalf of this user.
is_verified boolean Whether or not this user has agreed to Arbiter’s Terms of Service.
username string Display name of this user. If they have not created an account using the claim_url, this will be anonymous
claim_account_url string A unique URL for this user to claim their Arbiter Account. Once they have claimed their account, they can login to their Player Dashboard. They can also use their account credentials to login to an Arbiter enabled game and have access to their existing wallet created in a previous session.

Agree to Terms of Service

import requests

# id and token returned from the /user/initialize call
user_id = 'd8b50f95c8a24f24a7c64c9d3d5dde5f'
user_token = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# Game API Key from your developer dashboard
api_key = 'd6416b1e9be84c53b07524e37f94499d'

url = 'https://www.arbiter.me/api/v1/user/' + user_id + '/verify'
headers = {
    'Authorization': 'Token ' + user_token + '::' + api_key
}
r = requests.post(url)

r.json()
{
    success: True
}

Before a user can participate in a wager, we need to confirm that the user is over 18, their local jurisdiction allows skill based betting online, and they need to agree to the Arbiter Terms of Service. Display the exact text below with a confirmation button that posts to the the confirmation API.

Request URL

POST https://www.arbiter.me/api/v1/user/<USER ID>/verify

Returns

Field Type Description
success boolean Whether or not the user’s account was successfully verified

Details

import requests

# id and token returned from the user/initialize or user/login call
# IMPORTANT: Keep your users' tokens private
user_id = 'd8b50f95c8a24f24a7c64c9d3d5dde5f'
user_token = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
api_key = 'd6416b1e9be84c53b07524e37f94499d'

headers = {
    'Authorization': 'Token ' + user_token + '::' + api_key
}
url = 'https://www.arbiter.me/api/v1/user/' + user_id

r = requests.get(url, headers=headers)

r.json()
{
    'success': true,
    'user': {
        'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f',
        'is_verified': true,
        'username': 'anonymous',
        'token': '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'
    },
    'wallet': {
        'deposit_address': '1JbbREwe8Vb9DAVzB2zWtNYvKDYLyjyV3C',
        'deposit_address_qr_code': 'https://chart.googleapis.com/chart?cht=qr&chl=bitcoin%3A1JbbREwe8Vb9DAVzB2zWtNYvKDYLyjyV3C&choe=UTF-8&chs=300x300',
        'withdraw_address': null,
        'balance': '50',
        'pending_balance': '623'
    }
}

Returns details for a user.

Request URL

GET https://www.arbiter.me/api/v1/user/<USER ID>

Returns a User’s details

Field Type Description
id string Unique ID for this user. Save this ID with the user in your database.
token string Access token used for authentication. Store this in your database with the user and keep it secret.
is_verified boolean Whether or not the user has agreed to Arbiter’s Terms of Service
username string If the user has set their username. Defaults to anonymous

Wallet API

Details

import requests

# id and token returned from the user/initialize or user/login call
# IMPORTANT: Keep your users' tokens private
user_id = 'd8b50f95c8a24f24a7c64c9d3d5dde5f'
user_token = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
api_key = 'd6416b1e9be84c53b07524e37f94499d'

headers = {
    'Authorization': 'Token ' + user_token + '::' + api_key
}
url = 'https://www.arbiter.me/api/v1/wallet/' + user_id

r = requests.get(url, headers=headers)

r.json()
{
    'success': true,
    'wallet': {
        'deposit_address': '1JbbREwe8Vb9DAVzB2zWtNYvKDYLyjyV3C',
        'deposit_address_qr_code': 'https://chart.googleapis.com/chart?cht=qr&chl=bitcoin%3A1JbbREwe8Vb9DAVzB2zWtNYvKDYLyjyV3C&choe=UTF-8&chs=300x300',
        'withdraw_address': null,
        'balance': '50',
        'pending_balance': '623'
    }
}

Request URL

GET https://www.arbiter.me/api/v1/wallet/<USER ID>

Returns a user’s Wallet details

Field Type Description
balance integer The amount of Arbiter credits this user has available to bet with.
pending_balance integer The amount of Arbiter credits that are currently pending confirmation.
deposit_address string Bitcoin deposit address for the user to deposit bitcoin in exchance for Arbiter credits.
deposit_address_qr_code url Image URL to a QR code for depositing Bitcoin.
withdraw_address string If the user has cashed out to a Bitcoin address in the past, we include this value to autopopulate their cash out form

Deposit

You have a few options to choose from for how you want to let your users deposit funds into their wallets. Once you have decided how you want your players to deposit funds, we have 3 different payment options to choose from

In game using Bitcoin

Once you have queried a user’s wallet, display the wallet.deposit_address or the wallet.deposit_address_qr_code to the user. Then the user can use any Bitcoin wallet app to deposit Bitcoin to their address. We suggest either polling or including a refresh button for the user to trigger wallet queries after placing a deposit.

In game using Credit Card

Documentation coming soon…

In game using PayPal

Documentation coming soon…

If you don’t want to deal with implementing the Deposit API, you can link the user to their Web Dashboard. However, they will need to create account credentials using the [Claim Account API] in order to login in to their web dashboard.

Cash Out

Docuementation coming soon…

Tournament API

Tournaments are the core class handling all the betting interactions between your players. All of your tournaments will follow this flow:

  1. Your server requests a new Tournament using the Create API.
  2. Users buy into the Tournament using the Add User API.
  3. Your players play your game.
  4. Your server reports the winner of the game to the Report Score API.
  5. Arbiter will calculate the transactions fees and release the winnings.

Create

import requests

# Token is returned from the user/initialize or user/login call
# IMPORTANT: Keep your users' tokens private. Treat these like passwords.
USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
API_KEY = 'd6416b1e9be84c53b07524e37f94499d'

# Include the user_token requesting the tournament
headers = {
    'Authorization': 'Token ' + USER_TOKEN + '::' + API_KEY
}
url = 'https://www.arbiter.me/api/v1/tournament/create'
payload = {
    'buy_in': 100  # Bet size in Arbiter Credits
}
r = requests.post(url, data=payload, headers=headers)

r.json()
{
    'success': True
    'tournament': {
        'id': '7b62cac5dd164104955468ff80ee6d26'
        'buy_in': '100',
        'balance': '100',
        'users': [{'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None}],
    }
}

Request URL

POST https://www.arbiter.me/api/v1/tournament/create

Request Parameters

Field Type Description
buy_in integer The buy in (aka bet size or entry fee) in Arbiter credits for this tournament.

Returns the tournament’s state

Field Type Description
id string Unique identifier for this tournament.
buy_in string The buy in (aka bet size) in Arbiter credits for this tournament.
balance string The current balance of this tournament.
users array Array of dictionaries of each user that has successfully bought in to this tournament. Each dictionary has the user’s ID and the score reported by your server for each user in this tournament.

Create with Matchmaking Enabled

# Example success response from Create when matchmaking is enabled
import requests
headers = {...}
payload = {...}
r = requests.post('https://www.arbiter.me/api/v1/tournament/create', data=payload, headers=headers)

print r.status_code
# 200

r.json()
{
    'success': True
}

Matchmaking keeps the really good users from ruining new users' first game experiences. When matchmaking is enabled for your game, the Tournament Create API may take a couple seconds to find an accurate match. Because of this delay, we return a success response for the request immediately then create the tournament in the background.

After a client successfully requested a new tournament, the client should pull the Tournament List API until a new tournament is returned.

# Example list response when pulling
import requests
headers = {...}
r = requests.get('https://www.arbiter.me/api/v1/tournament', headers=headers)

r.json()
{
    'success': True,
    'tournaments': [
        {
            'id': '7b62cac5dd164104955468ff80ee6d26'
            'buy_in': '100',
            'balance': '100',
            'users': [{'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None}],
            'matched_users': ['d8b50f95c8a24f24a7c64c9d3d5dde5f', 'efc4654a2b9844589a8d77d09628afbf']
        }
    ]
}

Fields on Tournament with Matchmaking Enabled

Field Type Description
matched_users array User IDs of recently active users of similar skills.

Use the IDs in matched_users to notify the corresponding user that they have been matched. In the notification, that user should have a Buy-in to Tournament prompt that triggers the Add User API for that user.

Details

import requests

# Token is returned from the user/initialize or user/login call
USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
API_KEY = 'd6416b1e9be84c53b07524e37f94499d'

# Include the token of the User requesting the tournament
headers = {
    'Authorization': 'Token ' + USER_TOKEN + '::' + API_KEY
}
url = 'https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>'
r = requests.get(url, headers=headers)

r.json()
{
    'success': True
    'tournament': {
        'id': '7b62cac5dd164104955468ff80ee6d26'
        'buy_in': '100',
        'balance': '100',
        'users': [{'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None}]
    }
}

Request URL

GET https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>

Returns the tournaments’s state

Field Type Description
id string Unique identifier for this tournament.
buy_in string The buy in (aka bet size) in Arbiter credits for this tournament.
balance string The current balance of this tournament.
users array Array of dictionaries of each user that has successfully bought in to this tournament. Each dictionary has the user’s ID and the score reported by your server for each user in this tournament.

List

import requests

# Token is returned from the user/initialize or user/login call
USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
API_KEY = 'd6416b1e9be84c53b07524e37f94499d'

# Include the token of the User requesting the tournament
headers = {
    'Authorization': 'Token ' + USER_TOKEN + '::' + API_KEY
}

url = 'https://www.arbiter.me/api/v1/tournament'
r = requests.get(url, headers=headers)

r.json()
{
    'success': True
    'tournaments': [
        {
            'id': '7b62cac5dd164104955468ff80ee6d26'
            'buy_in': '100',
            'balance': '100',
            'users': [{'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None}]
        }
    ]
}

Request URL

GET https://www.arbiter.me/api/v1/tournament

Optional URL Params

Param Default Description
page 1 Depth of paginated results

Returns paginated list

TODO: Replace these with the fields to returned in paginated serializer

Field Type Description
id string Unique identifier for this tournament.
buy_in string The buy in (aka bet size) in Arbiter credits for this tournament.
balance string The current balance of this tournament.
users array Array of dictionaries of each user that has successfully bought in to this tournament. Each dictionary has the user’s ID and the score reported by your server for each user in this tournament.

Add User

Before adding a user, create a tournament using the Tournament Create API and save the tournament’s ID

import requests

# The user's token is returned from the user/initialize or user/login call
USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
API_KEY = 'd6416b1e9be84c53b07524e37f94499d'

# Include the user_token requesting the tournament
headers = {
    'Authorization': 'Token ' + USER_TOKEN + '::' + API_KEY
}
url = 'https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>/add-user/<USER_ID>'
r = requests.post(url, headers=headers)

r.json()
{
    'success': True
    'tournament': {
        'id': '7b62cac5dd164104955468ff80ee6d26'
        'buy_in': '100',
        'balance': '200',
        'users': [
            {'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None},
            {'id': 'efc4654a2b9844589a8d77d09628afbf', 'score': None}
        ]
    }
}

Transfers the tournament’s buy_in amount from the specified user’s wallet to the specified tournament. If no errors occur, then the user will be added to the users array and the tournament.balance will be updated.

Request URL

POST https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>/add-user/<USER_ID>

Returns the Jackpot State

Field Type Description
id string Unique identifier for this tournament.
buy_in string The buy in (aka bet size) in Arbiter credits for this tournament.
balance string The current balance of this tournament.
users array Array of dictionaries of each user that has successfully bought in to this tournament. Each dictionary has the user’s ID and the score reported by your server for each user in this tournament.

Report Score

Before reporting a score, create a tournament using the Tournament Create API add users to the tournament using the Add User API

import requests

# User tokens are returned in the user/initialize or user/login call
# IMPORTANT: Keep your users' tokens private
USER_TOKEN = '3d2fcd21dcd22ae1d64b799c486a959aeee42fbb'

# game API Key from your developer dashboard
API_KEY = 'd6416b1e9be84c53b07524e37f94499d'

# Include the user_token requesting the tournament
headers = {
    'Authorization': 'Token ' + USER_TOKEN + '::' + API_KEY
}
url = 'https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>/report-score/<USER_ID>'
payload={
    'score': '101'
}
r = requests.post(url, data=payload, headers=headers)

# If all users have reported a score, the tournament will automatically payout
r.json()
{
    'success': True
    'tournament': {
        'id': '7b62cac5dd164104955468ff80ee6d26'
        'buy_in': '100',
        'balance': '0',
        'users': [
            {'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': '101'},
            {'id': 'efc4654a2b9844589a8d77d09628afbf', 'score': None}
        ]
    }
}

Once a user has finished playing your game, report their score to Arbiter. Once all the users have reported their scores, Arbiter will compare the scores and set the winner to the user with the highest score. Once a winner has been set, Arbiter will automatically calculate the transaction fees and transfer the remainder of the tournament balance to the winning user’s Arbiter wallet.

Request URL

POST https://www.arbiter.me/api/v1/tournament/<TOURNAMENT_ID>/report-score/<USER_ID>

Request Parameters

Field Type Description
score integer The score of the user for this tournament.

Returns the tournament’s State

Field Type Description
id string Unique identifier for this tournament.
buy_in string The buy in (aka bet size) in Arbiter credits for this tournament.
balance string The current balance of this tournament. If all users have reported their score, this will be 0.
users array Array of dictionaries of each user that has successfully bought in to this tournament. Each dictionary has the user’s ID and the score reported by your server for each user in this tournament.

Matchmaking

The Arbiter matchmaking service keeps the good players from ruining new players experiences. When you turn on matchmaking for your game, Arbiter will automatically find an accurate match for a user whenever they request a new Tournament.

Enable Matchmaking

This is the easiest way to enable matchmaking in your game.

  1. Go to games tab in your Developer Dashboard
  2. Click edit for the game you want to enable matchmaking on.
  3. Check the Enable Matchmaking box in the configuration form.
  4. Click save.

Then whenever you make a call to the Tournement Create API, a new matched_users field will be included in the Tournament object from the Tournament Details API.

Field Type Description
matched_users array An array of user.id’s that have been matched based on the users' skill.

Override in API

import requests

headers = {...}
payload = {
    'users': [
        {'id': 'd8b50f95c8a24f24a7c64c9d3d5dde5f', 'score': None},
        {'id': 'efc4654a2b9844589a8d77d09628afbf', 'score': None}
    ],
    'buy_in': 100
}
url = 'https://www.arbiter.me/api/v1/tournament/create'
r = requests.post(url, data=payload, headers=headers)

r.json()
{
    'success': True
    'tournament': {
        'id': '7b62cac5dd164104955468ff80ee6d26'
        'buy_in': '100',
        'balance': '0',
        'users': [],
        'matched_users': ['d8b50f95c8a24f24a7c64c9d3d5dde5f', 'efc4654a2b9844589a8d77d09628afbf'],
    }
}

There may be edge case scenarios where you do not want to use matchmaking for all tournaments in your game. For example, challenging a friend through Facebook. Even if matchmaking is enabled for a game, including a users array in the Tournament Create API will disable matchmaking. The tournament will be created with the matched users equal to users and return a new tournament back in the response.

Unity iOS SDK

We have a Unity SDK for speeding up the integration when building a game in Unity for iOS. This package wraps all the API interaction into a single Arbiter class.

SDK Flow Overview

Below is an outline of the typical flow a user should be taken through when playing an Arbiter enabled game followed by detailed descriptions and code examples of each step. Don’t hesitate to message us if you have any questions or issues. support@arbiter.me

Implementation Prerequisites

Complete these steps before writing any code.

  1. Configure your game in your developer dashboard.
  2. Download the Unity Package.
  3. Import the package into your Unity game.
  4. Add the Arbiter Prefab located in /Assets/Plugins/Arbiter to your loading scene.
  5. Set your game’s API key and your developer access token in the Arbiter Game Object’s inspector.

Standard flow for your users

Each step below is done with a call to the Arbiter SDK.

  1. Authenticate a user session.
  2. Verify the user’s age and location (if this is a new session).
  3. Display the user’s wallet details.
  4. Prompt the user to deposit Arbiter credits.
  5. Have the user join a tournament.
  6. Report the user’s score for that tournament.
  7. View previous tournament results.
  8. Let the user withdraw their credits when they are done.
  9. Logout

Quick and Easy Implementation

The SDK includes iOS UIAlertViews for all the Arbiter UI elements (wallet dashboard screen, previous tournaments, deposits / withdraws, etc). This is the quickest way to integrate Arbiter into your game. Once you have added the Arbiter Game Object to your game, you can start making calls to the SDK and iOS UIAlertViews will automatically be displayed to the user with all the available user inputs in the UIAlertView.

Customized UI Implementation

The alternative implementation is for you to create your own custom UI elements that matches your game’s look and feel. As you build out your UI elements, you can bind your buttons directly to the Arbiter SDK methods instead of relying on the pre-built UIAlertView inputs.

The Arbiter Game Object

Once the Arbiter Game Object has been added to your loading scene, you will have access to the Arbiter Class. This class contains all the properties and methods that you will interact with throughout the implementation.

Properties

Name Type Description
IsAuthenticated bool Whether or not there is a currently authenticated session between the device and the Arbiter server.
Verified bool Will return true only if the user has agreed to the Terms and Conditions AND their location has been approved for you game.
LocationApproved bool Whether or not the user’s location has been approved for betting in your game.
AgreedToTerms bool Whether or not the user has agreed to the Terms and Conditions
UserId string The user’s unique identifier on Arbiter.
Username string The username or email associated with the current Arbiter account.
AccessToken string The access token for this user to make authenticated requests to the Arbiter server.
Balance string The currently available Arbiter credits for this user to bet with.
PendingBalance string Any pending Arbiter credits in the user’s wallet.
DepositAddress string Bitcoin address for purchasing Arbiter credits with Bitcoin
DepositQrCode string URL to a QR code for purchasing Arbiter credits with Bitcoin
WithdrawAddress string If the user has withdrawn Arbiter credits to a Bitcoin address, this field have their most recently used withdraw address.

Methods

Name Description
LoginAsAnonymous This will create an anonymous session for the user. The session will persist until they either reset their saved data or user the Logout call.
LoginWithGameCenter If the user has already logged into your game using Apple’s Game Center, this will link the Game Center user with an Arbiter account.
LoginWithAccessToken Coming soon Establishes a new session for an existing user based on an access token.
Login Displays a native UIAlertView for a user to login to an existing Arbiter account.
Logout Destroys the current Arbiter session.
VerifyUser Prompts the user to agree to the Terms and Conditions and verifies that your game is legal to bet on in their local jurisdiction.
GetWallet Updates Arbiter.Balance and Arbiter.PendingBalance.
DisplayWalletDashboard Updates Arbiter.Wallet then displays the wallet details in a native UIAlertView along with user inputs such as Deposit and Withdraw.
DisplayDepositFlow Displays native UIAlertViews that take the user through the checkout process for puchasing Arbiter credits.
DisplayWithdrawFlow Displays native UIAlertViews that take the user through the checkout process for redeeming Arbiter credits.
JoinTournament Enters the user in a new tournament.
ReportScore Reports the outcome of a tournament for the current user.
GetTournaments Returns a paginated list of a user’s previous tournaments.
DisplayPreviousTournaments Displays the the paginated list of previous tournaments in a native UIAlertView.

Login As Anonymous

public class LoginButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        Arbiter.LoginAsAnonymous(  Callback );
    }

    void Callback() {
        // Will print "Hello, anonymous!"
        Debug.Log( "Hello, " + Arbiter.Username + "!" );
    }
}

This will create an anonymous session for the user. The session will persist until they either reset their saved data or user the Logout call.

This will give a user most of the functionality as LoginWithGameCenter and Login, except when they want to Withdraw. Due to money laundering regulations, we cannot permit withdrawing until we gather some extra info from the user. When an anonymous user attempts to make a withdraw, they will be prompted to create a full account. After doing so, they will then be able to log back into that account using the Login method.

Login with Game Center

public class AnyScriptPriorToBetting : MonoBehaviour {

    void Start () {
#if UNITY_IOS
        Action<bool> processAuth = ( success ) => {
            if( success ) {
                Arbiter.LoginWithGameCenter( Callback );
            } else {
                Debug.LogError( "Could not authenticate to Game Center!" );
            }
        };
        Social.localUser.Authenticate( processAuth );
#endif
    }

    void Callback() {
        Debug.Log( "Hello, " + Arbiter.Username + "!" );
    }
}

If your game is setup to integrate with Game Center, a user can connect their Arbiter account with a Game Center account.

Once their Arbiter account has been connected to a Game Center account, they can use their Game Center credentials to establish a new session with their existing Arbiter Wallet in other Arbiter enabled games as well as on other devices.

To connect with a Game Center account, use Unity’s Social API to get a Game Center LocalUser. Once a LocalUser has been created, call Arbiter.LoginWithGameCenter() to connect their Game Center account with Arbiter.

Login with Username / Password

public class LoginButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        Arbiter.Login(  Callback );
    }

    void Callback() {
        Debug.Log( "Hello, " + Arbiter.Username + "!" );
    }
}

If a user has already created an account through the Web Registration or through the claim_account_url, they can re-establish an existing session using the Arbiter.Login(). This call will display a UIAlertView with an email and password field. Upon successful login, all the Arbiter properties will get set with the correct values.

Login With Access Token

public class Entrypoint : MonoBehaviour {

    private static string accessToken = TOKEN_FROM_YOUR_DATABASE_SAVED_FROM_PREVIOUS_SESSION;

    void Start () {
        Arbiter.LoginWithAccessToken( accessToken );
    }

    void Callback() {
        Debug.Log( "Hello, " + Arbiter.Username + "!" );
    }
}

Coming Soon...

If your game already has user authentication on your server, your users do not have to create new Arbiter account credentials.

The first time a user loads your game, call Arbiter.Initialize() to create a new session on Arbiter. This will set Arbiter.AccessToken to a string that can be used for authenticated requests for this user. Save that token with the user in your database. Then, whenever one of your users re-loads your game, call Arbiter.LoginWithAccessToken( accessToken ) to re-establish a session with the correct Arbiter account for that user.

Verify The User

public class AnyScriptPriorToBetting : MonoBehaviour {

    void VerificationStep() {
        Arbiter.VerifyUser(  Callback );
    }

    void Callback() {
        Debug.Log( Arbiter.Username + " is now verified: " + Arbiter.Verified );
    }
}

Whenever a new user is created, in addition to having the user agree to the standard terms and conditions, we need to make sure there are no local regulations restricting them from being able to bet in your game.

This method will:

  1. Prompt the user to enable location services (if not already enabled).
  2. Prompt the user to agree to the Terms and Conditions.
  3. Send the user’s postal code to the Arbiter server to check the legality of online betting in their location.

Get Wallet

// Setup wallet listeners
public class SetupWalletHandlerScript : MonoBehaviour {
    void Start() {
        Arbiter.AddWalletListener(  UpdateWalletUIElements );
    }

    void UpdateWalletUIElements() {
        Debug.Log( "Balance: " + Arbiter.Balance );
        Debug.Log( "Pending Balance: " + Arbiter.PendingBalance );
    }

    void ExampleOfRemovingWalletListener() {
        Arbiter.RemoveWalletListener( UpdateWalletUIElements );
    }
}

// Bind to a refresh button in your game
public class RefreshWalletButton : MonoBehaviour {
    void OnMouseUpAsButton() {
        Arbiter.GetWallet();
    }
}

In addition to updating Arbiter.Balance, you can also setup wallet listeners. This way, whenever the wallet is updated, you can bind your own handlers for updating you UI elements and such.

Calling Arbiter.GetWallet() will request the latest wallet detials from the server and then setup automatic polling at incrementing intervals. Anytime you call Arbiter.GetWallet() the polling intervals will reset the inrements.

Save time and use our Wallet Dashboard

// Bind to a 'Show Wallet' button in your UI
public class DisplayWalletButton : MonoBehaviour {
    void OnMouseUpAsButton() {
        Arbiter.DisplayWalletDashboard();
    }
}

To save on implementation time, you can use Arbiter.DisplayWalletDashboard() to give your users access to their wallets. This will display all their wallet info in a native UIAlertView with inputs for depositing and withdrawing.

Deposit Credits

// Bind to a 'Deposit Credits' button in your UI
public class DepositCreditsButton : MonoBehaviour {
    void OnMouseUpAsButton() {
        Arbiter.DisplayDepositFlow();
    }
}

Before a user can start betting, they will need Arbiter credits. Arbiter credits are the betting currency that users will use to bet in your game. Feel free to call them credits, cents, gold, gems, or whatever makes sense for your game.

1 Arbiter credit = $0.01 USD

Use Arbiter.DisplayDepositFlow() to display a native UIAlertView for purchasing Arbiter credits. If you are using Arbiter.DisplayWalletDashboard(), there is a Deposit button in the wallet dashboard for users to purchase Arbiter credits.

Join a Tournament

// Bind to a 'Join Tournament' button in your UI
public class JoinTournamentButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        string betSize = "100";
        Dictionary<string,string> filters = new Dictionary<string,string>();
        filters.Add( "arbitrary_key", "the_value" );
        Arbiter.JoinTournament( betSize, filters, Callback);
    }

    void Callback( Arbiter.Tournament tournament ) {
        // Have the user actually play your game and user Arbiter.ReportScore() to report the outcome.
        Debug.Log( "Joined tournament: " + tournament.Id );
    }
}

Now that the user has credits to bet with, they can request to join tournaments. If there are no current tournaments for the user to join, a new tournament will get created. Once the new tournament has been created on the server and is available on the device, load the actually game play scene for the user.

The Tournament Object

Property Type Description
Id string Unique identifier for a tournament
Status string Initializing The tournament has been created, but is still waiting for all the users to join.
Inprogress All the users have joined, but not all users have reported their scores.
Complete All users have reported their scores and the tournament has a winner.
Users List<Arbiter.TournamentUser> A List of Arbiter users that have joined this tournament. Each user includes the user’s UserId and a Score for this tournament (if they have reported a score yet).
Winner Arbiter.TournamentUser The winner of this tournament.

Using Tournament Filters

string betSize = "100";
Dictionary<string,string> filters = new Dictionary<string,string>();
filters.Add( "arbitrary_key", "the_value" );
Arbiter.JoinTournament( betSize, filters, Callback );

You can pass in a filters dictionary to sort tournaments into different groups. For example, if you want to create a tournament where the users are competing on level 2 of your game, you can set the filters to {"level": "2"}. This will make sure that when a user playing level 2 requests a tournament, they will only get matched with other users requesting a tournament for level 2 (rather than level 1 or 3). level is just an arbitrary example, this can be set to any string.

Report Score

// Put add these functions on any script that runs at the end of a user playing your game
public class EndOfGameScript : MonoBehaviour {

    // Save the tournament during the JoinTournament callback
    Arbiter.Tournament currentTournament = tournament;

    // Get the players score after playing your game
    int score = 101;

    // Called at the end of a user playing your game
    void HandleUserFinishingGame() {
        Arbiter.ReportScore( currentTournament.Id, score, Callback );
    }

    void Callback( Arbiter.Tournament tournament ) {
        if ( tournament.Status == "Complete" ) {
            if ( tournament.Winner.Id == Arbiter.UserId ) {
                Debug.Log( "You won!" );
            } else {
                Debug.Log( "User " tournament.Winner.Id + " won with a score of " + tournament.Winner.Score );
            }
        } else {
            Debug.Log( "Waiting for the other users to finish playing." );
        }
    }
}

After the user has successfully played the game and has generated a numeric score, send the score to the Arbiter server. Once all users in this tournament have reported their scores to the Arbiter server, we will determine the winner based on which user reported the highest score and distribute the credits to the winner’s wallet.

Display Previous Tournaments

public class ViewPreviousTournamentsButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        Arbiter.DisplayPreviousTournaments();
    }
}

This displays a paginated list of tournaments this user has joined in a native UIAlertView.

Withdraw Credits

public class WithdrawCreditsButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        Arbiter.DisplayWithdrawFlow();
    }
}

Once the user is ready convert their Arbiter credits back to USD, call this method to display the withdraw checkout flow. The flow is presented in a native UIAlertView and prompts the user to enter their Debit Card info for the card they want to redeem to.

If you are using Arbiter.DisplayWalletDashboard(), then the withdraw flow is already accesible through the native UIAlertView that is displayed from the DisplayWalletDashboard() call.

Logout

public class LogoutButton : MonoBehaviour {

    void OnMouseUpAsButton() {
        Arbiter.Logout( Callback );
    }

    void Callback() {
        // Update your UI to display the Login / Initialize flow
    }

}

This call will reset all the properties on the Arbiter class and end the current session.