module.exports = (shepherd) => { shepherd.elections = {}; shepherd.hex2str = (hexx) => { const hex = hexx.toString(); //force conversion let str = ''; for (let i = 0; i < hex.length; i += 2) { str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); } return str; }; shepherd.post('/elections/status', (req, res, next) => { if (shepherd.checkToken(req.body.token)) { const successObj = { msg: 'success', result: shepherd.elections.pub ? shepherd.elections.pub : 'unauth', }; res.end(JSON.stringify(successObj)); } else { const errorObj = { msg: 'error', result: 'unauthorized access', }; res.end(JSON.stringify(errorObj)); } }); shepherd.post('/elections/login', (req, res, next) => { if (shepherd.checkToken(req.body.token)) { let keys = shepherd.seedToWif(req.body.seed, req.body.network, req.body.iguana); shepherd.elections = { priv: keys.priv, pub: keys.pub, }; const successObj = { msg: 'success', result: keys.pub, }; res.end(JSON.stringify(successObj)); } else { const errorObj = { msg: 'error', result: 'unauthorized access', }; res.end(JSON.stringify(errorObj)); } }); shepherd.post('/elections/logout', (req, res, next) => { if (shepherd.checkToken(req.body.token)) { shepherd.elections = {}; const successObj = { msg: 'success', result: true, }; res.end(JSON.stringify(successObj)); } else { const errorObj = { msg: 'error', result: 'unauthorized access', }; res.end(JSON.stringify(errorObj)); } }); shepherd.get('/elections/listtransactions', (req, res, next) => { if (shepherd.checkToken(req.query.token)) { const network = req.query.network || shepherd.findNetworkObj(req.query.coin); const ecl = new shepherd.electrumJSCore(shepherd.electrumServers[network].port, shepherd.electrumServers[network].address, shepherd.electrumServers[network].proto); // tcp or tls const type = req.query.type; const _address = req.query.address; shepherd.log('electrum elections listtransactions ==>', true); const MAX_TX = req.query.maxlength || 10; ecl.connect(); ecl.blockchainAddressGetHistory(_address) .then((json) => { if (json && json.length) { json = shepherd.sortTransactions(json); json = json.length > MAX_TX ? json.slice(0, MAX_TX) : json; let _rawtx = []; shepherd.log(json.length, true); shepherd.Promise.all(json.map((transaction, index) => { return new shepherd.Promise((resolve, reject) => { ecl.blockchainBlockGetHeader(transaction.height) .then((blockInfo) => { if (blockInfo && blockInfo.timestamp) { ecl.blockchainTransactionGet(transaction['tx_hash']) .then((_rawtxJSON) => { shepherd.log('electrum gettransaction ==>', true); shepherd.log((index + ' | ' + (_rawtxJSON.length - 1)), true); shepherd.log(_rawtxJSON, true); // decode tx const _network = shepherd.getNetworkData(network); const decodedTx = shepherd.electrumJSTxDecoder(_rawtxJSON, network, _network); let _res = {}; let _opreturnFound = false; let _region; for (let i = 0; i < decodedTx.outputs.length; i++) { if (decodedTx.outputs[i].scriptPubKey.asm.indexOf('OP_RETURN') > -1) { _opreturnFound = true; _region = shepherd.hex2str(decodedTx.outputs[i].scriptPubKey.hex.substr(4, decodedTx.outputs[i].scriptPubKey.hex.length)); shepherd.log(`found opreturn tag ${_region}`); break; } } if (_opreturnFound) { let _candidate = {}; for (let i = 0; i < decodedTx.outputs.length; i++) { if (type === 'voter' && decodedTx.outputs[i].scriptPubKey.addresses && decodedTx.outputs[i].scriptPubKey.addresses[0] && decodedTx.outputs[i].scriptPubKey.addresses[0] !== _address) { shepherd.log(`i voted ${decodedTx.outputs[i].value} for ${decodedTx.outputs[i].scriptPubKey.addresses[0]}`); _rawtx.push({ address: decodedTx.outputs[i].scriptPubKey.addresses[0], amount: decodedTx.outputs[i].value, region: _region, timestamp: blockInfo.timestamp, }); } if (type === 'candidate') { if (decodedTx.outputs[i].scriptPubKey.addresses[0] === _address) { _candidate.amount = decodedTx.outputs[i].value; } else if (decodedTx.outputs[i].scriptPubKey.addresses[0] !== _address && decodedTx.outputs[i].scriptPubKey.asm.indexOf('OP_RETURN') === -1) { _candidate.address = decodedTx.outputs[i].scriptPubKey.addresses[0]; _candidate.region = _region; _candidate.timestamp = blockInfo.timestamp; } if (i === decodedTx.outputs.length - 1) { shepherd.log(`i received ${_candidate.amount} from ${_candidate.address}`); _rawtx.push(_candidate); } } } } resolve(true); }); } else { resolve(false); } }); }); })) .then(promiseResult => { ecl.close(); const successObj = { msg: 'success', result: _rawtx, }; res.end(JSON.stringify(successObj)); }); } else { const successObj = { msg: 'success', result: [], }; res.end(JSON.stringify(successObj)); } }); } else { const errorObj = { msg: 'error', result: 'unauthorized access', }; res.end(JSON.stringify(errorObj)); } }); return shepherd; }