DOCUMENTS

Documents of the BORA project.

Game Example: Pacman

Game sample is consist of Angular and Node.js servers. To understand previously presented sample games, you need to have prior and related knowledge of Javascript and Typescript. Even though you are not professional developer of Javascript, you will be able to understand previously integrated programs with minimal experience in programming since description is provided along with them.

Goal

Membership authorization

By integrating BORA membership information into regular web based open source games, user can experience same process of sign up and log on to access the service.

Transfering Bora Shell on real time basis.

Every earning or winning point is equivalent to in unit of BORA Shell during the game play and corresponding amount will be paid out on a real time basis.

Check BORA Shell transaction information in the BORA chain

Check the transaction history of the BORA Shell stored in the BORA chain in real time.

Screen Layout

Game area

Areas where you can play the game

BORA Chain information area

Area where you can check the information recorded in the BORA chain which is interconnected with the game
  • My BORA Shell : The wallet addresses and number of tokens in the user account
  • BORA Tower Blocks SCORE : Rank information based on highest game score
  • BORA Explorer Recent Blocks : Real-time block information in the BORA Chain
  • BORA Explorer Recent Transactions : Latest Transaction list

Explore example source code

First, please check the source code in git. Logic of the game is not explained, however integrating process with BORA platform is described at the bottom.If you want to run Game Server and Game Front directly, you can check the detailed intallation guide in github described below.

Game Server and Game Front

The open source game https://github.com/masonicGIT/pacman is uploaded on the Node.js server. With the exception of the settings for uploading to the Node.js server, only minimal modifications were made to record the acquired score in the blockchain. Only the saveScore function is added to the part of pacman.js which increases score.
  • app.js : Node.js Part for running the Node.js server
  • main.js : Define functions for communication between game and game server
  • chainApi.js : Call Chain API provided by the BORA platform
  • pacman.js : Please see the section on calling the saveScore function when acquiring the score among the sources in the game.
Game Server: https://github.com/boraecosystem/game-pacman Game Front: https://github.com/boraecosystem/game-front

Operation scenario

In order to achieve the goal mentioned above and pay BORA Shell in real time, the address information of the user to be paid and the authorization information of the content provider who provides BORA Shell are required.

Get user's address information

The purpose of receiving authentication from the user in this game is to obtain the address information of the user. A user refers to an end-user who uses the game.
  • Authorized by the user through OAuth 2.0 Authorization Code Grant based membership authorization page
  • Next, obtain an Access Token from the acquired code
  • Get address information for service by calling address verification API using Access Token

User's membership authorization

If the Access Token does not exist or expires, call the authorization page provided by BORA, and the following process is performed by BORA's authorization server.
  • User login via ID/PW input page
  • APP Authorization Check: If there is no authorization, query privilege escalation and approve.
  • Issue code for issuing Access Token
// https://github.com/boraecosystem/game-front/blob/master/src/app/components/main/main.component.ts#L48

if (this.accessToken === undefined || !this.accessToken) {
// redirect to auth//
window.location.href = environment.api + 'member/oauth/authorize' + '?response_type=code&state=xyz&client_id=' + this.clientId + '&redirect_uri=' + this.redirectUri;
return false;
}

Request an Access token

// https://github.com/boraecosystem/game-pacman/blob/master/app.js#L118

const httpOAuth = require('http');
const data = `grant_type=authorization_code&code=${code}&redirect_uri=${redirectUri}`;
function getUserToken(data, cb) {
const req = httpOAuth.request({
protocol: 'http:',
host: api_uri,
port: 443,
method: 'POST',
path: '/member/oauth/token',
auth: `${clientId}:${clientSecret}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}, res => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => cb(JSON.parse(body)));
}
);
req.on('error', e => console.error(`problem with request: ${e.message}`));
req.write(data);
req.end();
}

Get user's address

Call API which verifies the user's address by using the issued Access Token.
// https://github.com/boraecosystem/game-front/blob/master/src/app/components/auth/auth.component.ts#L40

this.api.getMembers(accessToken).subscribe(
resMember => {
bpAddress = resMember.token_addr;
if (bpAddress === undefined || !bpAddress) {
console.log('Returned bpAddress Invalid:', resMember);
window.location.href = environment.portal;
return false;
}
...
);

// https://github.com/boraecosystem/game-front/blob/master/src/app/api.service.ts#L48

public getMembers(userAccessToken: string): Observable {
const headers = new HttpHeaders({
'Authorization': 'Bearer ' + userAccessToken,
});
return this.http.get(environment.api + 'chain/v1/services/members', { headers: headers })
.map(res => res);
}
In this section, we have explained the steps to verify the user's address before paying them with BORA Shell.This example code is implemented for authorization each time to obtain an address. However, you may want to consider using this process while signing up for the content provider's service or at an appropriate level of interconnection with the BORA platform, and storing it in a database.Next, we will try paying the user BORA Shell whenever they get a score.

Pay BORA Shell to user

In this game, each time a user acquires a score, it delivers the BORA Shell owned by the content provider to the user, and delivers the points to the user through the API call using the content provider's Access Token.
  • Obtain content providers' Access Token using OAuth 2.0 Client Credential Grant method
  • Call BORA Shell Chain API using Access Token to send BORA Shell to user

Access Token issued by content provider

Issue an Access Token using the client id and client secret which have been issued to the content provider in advance. The function to pre-issue client ids and client secrets will be available in the future. Here, we use the client id and client secret which we have previously issued for testing purposes.
// clientId: X0yT6nI69Q, clientSecret: yM5pnll9GwdMjkapd7MWX0
// https://github.com/boraecosystem/game-pacman/blob/master/app.js#L141

const httpOAuth = require('http');
function getClientToken(cb) {
const data = 'grant_type=client_credentials';
const req = httpOAuth.request({
protocol: 'https:',
host: chain_api_uri,
port: 443,
method: 'post',
path: '/member/oauth/token',
auth: `${clientId}:${clientSecret}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}, res => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => cb(JSON.parse(body)));
}
);
req.on('error', e => console.error(`problem with request: ${e.message}`));
req.write(data);
req.end();
}

Pay BORA Shell to user

Call the Chain API and pay the BORA Shell to the user who earned the score.
// https://github.com/boraecosystem/game-pacman/blob/master/app.js#L69

// In Game Server

const chainApi = require('./module/chainApi')('dev');
app.get("/saveScore", function (req, res) {
var amount = req.query.amount;
const toAddr = req.cookies.bpAddress;
const apiuri = chain_api_uri;
chainApi.saveScore(apiuri, clientAccessToken, toAddr, amount, function (error, data) {
if (!error) {
res.send(data);
} else {
res.send(data);
}
});
});
// Request Chain-API
// https://github.com/boraecosystem/game-pacman/blob/master/module/chainApi.js#L12

saveScore: function (host, clientAccessToken, toAddr, amount, callback) {
OPTIONS.url = 'https://' + host + '/chain/v1/services/deposit/' + toAddr + '/' + amount;
OPTIONS.body = '';
OPTIONS.headers = { Authorization: 'Bearer ' + clientAccessToken };
request.get(OPTIONS, function (err, res, result) {
statusCodeErrorHandler(res.statusCode, callback, result);
});
So far, we have explained how to use the authorization and Cahin APIs. The following is a way to check the history of BORA Shell transaction. Here, we have explained how to use the BORA Explore APIs, but we will provide Chain APIs for checking the history in the future.

Check BORA Shell transaction history

This section is not essential part of the game configuration but intended to show the process of recording transactions on the blockchain. Used API is the one that provided by the BORA Explorer.
// https://github.com/boraecosystem/game-front/blob/master/src/app/api.service.ts#L13

import { HttpClient, HttpHeaders } from '@angular/common/http';
const http: HttpClient;

public bp_tx_list_by_addr(appId: number, address: string, page: number = 1, page_size: number = 1): Observable {
return this.http.get(environment.bpapi + 'points/' + appId + '/addresses/' + address + '/txs?page=' + page + '&pageSize=' + page_size)
.map(res => res);
}
public bp_block_list(appId: number, page: number = 1, page_size: number = 10): Observable {
return this.http.get(environment.bpapi + 'points/' + appId + '/blocks?page=' + page + '&pageSize=' + page_size)
.map(res => res);
}
public bp_info_addr(appId: number, address: string): Observable {
return this.http.get(environment.bpapi + 'points/' + appId + '/addresses/' + address)
.map(res => res);
}

Reference API documentation

Please see the following API documents for detailed usage of each API.Authorization APIsChain APIsBORA Explorer APIs