BBN Client Integration - BETR · 2020-01-19 · BETR Android app, BETR progressive web ... with a...
Transcript of BBN Client Integration - BETR · 2020-01-19 · BETR Android app, BETR progressive web ... with a...
1
BBN Client Integration
5th November 2018
Table of Contents Overview ............................................................................................................................................................ 2
Interaction .......................................................................................................................................................... 3
First Paragraph: JSON interaction with Wallet Server ......................................................................................... 4
Ethereum Interaction ................................................................................................................................... 4
Wallet Server Authentication ...................................................................................................................... 4
Authentication Methods .............................................................................................................................. 5
<iframe> Method for Javascript .................................................................................................................. 5
<iframe> Method for Javascript – Safari browser ........................................................................................ 7
Direct Call .................................................................................................................................................. 8
JSON-RPC Relay and Signing .................................................................................................................... 8
Second Paragraph: JSON interaction with BBN Server ..................................................................................... 11
1. events .................................................................................................................................................. 12
Events - parameters ................................................................................................................................... 13
Events - statuses........................................................................................................................................ 14
2. eventMarkets ....................................................................................................................................... 15
Lays .......................................................................................................................................................... 17
Templates ................................................................................................................................................. 18
Status Codes ............................................................................................................................................. 20
3. Leagues ............................................................................................................................................... 22
4. createPlaceBet ..................................................................................................................................... 23
5. createConfirmBet ................................................................................................................................. 24
6. getPendingBets .................................................................................................................................... 24
7. getPendingResults................................................................................................................................ 24
8. createResultBet .................................................................................................................................... 24
9. getBetHistory....................................................................................................................................... 25
10. addLayMarket ................................................................................................................................. 25
2
Overview
The initial launch of the BetterBetting application architecture will provide:
• Better Betting Node (BBN) service together with Layer UI (https://betrodds.io/) what offers
the layer functionality. User Interface is built by BetterBetting Foundation.
• BBN Client (Bettor UI) what offers the bettor functionality - there will be multiple interfaces:
BETR Android app, BETR progressive web app and Telegram betting bot built by
BetterBetting Foundation and many other user interfaces built by other developers.
• BETR Wallet service. It is envisaged that number of different BETR wallets can be used.
BetterBetting Foundation will build one of the wallets - https://betrwallet.com.
This document describes the JSON interfaces of the BBN service and BETR Wallet service which are used by the Bettor UI and Layer UI.
Bettor UI supports the following functionality:
● login to Wallet service (Bettor UI users will have an account on a wallet server which will
hold the user’s public and private keys)
● displaying sport event markets, selections and lays setup by different layers and prices/odds
● placing bets
● viewing users bet history
It is envisaged that many types of BBN Client will be developed. These will use different technologies with varying capabilities. The initial official release will be a BBN Client based on Xamarin and will work on Android mobile phones (BETR Android app). Thereafter, an official web app https://bet.betrodds.io will be released. BBN Client apps from other developers will also be created and deployed.
Useful links:
• Better Betting Node service and Layer UI: https://betrodds.io/
• Bettor web app: https://bet.betrodds.io
• Bettor Android native app: https://play.google.com/store/apps/details?id=com.betterbetting.BETR2018&hl=en_GB
• Bettor Telegram betting bot: http://t.me/TheBETRBot
3
Interaction
The following diagram outlines the interactions between the BetterBetting system components:
For displaying bet offers the BBN Client will request the events, odds and risks data from BBN Service
using the “events” (https://betrodds.io/ux/events) and “eventMarkets”
(https://betrodds.io/ux/eventMarkets/eventID) API-s.
For user authentication the BBN Client will submit the request to BETR Wallet service by calling the
<iframe> with a query string which is the JSON-RPC call URI Encoded.
For placing bets the BBN Client will generate transactions that are to be executed on the Ethereum
blockchain network by using standard JSON-RPC calls via BETR Wallet and JSON-RPC Relay service.
The JSON-RPC calls are sent by HTTP requests which are using a standard format and methods as
defined here https://github.com/ethereum/wiki/wiki/JSON-RPC.
This document consists of two main paragraphs:
1) First Paragraph: JSON interaction with Wallet Server - describes the interactions between
betting/laying user interface and BETR Wallet service www.betrwallet.com. You need to
implement the integration in order to allow user authentication with the wallet. BETR Wallet
will also sign the betting transactions which will be sent to Ethereum blockchain.
2) Second Paragraph: JSON interaction with BBN ServerSecond Paragraph: JSON interaction with
BBN Server – describes the interactions between betting/laying user interface and BBN
service https://betrodds.io/. You need to implement the integration in order to display sport
events, markets, selections and prices/odds to users.
4
First Paragraph: JSON interaction with Wallet Server
The BBN Client requires access to the Ethereum blockchain via a Wallet Server with an Ethereum
JSON-RPC Relay and Transaction Signing service (JSON-RPC RTS).
Ethereum Interaction
When the customer wishes to place a bet, the BBN client will need to interact with the Better Betting Contracts on the Ethereum Network without the usual complexity of traditional interface methods such as Metamask or Remix. Furthermore, the method of interaction must work on any platform and / or device (products such as Metamask or Web3 do not work on mobile browsers).
The solution for this interaction is to use a Wallet Server providing a RESTful API for the BBN client which will accept standard JSON-RPC calls as requests, sign the request if necessary, forward the request onto an Ethereum endpoint, receive the response and return the response to the BBN client.
The Wallet Server not only provides a solution to the request / response requirement but will also provide the customer with a secure wallet to hold their ETH and BETR tokens. It is envisaged that there will be many Wallet Servers operated by different companies. The customer will instruct the BBN client to use the Wallet Server where they have an account.
When required, the Wallet Server will sign requests using the customer’s private key which is also held on the Wallet Server. A request that requires signing will involve an Ethereum transaction that changes the Ethereum state such as when a bet is placed.
Wallet Server Authentication
BBN customers will need to have an account with a Wallet Server and will need to have a balance of ETH and BETR tokens to place bets - ETH is used for the transaction costs associated with the submission of a state-change Ethereum transaction and BETR tokens are used as the betting currency for the Better Betting network.
The intention is to separate the BBN client from the Wallet Server authentication process. In other words, the BBN client does not hold the Wallet Server’s authentication tokens or depend on the method of authentication. This approach allows the Wallet Server to carry out their authentication process in any way that is applicable to their operation. This includes 2FA and other third-party forms of Authentication including Facebook and Google authentication.
The primary method that will enable this will be to make Ethereum requests to the Wallet Server via an <iframe>. Alternatively the request can be submitted as a simple HTTP call. If authentication is required, then the Wallet Server will handle the process separately from the BBN client. When authentication has successfully completed, the original request will be forwarded onto the Ethereum endpoint and the response returned as expected. From then on and until authentication is needed again (on timeout or any other reason the Wallet Server decides), Ethereum requests will be submitted and responses received via the Wallet Server.
Usually the Wallet Server will supply some form of authentication token in the form of a Cookie. Subsequent calls to the Wallet Server will automatically supply the Cookie as part of the usual HTTP request process. If the Cookie is invalidated for any reason (such as a timeout) then the Wallet Server will need to request authentication again.
5
Authentication Methods
BBN Clients written in various languages and running on different platforms will have differing capabilities. Therefore, the Wallet Server will need to respond in different ways depending on the client. For example, the BBN Test Client is written using Javascript and uses an <iframe> for all communication with the Wallet Server and the Xamarin BBN client will use Webview which is a browser container.
<iframe> Method for Javascript
For Javascript interaction an <iframe> is recommended which encapsulates the Wallet Server interaction into a window. The issue with the <iframe> approach is to receive the response from the <iframe> call back and pass it up to the BBN Client. The proposed method is to use Event Listeners in the BBN Client which can receive posted messages from an <iframe> window. For example, in the BBN Client an Event Listener is defined and will listen for any event with the property of ‘message’. The origin of the message can be restricted by checking the event origin which in our case only messages from https://betrwallet.com/api/request/ are to be checked.
Here’s a code snippet to demonstrate this.
window.addEventListener('message', function(event) {
if (~event.origin.indexOf('https://betrwallet.com/api/request')) {
var return_data = JSON.parse(event.data);
So now the BBN Client is waiting on messages to be posted from the <iframe>. To send messages up to the client, the <iframe> request will return a piece of Javascript which will contain
window.parent.postMessage(JSON.stringify(data), '*');
to send responses to the parent which is the BBN Client. Ok, so that’s how we can communicate between the <iframe> and the BBN Client. To send a request for the current Ethereum gas price, the following JSON-RPC request needs to be sent: {"jsonrpc":"2.0","method":"eth_gasPrice", "params":[],"id":900}
Please note that all wallet requests should have ?js=1 parameter. To initiate the call to the Wallet Server, the <iframe> can be created with a call like this:
<iframe
src="https://betrwallet.com/api/request?js=1&qs=%7B%22jsonrpc%22%3A%222.0%2
2%2C%22method%22%3A%22eth_gasPrice%22%2C%20%22params%22%3A%5B%5D%2C%22id%22
%3A900%7D"></iframe>
Or programmatically like this: $("#iframe_id").attr('src',$("#walletServerURL").val() + "?js=1&qs=" +
encodeURIComponent($("#JSONData").val()));
6
The response from the Wallet Server will contain a piece of Javascript which will automatically execute. Here’s the template which will need to be edited by the Wallet Server before sending. <!DOCTYPE html>
<html>
<head>
<title>JSONRPCQS1 Return</title>
</head>
<body>
<b>BETR.VIP Wallet Server iframe</b>
<br><br>JSON RPC QS 1
<script type="text/javascript">
var endPointURL = "ENDPOINT_URL";
var accountObj = {
walletAddress:"WALLET_ADDRESS",
ETHBalance:"ETH_BALANCE",
BETRBalance:"BETR_BALANCE"
};
accountObj['rpcResponse'] = "JSON_RPC RESULT OBJECT";
window.parent.postMessage(JSON.stringify(accountObj),'*');
</script>
</body>
</html>
7
Example: !DOCTYPE html>
<html>
<head>
<title>JSONRPCQS1 Return</title>
</head>
<body>
<script type="text/javascript">
var accountObj = {
walletAddress: "0x694d91a320fA83c95B89297C826CD455509Bfe91",
ETHBalance: "0.995522",
BETRBalance: "759.999999" };
accountObj['rpcResponse'] =
"{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"0x3b9aca00\"}";
window.parent.postMessage(JSON.stringify(accountObj), '*');
</script>
</body>
</html>
The Wallet Server is returning the Wallet Address, the ETH and BETR balances by editing the fields with the values from the Wallet Server Database. The result object of the JSON-RPC call is inserted into the accountObj. The accountObj is the posted to the <iframe> parent for subsequent processing. A point to note is that the responses from the Wallet Server must always contain a HTTP Header to prevent a cross domain error. The HTTP Header name is “Access-Control-Allow-Origin” and is sent with a “*” to allow for all origins.
<iframe> Method for Javascript – Safari browser
For Safari browser authorization should go a bit different. As Safari has no cookies in cross-origin iframes, we need to get token while logging in, and then use this token each request.
To get token –
$("#wallet_id").attr('src', `https://betrwallet.com/?js=1`);
Token will be posted in parent window.
Then token should be added to each request
${walletUrl}?js=1&qs=${qs}&tk=${token}
8
Direct Call
In cases where the <iframe> method will not work, such as with the Xamarin Webview, the alternative is to use direct calls and handle the responses programmatically. The Direct Call method consists of one call using the same URIEncoded query string format as with the <iframe> method. If the Wallet Server needs to carry out authentication, then it will return the necessary HTML for the client to display. The Wallet Server will return HTML The response will be like this: <result>
<walletAddress>0x1B5a00d5538bdC328Eff099B61f84e65C2c4115b</walletAddress>
<ETHBalance>0.0023087777906</ETHBalance>
<BETRBalance>170.479883889435672595</BETRBalance>
<rpcResponse>{"jsonrpc":"2.0","id":123,"result":"0x2540be400"}</rpcResponse>
</result>
Alternatively, the response can be wrapped in a JSON string as follows: {“response”:{“walletAddress”:
“0x1B5a00d5538bdC328Eff099B61f84e65C2c4115b”,”ETHBalance”:
0.0023087777906,”BETRBalance”:170.479883889435672595,”rpcResponse” :
{"jsonrpc":"2.0","id":123,"result":"0x2540be400"}}}
JSON-RPC Relay and Signing
As the BBN client does not have any direct communication with Ethereum, the next requirement for
the Wallet Server is to act as an agnostic JSON-RPC Relay or interface between the BBN client and
Ethereum.
There are two types of request, those that do not change Ethereum state such as getting a balance,
and those that do change state such as placing a bet or transferring tokens from one account to
another.
Requests that do change state will need to be signed with the Wallet Server user’s private key before
sending on to Ethereum. This is because the transaction needs to be identified and paid (in ETH) for
by the user’s address that is sending the transaction. The response is sent back to the BBN client the
same in both cases.
Generally, the transactions that change state are requested by the JSON-RPC
eth_sentRawTransaction method. The Wallet server will intercept these transactions and carry out
the following steps:
1. Get ETH Balance and check is greater that 0, if not, then reject this request
2. Get BETR Balance and check if greater than 0, if so then
9
a. Check the escrowAllowed flag is set to TRUE on the BETR token account for the
Wallet User, if not, then assemble a transaction to set the flag to TRUE and then
submit the transaction to the following process
b. Once the escrowAllowed transaction has completed, then submit original
transaction. It’s quite hard to know when the escrowAllowed transaction has
completed. A check on the flag status every 10 seconds with a failure after, say, 5
minutes would be one solution. Another might be just to submit the original
transaction after a, say, 30 second wait might be another approach.
3. Get Gas Price
4. Estimate the Cost of the transaction that will be submitted
5. Set the gas (limit) of the transaction to be the estimated Gas Price
6. Sign the transaction with the user’s private key
7. Send transaction to Ethereum and return the response to the BBN Client
Sample code for a Node JS server is available if needed.
Here’s an overview of what’s happening:
10
11
Second Paragraph: JSON interaction with BBN Server
Betting event and price data is provided to the BBN Clients (both Bettor and Layer UI) from a BBN
Server. The Bettor UI customer may select the Sport, Competition, Event, the Bet they wish to bet
and the amount in BETR tokens that they wish to bet. Also, the customers may consult their betting
history to see the results of their previously placed bets.
BBN Server API-s used by the Bettor UI:
1) events
2) eventMarkets
3) createPlaceBet
4) getBetHistory
5) getPendingBets (optional)
BBN Server API-s used by Layer UI:
1) getPendingBets
2) createConfirmBet
3) getPendingResults
4) createResultBet
5) addLayMarket
Please find below the overview of all of the API-s.
12
1. events In order to display Events in Bettor UI, please use the Events API: https://betrodds.io/ux/events. It
returns list of sport events in date order. Like this:
13
Events - parameters
The service also accepts parameters in any combination which allows you to build filters:
• https://betrodds.io/ux/events?location=248
• https://betrodds.io/ux/events?location=248&sport=6046
You can specify parameters for sport or league. Examples of requests for events/leagues:
• get sports list:
https://betrodds.io/ux/sports
• get leagues filtered by sport:
https://betrodds.io/ux/leagues/sport/7231350366223531278
• get events filtered by league:
https://betrodds.io/ux/events/league/7231350366223533224
• get events filtered by sport :
https://betrodds.io/ux/events/sport/7231350366223531278
Here is an example how Events are typically displayed in Bettor UI:
14
Events - statuses
Events service provides the below status codes:
1) status – indicates the status of the event. Possible values are:
1 - not started yet
2 - in progress
9 - about to start (this status becomes active 2-3 minutes before the in-play betting
starts)
2) live – indicates, if game is in Live and is playing now. Same as “status = 2 (in progress)”.
Possible values are:
0 -no
1 – yes
3) ingame – indicates, if in-game betting is offered for that even or not. Possible values are:
0 -no
1 – yes
4) ingame_status – indicates, if BBN in-game service is working. Possible values are:
0 -no
1 – yes
15
2. eventMarkets In order to display Markets, Selections, Layers and Prices/Odds per Event, please use eventMarkets
API: https://betrodds.io/ux/eventMarkets/15806291250007643066 – when testing, please replace
the event_id (15806291250007643066) and use the ID, which is available in the system – ie use an
event which starts in 1-2 days. Such events are typically available for testing).
It returns list of markets, layers, lays, selections and prices/odds (any many other Event/Market data
fields which can be used to build more detailed UI). Like this:
16
Note that you can also narrow down (for efficiency when looking at one market) by adding a
market_type_id:
https://betrodds.io/ux/eventMarkets/7231350366221107308?market_type_id=7231350366221112
720
Here is an example how Markets, Selections, Lays and Odds/Prices are typically displayed in Bettor
UI:
Another useful filter will be the price/odds updates feed, what you can use for building In-Game
(Livebetting) user interface where prices change often.
Please find a sample with additional parameter selection_type_id here:
https://betrodds.io/ux/eventMarkets/7231350366221107260?selection_type_id=7231350366221260232
17
Lays
What differentiates BETR Bettor UI from classical sportsbooks is that there is typically many Layers
offering their Lays under every market. This also makes the user interface more complex as under
every Selection you will have many Lays.
In order to display correct Lays under every Selection, please call the service with selection_id:
https://betrodds.io/ux/eventMarkets/15806253598058506279?selection_id=158062535980585064
08
Below you can find an explanation of the eventMarkets call fields:
• “id” – ID of the Lay
• “lay_market_id” -
• “layer” – Layer Wallet ID
what is used to back the lay
• “layer_type” – if 2, then user
description is displayed; if 1,
then we show layer as
anonymous
• “layer_name” – Layer display
name
• “layer_image_url” – Layer
image thumbnail (optional)
• “resultor” – Resultor Wallet
ID what is used to result the
Lay
• “price” – price/odds specified
by the Layer what you can
use to place bets (in BETR).
Price/Odds usually change
over time and you need to
update the prices in your UI
• “start_price” – initial odds
offer (the first odds value
when it was first recieved
from sports feed)
• “price_move” – values can be
can be 0 / -1 / 1 – they
indicate the price move ether
up (1) or down (2). 0
indicates that the price
stayed the same
• “max_bet” – maximum bet
amount (in BETR)
• “status” - 1 = open for betting. 2 = suspended. 3 = resulted. Anything higher is internal
18
Templates
In the eventMarkets API call we have “template” field that indicates how the markets and selections should be rendered.
This field is used by the Bettor UI built by BetterBetting Foundation and is completely optional for you. However, the field might help you to understand how to render different selections (eg number of columns, rows, grouping, filtering). Here is the list of templates built into the API:
• 1x2 – display template with 1 row and 1 column. Example: “Both Teams To Score” market
• 1x3 – display template with 1 row and 3 columns. Example: “Full Time Result” market
19
• 3x3 – display template with 3 rows and 3 columns. Example: “Half Time / Full Time” market
• NX3 – display template with unlimited number of rows and 3 columns. Example: “Correct Score” market
• NX2 – display template with unlimited number of rows and 2 columns. Example: “Goals Over/Under” market
• NX2[{team1}][{team2}] – subtype of NX2 display template with unlimited number of rows and 2 columns. Used for markets where in the selections you have home team and away team. Example: “Asian Handicap” market
20
In most cases eventMarkets API also sorts the selections under every market using the “position” field.
Status Codes
https://betrodds.io/ux/eventMarkets/7231350366221107308 has 3 different status codes: API call status, event status and selection status. The status codes for the event and selection are the same: 1 = open for betting 2 = suspended 3 = resulted Anything higher is internal The API call status will be >0 if something went wrong with an explanation in the text field. Please see the example below:
21
22
3. Leagues
Leagues API gives you the list of available leagues with locations: https://betrodds.io/ux/leagues.
Location data is especially useful when building localized user interfaces – for example to display
American sports using the traditional “away team” @ “home team” template. You can find the API
sample data here:
23
4. createPlaceBet
In order to place a bet please use the createPlaceBet API to pass the data to the Wallet server:
https://betrodds.io/ux/createPlaceBet?stake=10&lay_id=7231350366221140459
CreatePlaceBet creates JSON token call to reserve a bet on behalf of the Bettor. The call places a bet
and sends it to Ethereum blockchain.
This would be followed by createConfirmBet what is created by the Layer.
NB! Stake and Lay ID are required fields.
Data part is what is needed for contract execution.
LayerID is Ethereum public wallet address of the layer
BettorID is Ethereum public wallet address of the bettor
Here is an example code snippet how to setup parameters for createPlaceBet API:
JSON
• BBN
o api : "createPlaceBet"
o version : "1.0"
o status : 0
o msg : ""
o debug :
"{"params":{"name":"placeBet","type":"function","inputs":[{"type":"uint256","name":"_m
arketId"},{"type":"uint256","name":"_selectionId"},{"type":"string","name":"_odds"},{"ty
pe":"uint256","name":"_stakeAmount"},{"type":"address","name":"_layerAddress"},{"typ
e":"address","name":"_resultorAddress"},{"type":"string","name":"_betDescription"}]},"0"
:["7231350366221140458","7231350366221129103","3.10000000","10000000000000000
000","0x78Ae08B7164E7859b3E4C9cC50a69EED699D36d3","0x78Ae08B7164E7859b3
E4C9cC50a69EED699D36d3","2018-05-26 18:45:00 - Real Madrid vs Liverpool : Full
Time Result"]}"
• data
o to : "0xf1C6900A2e8F05F30C87960897b23Cac3C1017a5"
o data :
"0x36fe3f95000000000000000000000000000000000000000000000000645aead8410081ea
000000000000000000000000000000000000000000000000645aead84100558f0000000000
0000000000000000000000000000000000000000000000000000e00000000000000000000
000000000000000000000000000008ac7230489e8000000000000000000000000000078ae0
8b7164e7859b3e4c9cc50a69eed699d36d300000000000000000000000078ae08b7164e785
9b3e4c9cc50a69eed699d36d30000000000000000000000000000000000000000000000000
24
0000000000001200000000000000000000000000000000000000000000000000000000000
00000a332e313030303030303000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000041323031382d30
352d32362031383a34353a3030202d205265616c204d6164726964207673204c6976657270
6f6f6c203a2046756c6c2054696d6520526573756c74000000000000000000000000000000
00000000000000000000000000000000"
o value : "0x0"
o id : 0
5. createConfirmBet
createConfirmBet is created by the Layer after Bettor places a bet using CreatePlaceBet call. With
this call bet is confirmed in the Ethereum blockchain.
Layer will typically use the following flow:
a. Layer queries for the bets waiting for confirmation by using getPendingResults call
b. Layer confirms the bets using createConfirmBet call
6. getPendingBets
getPendingBets is call used to display bets waiting for Layers confirmation
getPendingBets API: https://betrodds.io/ux/getPendingBets($address) NB! address is Layers wallet address which is used to lay BETR bets.
7. getPendingResults
getPendingResults is call used by the Resultor (often it’s the same entity as Layer) getPendingResults API: https://betrodds.io/ux/getPendingResults($address)
8. createResultBet
createResultBet is call used by the Resultor to result the bets. createResultBet API: https://betrodds.io/ux/createResultBet
25
9. getBetHistory
In order to display Bet History, please use service: https://betrodds.io/ux/history/address/<address>
Address is customer’s BETR Wallet address and Bettor UI only displays the betting history linked to
that wallet.
NB! There might be delay (up to 2 minutes) after bet is placed until the Bet History becomes visible.
Please be aware of that restriction as it affects customer experience.
Below you can find the bet status ID-s returned by the getBetHistory feed:
0 => 'Not Confirmed (Bet is created by Bettor but not yet Confirmed by Layer)',
1 => 'Confirmed & Not Resulted Yet',
2 => 'Bet Rejected By Layer',
3 => 'Bet Cancelled by System',
4 => 'Bet Cancelled by Bettor',
13 => 'Bet Won',
12 => 'Bet Lost',
14 => 'Refund',
15 => 'Lose / Push',
16 => 'Win / Push'
10. addLayMarket
Call used by Layer to add a market for laying bets.
https://betrodds.io/ux/addLayMarket
Note that either prices should be specified for all selections, or the market should be pinned to
'reference prices'. Market and selection IDs should be valid as per the existing API