Skip to main content

Access Block Service API

image

This tutorial will get you konw how to access Block Service api. The Block Service is a application for syncing and serving the Lamden Blockchain to a local app. This application serves as starting point to be able to build an app on Lamden that requires easy access to current state and realtime updates.

Here is the completed Git repo for this part

caution

The Block Service used in these tutorials do not provide any guarantee !!! As a result, your should set up your own Block Service. Click here to learn more about the Block Service.

Display current round data

As a dapp, it's important to show the current lottery round data to users. Luckily the Block Serivce provides us with some APIs to accees the current state of smart contract.

Open the file src\helper.js. There are two methods getVariable() and getAllVariable, which are the wrappers of the two APIs mentioned above. We'll use these two methods to retrieve the current states of smart contract.

/** Return current state of a contract variable for smart contract 
* @param {string} contract
* @param {string} variableName
* @param {any[]} keys
* @param {any} default_value
**/
export async function getVariable(contract, variableName, keys, default_value) {
try {
let url = `http://${Network[process.env.NODE_ENV].blockService}/current/one/${contract}/${variableName}`;
if (keys.length > 0) {
url = `${url}/${keys.join(':')}`
}
const res = await fetch(
url, {
method: 'GET',
},
)
if (res.status === 200) {
let json = await res.json()
let value = json.value
if (value || value===0) {
if (value.__fixed__) return new BigNumber(value.__fixed__)
else return value
} else {
return default_value
}
} else {
return default_value
}
} catch (error) {
return default_value;
}
}

/** Return all the state of a contract variable
* @param {string} contract
* @param {string} variableName
* @param {any[]} keys
**/
export async function getAllVariable(contract, variableName, keys) {
try {
let url = `http://${Network[process.env.NODE_ENV].blockService}/current/all/${contract}/${variableName}`;
if (keys.length > 0) {
url = `${url}/${keys.join(':')}`
}
const res = await fetch(
url, {
method: 'GET',
},
)
if (res.status === 200) {
return res.json()
} else {
return {}
}
} catch (error) {
return {};
}
}

Let us open the file src\Pages\Home\Play.jsx. First we should know the newest round number of lottery. Copy the below code into the file. It will get the newest round number when the component is mounted.

useEffect(() => {
getVariable(contract, "current_round", [], 0).then((res) => setCurrentRound(2))
}, [])

Now that we have known what is the newest round. Next we will fetch the whole data of the newest round.

info

The timezone on the Lamden Blockchain is always UTC+0 so that we should convert the date from blockchain to local date.

useEffect(() => {
const convertDate = (dateArr) => {
let date = new Date(...dateArr)
date.setMonth(date.getMonth() - 1)
return changeTimeZone(date).toLocaleString()
}

getAllVariable(contract, "rounds", [currentRound])
.then((res) => {
let data = res[contract]["rounds"][currentRound.toString()]
data.endTime = convertDate(data.endTime.__time__)
data.startTime = convertDate(data.startTime.__time__)
data.roundNumber = currentRound

let statistics = {
restPrize: 0,
totalBetAmount: 0,
Banana: 0,
Grape: 0,
Lemon: 0,
Orange: 0,
Peach: 0,
Pineapple: 0
}

for (let key in data.betInfo) {
for (let item of data.betInfo[key]) {
statistics[key] = new BigNumber(item.amount.__fixed__ || item.amount).plus(statistics[key])
}
statistics.totalBetAmount = new BigNumber(statistics[key]).plus(statistics.totalBetAmount)
}
if (currentRound)
setRound(r => {
// Don't update
if (r.roundNumber > data.roundNumber) return r

statistics.restPrize = r.statistics.restPrize
return {
...data,
statistics
}
})
})

getVariable(contract, "total", [], 0).then((res) => {
setRound(r => {
r.statistics.restPrize = res
return r
})
})
}, [currentRound])

Save the changes and you would see:

image

Please click the button Buy Tickets, you'll see the back of draw card.

image

Display Tau Balance

You will notice that the balance is 0, but your actual balance is not 0. You need to add some new code to make the balance display correct.

useEffect(() => {
if (!showCover) {
getVariable("currency", "balances", [wallet.account], 0).then((res) => setWallet(w => ({
...w,
tauBalance: res.toString()
})))
}
}, [showCover, wallet.account, setWallet])

Save the new changes and take a look!

image

Display History

Click the tab button Claim. Then you will find nothing about the bet history.

image

We can get current states of lottert contract by calling the Block Service APIs and then display them to suers. So that users can easily figure out what rounds they have played so far.

The first thing that we need to do is to get to know what rounds users have played. So we can get the value of user_rounds. Open the file src\Pages\Home\Claim.jsx and copy the code into the componet "Claim".

useEffect(() => {
getVariable(contract, "user_rounds", [wallet.account], [])
.then((res) => setUserRounds(res))
}, [wallet.account])

Next get all lottery data, and then filter out the lottery data that the user has played.

useEffect(() => {
// Conver date to local date
const convertDate = (dateArr) => {
let date = new Date(...dateArr)
date.setMonth(date.getMonth() - 1)
return changeTimeZone(date).toLocaleString()
}

if (userRounds.length > 0 && wallet.account) {
getAllVariable(contract, "rounds", [])
.then((res) => {
if (res === {}) return

let betList = []

let data = res[contract]["rounds"]
for(let i of userRounds) {
let round = i.toString()
data[round].endTime = convertDate(data[round].endTime.__time__)
data[round].startTime = convertDate(data[round].startTime.__time__)
data[round].id = round

for(let k in data[round].betInfo) {
let amount = 0
for(let b of data[round]['betInfo'][k]){
if (b.buyer === wallet.account) {
amount = new BigNumber(b.amount.__fixed__ || b.amount).plus(amount)
}
}
data[round]['betInfo'][k] = amount.toString()
}
betList.push(data[i])
}
setBetInfo(betList)
})
} else {
// Reset the betinfo if wallet connection disconnect
setBetInfo([])
}
}, [userRounds, wallet.account])

Save the changes above to file src\Pages\Home\Claim.jsx and take a look !!!

image