mirror of https://github.com/lukechilds/Agama.git
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
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;
|
|
};
|