Skip to main content

Haste API Integration

Haste API Integration⚒️

Introduction

Want to integrate HLP into your game? Follow these straightforward steps to ensure a seamless integration with our API that gets you (and your users) paid faster.

  • Verify your game is compatible with Haste HLP APIs
  • Register your game through the Haste Developer Portal and generate game access keys.
  • Review the Security standards for Haste and ensure your game follows the authoritative server model described there.
  • Ensure all required functions are implemented. If you'd like to reference our API documentation, you can do that here, but below you'll find a quick list of the API calls required to list your game in Haste Arcade.

Table of Contents

Architecture

Haste Browser Architecture

Server-side Functions

The @hastearcade/server package is the primary entry point to the Haste ecosystem. The SDK is a wrapper for the Haste API and allows developers to HLP enable a game. The Haste ecosystem provides tools to handle most components of HLP; these functions are required to list your game with us, so make sure you have them somewhere in your code.

Machine to Machine Authorization

In order to interact with the Haste API as a developer, you must retrieve a bearer token from the Haste API. The token uses the developer's game client_id and client_secret to retrieve a token for usage on Get Leaderboards, Play, Score.

Start Machine to Machine Authorization

curl --location --request POST 'https://api.hastearcade.com/oauth/writetoken' \
--header 'Content-Type: application/json' \
--data-raw '{
"client_id": "server_client_id_from_developer_portal",
"client_secret": "server_client_secret_from_developer_portal"
}'

# example response
{
"access_token": "JWT",
"token_type": "Bearer",
"expires_in": 1209600,
"developerId": "developer_uuid",
"gameId": "game_uuid", # needed for play and score
"arcadeId": "arcade_uuid" # needed for play and score
}

Integrate Game Client with Game Server

In order to call certain API endpoints such as Play and Score, you will want to validate the JWT provided by the game client to ensure you have the correct playerId. In order to interact with the Haste API as a developer, you will need your write token defined in the previous step and the validated playerId. Please see here for details on sending the player JWT from the game client to the game server. Once you have it you can validate it similar this example:

Validate Player JWT

import jwt, { JwtHeader, JwtPayload, SigningKeyCallback } from "jsonwebtoken";
import { JwksClient, SigningKey } from "jwks-rsa";

export const validateAuthenticationToken = (
playerAuthToken: string,
authUrl: string
): Promise<JwtPayload> => {
const auth0Url = `https://${authUrl}/`;
const jwtClient = new JwksClient({
jwksUri: `https://${authUrl}/.well-known/jwks.json`,
});

const getKey = (header: JwtHeader, callback: SigningKeyCallback) => {
try {
jwtClient.getSigningKey(header.kid, (err: Error, key: SigningKey) => {
if (key) {
const signingKey = key.getPublicKey();
callback(err, signingKey);
} else {
callback(new Error());
}
});
} catch (err) {
callback(err);
}
};

return new Promise<JwtPayload>((resolve, reject) => {
if (playerAuthToken) {
jwt.verify(playerAuthToken, getKey, {}, (err, decoded) => {
if (err)
return reject(
new Error(
`The token does not match the authentication configuration. Validate that you are utilizing the correct auth url for Haste.authenticate()`
)
);
if (
decoded.iss === auth0Url &&
decoded.exp > new Date().getTime() / 1000
) {
return resolve(decoded);
} else {
return reject(
new Error(
"The player access token provided was invalid. Ensure that you are logged in correctly."
)
);
}
});
} else {
reject(
new Error(
"A player token must be provided to the middleware. Verify the token is being supplied and the user is logged in correctly"
)
);
}
});
};

const jwt = await validateAuthenticationToken(playerAccessToken, authUrl);
const playerId = jwt["https://hastearcade.com/playerId"] as string;
console.log(`The playerId is ${playerId}`);

Get Leaderboard for Play Selection

In the Haste Arcade players can choose what level they wish to play at. They can risk small amounts or larger amounts based on their desire to earn. The Haste ecosystem currently has multiple leaderboards that can be played for every game. Each tier requires additional funds to play the game (i.e. paying a penny vs paying a "quarter"). Every game in the arcade must support this concept in game. Thus, most games will display a dropdown UI to allow the player to select what leaderboard they wish to participate in. In order to retrieve the list of leaderboards to show in your dropdown you can use

Get Leaderboards for Play Selection


# the $arcadeId, $gameId, and $bearerToken can be retrieved from /oauth/writetoken response
curl --location --request GET 'https://api.hastearcade.com/arcades/$arcadeId/developergames/$gameId' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $bearerToken' \

# example response
{
id: "Game UUID",
name: "Game Name",
description: "Game Description",
category: "Game Category",
developerInfo: "Game Developer Info",
tagLine: "Game Tagline",
url: "Game Hosted URL",
leaderboards: [
id: "Leaderboard UUID",
name: "Leaderboard Name aka Practice, Macro, High Roller",
cost: 4, # the cost for the player to play at this level
leaders: [ # the current leaders for this specific leaderboard
playerId: "Player UUID",
score: number,
name: "Players display name",
avatar: "Players avatar url"
]
],
playerId: "Game Developer UUID"
}

Submit Play

To play a game in a physical arcade, you have to first insert a quarter. Once a player has selected their Leaderboard, the developer will need to submit a "play" to the Haste API. The following code shows a demonstration of this concept: The general flow of the scoring process should be:

  • The play call comes back with a good response, indicating the player can start the game.
  • The player plays the game.
  • When the game ends, the score function is called.

Submit Play


# the $arcadeId, $gameId, and $bearerToken can be retrieved from /oauth/writetoken response
curl --location --request POST 'https://api.hastearcade.com/arcades/$arcadeId/games/$gameId/play' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $bearerToken' \
--data-raw '{
"playerId": "players UUID from player JWT",
"leaderboardId": "leaderboard UUID from Get Leaderboards"
}'

# example response
{
"id": "play uuid - needed for score",
"createdAt": "2022-01-31T21:34:46.647Z",
"updatedAt": "2022-01-31T21:34:46.647Z",
"deletedAt": null,
"deleted": false,
"playerId": "player uuid",
"gameId": "game uuid",
"gameArcadeId": "arcade uuid",
"developerId": "developer uuid",
"leaderboardId": "leaderboard uuid",
"cost": 2000,
"ilpRegistrationId": "corresponding ilp id",
}

Submit Score

To play a game in a physical arcade, you have to first insert a quarter. The @hastearcade/server SDK requires a similar flow. Once a player has selected their Leaderboard, the developer will need to submit a "play" to the Haste API via the SDK. The following code shows a demonstration of this concept: The general flow of the scoring process should be:

  • The play call comes back with a good response, indicating the player can start the game.
  • The player plays the game.
  • When the game ends, the score function is called.

Submit Score


# the $arcadeId, $gameId, and $bearerToken can be retrieved from /oauth/writetoken response
curl --location --request POST 'https://api.hastearcade.com/arcades/$arcadeId/games/$gameId/score' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $bearerToken' \
--data-raw '{
"playId": "play UUID from call to /play",
"leaderboardId": "leaderboard UUID from Get Leaderboards",
"score": number
}'

# example response
{
"id": "score uuid",
"score": number,
"leaders": [ # the current leaders for this specific leaderboard
playerId: "Player UUID",
score: number,
name: "Players display name",
avatar: "Players avatar url"
]
"isWinner": boolean,
"leaderRank": number
}

These are the only required functions since you're in the QuickStart section. If you want to see more functions from the SDK, skip ahead to the Desired Functions section in the Detailed Instructions.

Client-side Functions

While the primary work of integrating with Haste is performed on the server-side (where all game logic and score state should be maintained), Haste also provides a web-based SDK to assist in the authentication process. In order for a player to play your game, they will need to authenticate with the Haste Arcade.

The web SDK works by utilizing a Single Sign-On (SSO) system with Haste Arcade. The SDK is a wrapper to help facilitate this process.

If you're not using a Single-Page application (SPA), but instead are using a traditional server-side web application, you can look at using our @haste-express library.

Start Login Process

Make a POST request to https://authservice.hastearcade.com/cli. This request body requires a single parameter called description. This value normally contains identifying information about the client system, for example, operating system + device name or your name + device name.

Start Login

curl --location --request POST 'https://authservice.hastearcade.com/cli' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": "client-system-name-or-some-other-identifier"
}'

# example response
{
browserUrl: "url user can use to login",
requestorId "UUID",
cliUrl: "/cli",
token: "JWT"
}

User Login

Parse out the browserURL from the previous call. This will be the actual URL for the game user. The developer will need to make a system call to open a browser with this URL, or the user can be prompted to visit the URL themselves. This will display the login screen.

Open Browser

curl --location --request POST 'https://authservice.hastearcade.com/cli' \
--header 'Content-Type: application/json' \
--data-raw '{
"description": "client-system-name-or-some-other-identifier"
}' | jq -r '.browserUrl' | awk '{print "https://authserver.hastearcade.com"$1}'

# the output can be opened in the default browser to start the user login process

Get Player Token

Asynchronously, the client system will poll GET /cli/{id} to get a JWT access token that will be used in successive calls to the Haste API e.g. /play, /score, /getLeaderboards. The desktop or mobile client should store this access token in a secure location.

The Bearer Token comes from the start of the login POST to /cli and is the token in the response body.

The requestorId comes from the start of the login POST to /cli and is the requestorId in the response body.

Get Player Token

curl --location --request GET 'https://authservice.hastearcade.com/cli/requestorId' \
--header 'Authorization: Bearer <Bearer Token>'
}'

# example response
{
access_token: "JWT",
}

# The access_token should be stored securely on desktop or mobile clients and will need to validated in the game server and used on the game server to submit plays and scores.

Send Player Token to Server

Once you have secured the access_token in your desktop or mobile client, you should send the token to your game server. This will ultimately be up to you to define based on your server architecture. See the server section Integrate Game Client with Game Server for details on how to validate this JWT.

Send Player Token to Server

# this will be a REST call or equivalent to your own API / game server
curl --location --request POST 'https://your.gameserver.com/authorization' \
--header 'Authorization: Bearer <Your Own Bearer Token>'
--data-raw '{
"player_access_token": "JWT from /cli/requestorId"
}'