constrequest=require('request');constcorrespondents=require('./correspondents');let steps = {}; // store user stepslet assocDeviceAddressToCurrentCityAndTemp = {}; let assocDeviceAddressToAddress = {};let bets = [];letKEY_API='50ace22603c84daba1780432180111'; // apixu.comlet my_address;
Save our address for use in the contract
headlessWallet.readSingleWallet(walletId => {db.query("SELECT address FROM my_addresses WHERE wallet=?", [walletId],function (rows) {if (rows.length===0)throwError("no addresses"); my_address = rows[0].address; });});
Let’s add a text handler and analyze what happens:
eventBus.on('text', (from_address, text) => { text =text.trim().toLowerCase();if (!steps[from_address]) steps[from_address] ='start';let step = steps[from_address];constdevice=require('ocore/device.js');if (validationUtils.isValidAddress(text.toUpperCase())) { // If address sent to us - save it. assocDeviceAddressToAddress[from_address] =text.toUpperCase();returndevice.sendMessageToDevice(from_address,'text','I saved your address. Send me the name of the city'); } else if (!assocDeviceAddressToAddress[from_address]) { // If we do not know the address - asking it to send for us.
return device.sendMessageToDevice(from_address, 'text', 'Please send me your byteball address(... > Insert my address)');
} elseif (step ==='city'&& (text ==='more'|| text ==='less')) { // Create a contract and ask to pay for itlet time =Date.now() +20*60*1000;let name = assocDeviceAddressToCurrentCityAndTemp[from_address].city +'_'+ time;let operator = text ==='more'?'>=':'<=';let value = assocDeviceAddressToCurrentCityAndTemp[from_address].temp; createContract(my_address, assocDeviceAddressToAddress[from_address], 2001, 2000, from_address, name, operator, value, time,
(err, paymentRequestText, shared_address, timeout) => {if (err) throw err;findOracleAndSendMessage(assocDeviceAddressToCurrentCityAndTemp[from_address].city +':'+ time, () => {bets.push({ myAmount:2001, peerAmount:2000, myAddress: my_address, peerAddress: assocDeviceAddressToAddress[from_address], sharedAddress: shared_address, peerDeviceAddress: from_address, name, operator, value, timeout });device.sendMessageToDevice(from_address,'text', paymentRequestText);setTimeout(() => { // If the payment was not made for 10 minutes-we take the moneyheadlessWallet.sendAllBytesFromAddress(shared_address, my_address, from_address, (err, unit) => {if (!err) console.error('unit:: ', unit); }); },15*60*1000); }); }); } elseif (step ==='start') { // Check the weather and specify what rate the user wants to makeswitch (text) {case'berlin':case'moscow':case'helsinki':case'washington': request('https://api.apixu.com/v1/current.json?key=' + KEY_API + '&q=' + text, function (error, response, body) {
if (error) {console.error(error);device.sendMessageToDevice(from_address,'text','An error occurred. Try again later.'); } else {let result =JSON.parse(body);let temp =result.current.temp_c; device.sendMessageToDevice(from_address, 'text', 'Want to bet that in an hour the weather in ' + text + ' will be\n[more ' + temp + 'c](command:more) or [less ' + temp + 'c](command:less)?');
steps[from_address] ='city'; assocDeviceAddressToCurrentCityAndTemp[from_address] = {city: text, temp}; } });break;default:device.sendMessageToDevice(from_address,'text',"City not support");break; } } else { device.sendMessageToDevice(from_address,'text',"unknown command"); } });});
Now let’s talk about contract creation.
We need a separate function
Let’s analyze what happens
arrSeenConditionPeer - watching if there was a payment in the contract with the amount same of the user.
arrSeenConditionMyInput - сhecking, did we withdraw bytes? If yes, then allow the user to pick up their bytes.
arrDefinition - this is what our contract looks like, let’s look at it in details.
When we need some address to subscribe we use [‘address’, address]
When we need to check the publication data_feed we use
[‘in data feed’, [[conf.oracle_address], name, operator, value]]
assocSignersByPath - in this object, we prescribe the path in the array of the contract before you need to sign and who should sign it. In our example, we sign all ‘address’. The path starts with r-this is the first element in the array, in our case ‘or’ construction. Other examples with signatures will be discussed in the following lessons.
walletDefinedByAddresses.createNewSharedAddress - we create a contract address
headlessWallet.issueChangeAddressAndSendPayment - we add the address of the contract and make a payment to it
We check whether there is an oracle in our correspondents and if it is not - we add.
That’s all. I also have a homework for you. Complete the oracle and our bot so that oracle informs us that he published and the publication has become stable. After oracle message, notify the user that he lost or won. And if he lost then take the money out of the contract. All code is available on github. Did you like the lesson? Any questions? What topics have caused you difficulties and it is worth talking about them? Write in the comments and I will help you. Also join my telegram chat - @obytedev.