You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.7 KiB

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;
}