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.
 
 
 

314 lines
8.7 KiB

const Promise = require('bluebird');
module.exports = (shepherd) => {
/*
* Combined native dashboard update same as in gui
* type: GET
* params: coin
*/
shepherd.post('/native/dashboard/update', (req, res, next) => {
const _coin = req.body.coin;
let _returnObj;
let _promiseStack;
if (_coin === 'CHIPS') {
_returnObj = {
getinfo: {},
listtransactions: [],
getbalance: {},
listunspent: {},
addresses: {},
};
_promiseStack = [
'getinfo',
'listtransactions',
'getbalance',
];
} else {
_returnObj = {
getinfo: {},
listtransactions: [],
z_gettotalbalance: {},
z_getoperationstatus: {},
listunspent: {},
addresses: {},
};
_promiseStack = [
'getinfo',
'listtransactions',
'z_gettotalbalance',
'z_getoperationstatus'
];
}
const getAddressesNative = (coin) => {
const type = [
'public',
'private'
];
if (coin === 'CHIPS') {
type.pop();
}
Promise.all(type.map((_type, index) => {
return new Promise((resolve, reject) => {
_bitcoinRPC(
coin,
_type === 'public' ? 'getaddressesbyaccount' : 'z_listaddresses',
['']
).then((_json) => {
if (_json === 'Work queue depth exceeded' ||
!_json) {
resolve({ error: 'daemon is busy' });
} else {
resolve(JSON.parse(_json).result);
}
});
});
}))
.then(result => {
if (result[0] &&
result[0].length &&
result[0][0].length &&
result[0][0].length > 10) {
const calcBalance = (result, json) => {
if (json &&
json.length &&
json[0] &&
json[0].address) {
const allAddrArray = json.map(res => res.address).filter((x, i, a) => a.indexOf(x) == i);
for (let a = 0; a < allAddrArray.length; a++) {
const filteredArray = json.filter(res => res.address === allAddrArray[a]).map(res => res.amount);
let isNewAddr = true;
for (let x = 0; x < result.length && isNewAddr; x++) {
for (let y = 0; y < result[x].length && isNewAddr; y++) {
if (allAddrArray[a] === result[x][y]) {
isNewAddr = false;
}
}
}
if (isNewAddr &&
(allAddrArray[a].substring(0, 2) === 'zc' ||
allAddrArray[a].substring(0, 2) === 'zt')) {
result[1][result[1].length] = allAddrArray[a];
} else {
result[0][result[0].length] = allAddrArray[a];
}
}
}
// remove addr duplicates
if (result[0] &&
result[0].length) {
result[0] = result[0].filter((elem, pos) => {
return result[0].indexOf(elem) === pos;
});
}
if (result[1] &&
result[1].length) {
result[1] = result[1].filter((elem, pos) => {
return result[1].indexOf(elem) === pos;
});
}
let newAddressArray = [];
for (let a = 0; a < result.length; a++) {
newAddressArray[a] = [];
if (result[a]) {
for (let b = 0; b < result[a].length; b++) {
const filteredArraySpends = json.filter(res => res.address === result[a][b]);
const filteredArray = json.filter(res => res.address === result[a][b]).map(res => res.amount);
let sum = 0;
let spendableSum = 0;
let canspend = true;
for (let i = 0; i < filteredArray.length; i++) {
sum += filteredArray[i];
if (filteredArraySpends[i].spendable) {
spendableSum += filteredArray[i];
} else {
canspend = false;
}
}
newAddressArray[a][b] = {
address: result[a][b],
amount: sum,
spendable: spendableSum,
canspend,
type: a === 0 ? 'public': 'private',
};
}
}
}
// get zaddr balance
if (result[1] &&
result[1].length) {
Promise.all(result[1].map((_address, index) => {
return new Promise((resolve, reject) => {
_bitcoinRPC(coin, 'z_getbalance', [_address])
.then((__json) => {
__json = JSON.parse(__json);
if (__json &&
__json.error) {
resolve(0);
} else {
resolve(__json.result);
newAddressArray[1][index] = {
address: _address,
amount: __json.result,
type: 'private',
};
}
});
});
}))
.then(zresult => {
_returnObj.addresses = {
public: newAddressArray[0],
private: newAddressArray[1],
};
const returnObj = {
msg: 'success',
result: _returnObj,
};
res.end(JSON.stringify(returnObj));
});
} else {
_returnObj.addresses = {
public: newAddressArray[0],
private: newAddressArray[1],
};
const returnObj = {
msg: 'success',
result: _returnObj,
};
res.end(JSON.stringify(returnObj));
}
}
_bitcoinRPC(coin, 'listunspent')
.then((__json) => {
if (__json === 'Work queue depth exceeded' ||
!__json) {
const returnObj = {
msg: 'success',
result: _returnObj,
};
res.end(JSON.stringify(returnObj));
} else {
_returnObj.listunspent = JSON.parse(__json);
calcBalance(
result,
JSON.parse(__json).result
);
}
});
} else {
_returnObj.addresses = {
public: {},
private: {},
};
const returnObj = {
msg: 'success',
result: _returnObj,
};
res.end(JSON.stringify(returnObj));
}
})
}
const _bitcoinRPC = (coin, cmd, params) => {
return new Promise((resolve, reject) => {
let _payload;
if (params) {
_payload = {
mode: null,
chain: coin,
cmd: cmd,
params: params,
rpc2cli: req.body.rpc2cli,
};
} else {
_payload = {
mode: null,
chain: coin,
cmd: cmd,
rpc2cli: req.body.rpc2cli,
};
}
const options = {
url: `http://127.0.0.1:${shepherd.appConfig.agamaPort}/shepherd/cli`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ payload: _payload }),
timeout: 120000,
};
shepherd.request(options, (error, response, body) => {
if (response &&
response.statusCode &&
response.statusCode === 200) {
resolve(body);
} else {
resolve(body);
}
});
});
}
Promise.all(_promiseStack.map((_call, index) => {
let _params;
if (_call === 'listtransactions') {
_params = [
'*',
300,
0
];
}
return new Promise((resolve, reject) => {
_bitcoinRPC(
_coin,
_call,
_params
)
.then((json) => {
if (json === 'Work queue depth exceeded' ||
!json) {
_returnObj[_call] = { error: 'daemon is busy' };
} else {
_returnObj[_call] = JSON.parse(json);
}
resolve(json);
});
});
}))
.then(result => {
getAddressesNative(_coin);
});
});
return shepherd;
};