Config
 
                    module.exports =  Object.freeze({
                        address: {
                            node: 'https://nodes.wavesplatform.com',
                            matcher: 'https://matcher.wavesplatform.com',
                            wallet: '3PPwkvZnzicSGCzJdqMj7TsphVstMT4EXN9',
                            data: 'test random data',
                        },
                        accepted: {
                            WAVES: 'WAVES',
                            BTC: '8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS',
                            ETH: '474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu',
                            TRY: '2mX5DzVKWrAJw8iwdJnV2qtoeVG9h5nTDpTqC1wb1WEN',
                            LTC: 'HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk',
                        },
                        exchange: {
                            dataServices: 'https://api.wavesplatform.com/v0/pairs',
                        }, 
                    });
                    
Server
var express = require('express');
var socket = require('socket.io');
const axios = require("axios");
const pdftk = require('node-pdftk');
var https = require('https');
var http = require('http');
var fs = require('fs');
var app = express();
var config1 = require('./config');
const uuidv1 = require('uuid/v1');
Base58 = require("base-58");

assetList = [];

var options = {
    key: fs.readFileSync('payment.digilira.com/combined'),
    cert: fs.readFileSync('payment.digilira.com/combined'),
    ca: fs.readFileSync('payment.digilira.com/combined')
};

for (var key in config1.accepted) {
    if (config1.accepted[key] != "WAVES") {
        loadAsset(config1.accepted[key]);
    }
}

var server = https.createServer(options, app);
const io = socket(server);

server.listen(8080, function () {
    console.log('server up and running at 8002 port');

});

console.log('socket');

io.on('connection', function (socket) {
    var socketId = socket.id;
    var clientIp = socket.request.connection.remoteAddress;

    console.log(clientIp, socketId);

    socket.on('data', function (buf) {
        console.log(buf);
        var js = JSON.parse(buf);
        io.emit(js.msg, js.data); //Send the msg to socket.io clients
    });

    socket.on('blockchain', async function (buf) {
        var price = await checkBlockchain(buf.key, 0)
        console.log(price[0]);
        io.sockets.connected[socket.id].emit('onay', price[0]);

    });

    socket.on('qrcodePay', async function (data) {
        app.get('./dekont.pdf', (req, res, next) => {
            pdftk
                .input('./dekont.pdf')
                .fillForm({
                    txt_tarih: 'data'
                })
                .flatten()
                .output('./test.pdf')
                .then(buf => {
                    res.type('application/pdf');
                    res.send(buf);
                })
                .catch(next);
        });

        console.log(data.islemid);
        var a = await checkBlockchain(data, 0);
        io.sockets.connected[socket.id].emit('onay', a);
    });

    socket.on('fetch', async function (data) {
        console.log(data);
        var a = await fetchData(config1.address.wallet);
        io.sockets.connected[socket.id].emit('fetch', a);
    });

    socket.on('onay', async function (data) {
        console.log(data.product);
        var dict = JSON.parse(data.transfer);
        var a = await checkKeeperTrx(dict['id']);
        var result = [a, data.product, "PAYMENT-" + data.product];
        io.sockets.connected[socket.id].emit('onay', a[0]);
    });

    socket.on('admin', async function (data) {
        var value = Buffer.from(JSON.stringify(data)).toString('base64');
        params = {
            type: 'string',
            key: "PRODUCT-" + uuidv1(),
            value: value,
        }
        console.log(params);
        io.sockets.connected[socket.id].emit('dataTrx', params);

    });

    socket.on('editItem', async function (data) {
        var value = Buffer.from(JSON.stringify(data)).toString('base64');
        console.log(data);
        params = {
            type: 'string',
            key: data.data.id,
            value: value,
        }
        console.log(params);
        io.sockets.connected[socket.id].emit('dataTrx', params);

    });


    socket.on('fiyat', async function (data) {

        for (var key in config1.accepted) { 
            if (config1.accepted[key] == data.priceAsset) {
                var price = await orderbook(config1.accepted[key], data.amountAsset, data.price, key);
            }
        }
        var uuid = uuidv1(),
            params = {
                div: data.key,
                item: data.item,
                para: price[0],
                coin: price[1],
                adres: config1.address.wallet,
                asset: data.priceAsset,
                uuid: uuid,
                qrcode: "https://client.wavesplatform.com/#send/" + data.priceAsset + "?recipient=" + config1.address.wallet + "&amount=" + price[0] + "&attachment=" + uuid + "&strict",
            }
        console.log(params);
        io.sockets.connected[socket.id].emit('result1', params);

    });

});


function fetchAsset(ASSETID) {

    return new Promise(function (resolve, reject) {
        try {
            const url = config1.address.node + "/assets/details/" + ASSETID;
            const getData = async url => {
                try {
                    const response = await axios.get(url);
                    const data = response.data;
                    resolve((data));
                } catch (error) {
                    console.log(error);
                }
            };
            getData(url);
        } catch (error) {
            console.log(error);
        }
    })
}


function orderbook(AMOUNT, PRICE, DEAL, NAME) {
    return new Promise(function (resolve, reject) {
        try {
            amountDecimals = 0;
            priceDecimals = 0;
            amountAssetName = "";
            priceAssetName = "";

            assetList.forEach(function (element) {
                if (element.assetId == AMOUNT) {
                    amountDecimals = element.decimals
                    amountAssetName = element.name;

                };
                if (element.assetId == PRICE) {
                    priceDecimals = element.decimals
                    priceAssetName = element.name;
                };
            });

            if (AMOUNT == 'WAVES') {
                amountDecimals = 8;
                amountAssetName = 'WAVES';
            }
            if (PRICE == 'WAVES') {
                priceDecimals = 8;
                priceAssetName = 'WAVES';

            }

            if (AMOUNT == PRICE) {

                var price = (DEAL);
                dict = [price, priceAssetName];

                resolve(dict); //RETURN PRICE
                return true;
            }

            const url = config1.address.matcher + "/matcher/orderbook/" + AMOUNT + "/" + PRICE;

            const getData = async url => {
                try {
                    const response = await axios.get(url);
                    var pair = response.data['pair'];

                    var asks = response.data['asks'];
                    var bids = response.data['bids'];

                    amountAsset = pair['amountAsset'];
                    priceAsset = pair['priceAsset'];
 
                    //console.log(asks);
                    var base = 0;
                    asks.some(function (element) {

                        base += element['amount'] / 10 ** priceDecimals;
                        console.log(base, DEAL);
                        if (base > parseFloat(DEAL)) {
 
                            console.log(DEAL, PRICE, AMOUNT, element['price'], amountDecimals);
                            if (AMOUNT == amountAsset) {
                                var price = (DEAL) / (element['price'] / 10 ** priceDecimals);
                                dict = [price.toFixed(amountDecimals), amountAssetName];
                                console.log("STRAIGHT");
                            }
                            if (AMOUNT == priceAsset) {
                                var price = (DEAL) * (element['price'] / 10 ** amountDecimals);
                                dict = [price.toFixed(amountDecimals), amountAssetName];
                                console.log("CROSSED");
                            }

                            resolve(dict); //RETURN PRICE
                            return true;
                        }
                    });
                    if (base < parseFloat(DEAL)) {
                        console.log('NOT ENOUGH DEPTH');
                        dict = ['E0', 'NOT ENOUGH DEPTH'];

                        resolve(dict); //RETURN PRICE
                        return true;
                    }

                } catch (error) {
                    console.log(error);

                }
            };
            getData(url);
        } catch (error) {
            console.log(error);
        }
    })


}


async function loadAsset(ASSETID) {

    let promise = new Promise((resolve, reject) => {
        var details = fetchAsset(ASSETID);
        resolve(details);
    });
    let result = await promise; // wait till the promise resolves (*)
    assetList.push(result);
}


async function fetchData(WALLET) {

    return new Promise(function (resolve, reject) {
        try {
            const url = config1.address.node + "/addresses/data/" + WALLET;
            const getData = async url => {
                try {
                    const response = await axios.get(url);
                    const data = response.data;
                    var dict = [];
                    var main = [];
                    data.forEach(function (element) {
                        var arr = element.key.split("-");
                        if (arr[0] == "PRODUCT") {
                            //console.log(assetList);
                            var decoded = new Buffer.from(element.value, 'base64').toString();
                            var js = JSON.parse(decoded);
                            assetList.forEach(function (element) {
                                if (element.assetId == js["data"]["coin"]) {
                                    js["data"]["name"] = element.name;
                                }
                            })
                            if (js["data"]["coin"] == "WAVES") {
                                js["data"]["name"] = "WAVES";
                            }

                            console.log(js);
                            dict.push({
                                key: element.key,
                                value: js['data']
                            });
                        }
                    });

                    main.push(dict);
                    main.push(config1.accepted);

                    console.log(main);
                    resolve((main));
                } catch (error) {
                    console.log(error.response.status);
                    if (error.response.status == 404) {
                        setTimeout(function () {
                            getData(url);
                        }, 5000);
                    }
                }
            };
            getData(url);
        } catch (error) {
            console.log(error);
        }
    })
}


async function checkKeeperTrx(TID) {
    return new Promise(function (resolve, reject) {
        try {
            dict = [];
            console.log(TID);
            const url = config1.address.node + "/transactions/info/" + TID;
            console.log(url);

            const getData = async url => {
                try {
                    const response = await axios.get(url);
                    const data = response.data;
                    console.log(data);
                    dict.push({
                        key: (data['id']).toString(),
                        value: "PAYMENT SUCCESSFUL"
                    });
                    resolve(dict);
                } catch (error) {
                    console.log(error.response.status);
                    if (error.response.status == 404) {
                        setTimeout(function () {
                            getData(url);
                        }, 5000);
                    }
                }
            };
            getData(url);
        } catch (error) {
            console.log(error);
        }
    })
}

 async function checkBlockchain(DATA, TRYAGAIN) {
    return new Promise(function (resolve, reject) {
        try {
            dict = [];
            console.log(DATA);
            const url = config1.address.node + "/transactions/address/" + config1.address.wallet + "/limit/100";
            console.log(url);
            const getData = async url => {
                try {
                    const response = await axios.get(url);
                    const data = response.data;

                    var search = "";
                    if (data[0].length <= 0) {
                        setTimeout(function () {
                            getData(url, 0);
                        }, 5000);
                    } else {
                        data[0].forEach(function (element) {
                            if (element['attachment'] != null) {
                                var A = Base58.decode(element['attachment'])
                                var B = String.fromCharCode.apply(null, A);
                                if (B == DATA) {
                                    console.log("PAYMENT SUCCESSFUL");
                                    dict.push({
                                        key: (element['id']).toString(),
                                        value: "PAYMENT SUCCESSFUL"
                                    });
                                    resolve(dict);
                                    search = B;
                                }
                            }

                        });
                        console.log("try again..", DATA, TRYAGAIN);

                        if (TRYAGAIN < 20) {
                            if (search != DATA) {
                                TRYAGAIN++;

                                setTimeout(function () {
                                    getData(url, TRYAGAIN);
                                }, 5000);
                            }
                        }else{
                            dict.push({
                                key: "PAYMENT FAILURE",
                                value: "PAYMENT FAILED"
                            });
                            resolve(dict);
                        }
                    }
                } catch (error) {
                    console.log(error);
                    if (error.response.status == 404) {
                        setTimeout(function () {
                            getData(url);
                        }, 5000);
                    }
                }
            };
            getData(url);
        } catch (error) {
            console.log(error);
        }
    })
}
Keeper
var socket = io.connect('https://payment.digilira.com:8080', {secure: true});

var mobile = 0;
var ua = navigator.userAgent;
if (ua.match(/(iPhone|iPod|iPad|BlackBerry|Android)/)) {mobile = 1;}

function getDiv(DIV) {
	var frame = document.getElementById(DIV);
	return frame;
}


socket.on('result1', function(data){
	var frame = getDiv('productQR');
	var qrdiv = getDiv('product-QR');
	var info =  getDiv('product-title');
	var price =  getDiv('product-price');

	var qrcode = data.qrcode;

	info.textContent = ( data.item);
	price.textContent = ( data.coin + ":" + data.para + "\n" + data.adres );

	$(qrdiv).empty();
	$(qrdiv).qrcode(qrcode);
        $(qrdiv).unbind();
	$(qrdiv).click(function(){

		var win = window.open(qrcode, '_blank');
		win.focus();
	});

	var buybutton = document.createElement('div');
	buybutton.className = 'btn btn-primary btn-block btn-xs';
	buybutton.textContent = "Pay with WavesKeeper";

	buybutton.onclick = function () {
		$(info).text(data.item);
		app.send(data.adres, data.asset, (data.para).toString(), data.div, data.uuid);
	}

	var seperator = document.createElement('div');
	seperator.id = 'seperator'; 
	seperator.className = 'product-buttons'; 
	price.appendChild(seperator);

	price.appendChild(buybutton);

	frame.style.display = "block";

	socket.emit('blockchain', {
		key:data.uuid,
	});



});





socket.on('fetch', function(data){

	var container_root = document.createElement('div');
	container_root.className = 'container'; 

	var row_root = document.createElement('div');
	row_root.className = 'row'; 

	var colsm9 = document.createElement('div');
	colsm9.className = 'col-sm-9';

	var colsm3 = document.createElement('div');
	colsm3.className = 'col-sm-3'; 
	colsm3.id = "col-sm-3";

	var productQR = document.createElement('div');
	productQR.className = 'QR'; 
	productQR.id = 'productQR'; 

	var QR = document.createElement('div');
	QR.className = 'image'; 
	QR.id = 'product-QR'; 
	productQR.appendChild(QR);

	var QRTitle = document.createElement('div');
	QRTitle.className = 'product-title'; 
	QRTitle.id = 'product-title'; 
	productQR.appendChild(QRTitle);

	var QRPrice = document.createElement('div');
	QRPrice.id = 'product-price'; 
	QRPrice.className = 'product-buttons'; 
	productQR.appendChild(QRPrice);

	productQR.style.display = "none";


	var row_root2 = document.createElement('div');
	row_root2.className = 'row'; 

	document.getElementsByTagName('body')[0].appendChild(container_root);
	container_root.appendChild(row_root);

	row_root.appendChild(colsm9);
	colsm3.appendChild(productQR);

	row_root.appendChild(colsm3);
	colsm9.appendChild(row_root2);



	data[0].forEach(function(element) {


		var container = document.createElement('div');
		container.id = element.key;
		row_root2.appendChild(container);


		var colsm4 = document.createElement('div');
		colsm4.className = 'col-sm-4'; 
		container.appendChild(colsm4);


		var product = document.createElement('div');
		product.className = 'product'; 
		colsm4.appendChild(product);

		var picture = document.createElement('div');
		picture.className = 'image';

		var img = document.createElement('img');
		img.src = 'image/' + element.key + '.jpg';
		img.style.height = "200px";

		img.onload = function() { 
			picture.appendChild(img); 
		}

		img.onerror = function() {
			picture.textContent = element.key;
		}

		product.appendChild(picture);

		var productdesc = document.createElement('div');
		productdesc.className = 'product-desc'; 
		product.appendChild(productdesc);

		var producttitle = document.createElement('div');
		producttitle.className = 'product-title'; 
		producttitle.textContent = element.value['item'];
		productdesc.appendChild(producttitle);

		var productprice = document.createElement('div');
		productprice.className = 'product-price'; 
		productprice.textContent = element.value['name'] + " " + element.value['amount'];
		productdesc.appendChild(productprice);


		var productbuttons = document.createElement('div');
		productbuttons.className = 'product-buttons';
		productdesc.appendChild(productbuttons);


		var formgroup = document.createElement('div');
		formgroup.className = 'form-group'; 
		productbuttons.appendChild(formgroup);


		var label = document.createElement("LABEL");
		label.textContent = "Choose Coin"; 
		formgroup.appendChild(label);

		var selCoin = document.createElement("select");
		selCoin.class = "form-control input-sm";
		selCoin.name = "coin";
		selCoin.id = element.key + "-sid";
		for (var key in data[1]) {
			var value = data[1][key];
			selCoin.options[selCoin.length] = new Option(key, value);
		} 

		formgroup.appendChild(selCoin);

		var buybutton = document.createElement('div');
		buybutton.className = 'btn btn-primary btn-block btn-xs';
		buybutton.textContent = "Buy Now";


		buybutton.onclick = function () {

			var  e = document.getElementById (  selCoin.id  );
			var  strUser = e.options [e.selectedIndex].value;

			socket.emit('fiyat', {
				key:element.key,
				price:element.value['amount'],
				item:element.value['item'],
				amountAsset:element.value['coin'],
				priceAsset:strUser,
			});

		}

		productbuttons.appendChild(buybutton);





	});


});

socket.on('onay', function(data){
	var qrdiv = getDiv('product-QR');
	var info =  getDiv('product-title');
	var price =  getDiv('product-price');
	$(price).html("<br/><b> "  + data.value + "</b>");


});

socket.on('dataTrx', function(data){
	app.datatrx(data.type, data.key, data.value);
});


var app = new Vue({
	el: '#app',
	data: {
		node: 'https://nodes.wavesplatform.com',
		fee: '0.001',
	},
	methods: {

		fetchData:async function() {
			socket.emit('fetch', {
				data:"fetch",
			});

		}, 
		datatrx: async function (TYPE, KEY, VALUE) {
			let params = {
				type: 12,
				data: {
					fee: {
						assetId: 'WAVES',
						tokens: '0.001'
					},
					data: [
						{ type: TYPE, key: KEY, value: VALUE},
					],
				}
			} 

			if (this.checkKeeper()) {
				try {
					let res = await window.Waves.signAndPublishTransaction(params);
				} catch (err) {
					$('#bilgi').text("data hatası" );
				}
			} else {
				if (mobile == 0) { 
					alert('Please install WavesKeeper Extension.');
				}
			}


		},

		send: async function(ADRESS, COIN, AMOUNT, DIV, UUID) {
			let params = {
				type: 4,
				data: {
					amount: {
						assetId: COIN,
						tokens: AMOUNT
					},
					fee: {
						assetId: 'WAVES',
						tokens: '0.001'
					},
					recipient: ADRESS,
					attachment: UUID
				}
			}
			if (this.checkKeeper()) {
				try { 
					let res = await window.Waves.signAndPublishTransaction(params); 
					socket.emit('onay', {
						transfer:res,
						product:DIV
					});
					alert('Your payment is being processed, please wait.. ');
				} catch (err) {
					var frame = document.getElementById('productQR');
					var qrdiv = document.getElementById('product-QR');
					var info =  document.getElementById('product-title');
					var price =  document.getElementById('product-price');

					$(price).html("PAYMENT FAILED" );
				}
			} else {
				if (mobile == 0) { 
					alert('Please install WavesKeeper Extension.');
				}
			}
		},

		checkKeeper: function() {
			return typeof window.Waves !== 'undefined';
		}
	}
});
app.fetchData();