#!/usr/bin/node "use strict" const Libbfa = require( process.env.BFAHOME + '/bin/libbfa.js'); const rl = require('readline').createInterface( { input: process.stdin, output: process.stdout } ); var web3; var Distillery; var bfa; var notation = [ 6 ]; function init() { notation.push( Math.pow(10, notation[0]) ); switch ( notation[0] ) { case 6: notation.push( "Mwei" ); break; case 9: notation.push( "Gwei" ); break; default: notation = [ 6, Math.pow(10, 6), "Mwei" ]; } bfa = new Libbfa(); web3 = bfa.newweb3(); Distillery = bfa.contract( web3, 'Distillery' ); if ( undefined == Distillery ) fatal('Can not initialise Distillery contact.'); web3.eth.getBalance( Distillery.contractaddress ).then( function receivedOwnBalance(val) { Distillery.contractbalance = val; getlist(); }, function err(x){ bfa.fatal("Can't do that: "+x);process.exit(1); } ); } function palletSort(a,b) { if ( b == undefined ) { if ( a == undefined ) return 0; else return -1; } if ( a == undefined ) return 1; var strA = a[0].toLowerCase(); var strB = b[0].toLowerCase(); if ( strA < strB ) return -1; if ( strA > strB ) return 1; return 0; } function requestBalances( count ) { var pallet = new Array; var proms = new Array; var i; // Fetch addresses from the list in the contract. for ( i=0; i<count; i++ ) { proms.push( Distillery.methods.atPosition(i).call( {} ) .then( function(res) { pallet.push(res); }, function(err) { bfa.fatal("Fetching position data failed: "+err) } ) ); } Promise.all( proms ).then( function(x) { // The Well has now been filled out // so we will ask for the balances of the found accounts var p2 = new Array(); for ( i=0; i<count; i++ ) { var cb = setBal.bind(null,pallet,i); p2.push( web3.eth.getBalance( pallet[i][0] ).then(cb) ); } Promise.all( p2 ).then( function allbalances(a) { displayBalances(pallet) }, function(err) { bfa.fatal("Getting balances failed: "+err) } ); }, function(err) { bfa.fatal("Getting account list failed: "+err) } ); } function setBal( arr, idx, val ) { arr[idx][2]=val; } function editAccount( entry, pallet ) { if ( entry == undefined ) return; var acct; var value; // it is an existing account address? if ( bfa.isAddr(entry) ) { var i = 0; var n = pallet.length; while ( i < n ) { if (String(pallet[i][0]).toLowerCase() == String(entry).toLowerCase() ) entry = i; i++; } } // it is a new account address? if ( bfa.isAddr(entry) ) { acct = entry; value = 0; } else if ( bfa.isNumeric(entry) && entry < pallet.length ) { acct = pallet[entry][0]; value = pallet[entry][1]; } else if ( entry == "x" ) { // trigger distribution Distillery.methods.distribute().send( {"from": bfa.account, "gas": 4000000 } ) .then( function distOK(x) { console.log( "Distribute returned succesfully in block# " + x.blockNumber + " using " + x.gasUsed + " gas." ); getlist(); }, function distFail(x) { bfa.fatal( "Distribute returned errors in block# " + x.blockNumber + " using " + x.gasUsed + " gas." ); console.log(x); process.exit( 1 ); } ); return; } else if ( entry == "" ) { // Do nothing, basically just update the display return; } else { bfa.fatal("I don't know what to do with \""+entry+"\"." ); } rl.question( "Adjust the " + notation[2] + " fill value of " + acct + " (setting to 0 is the same as deleting)\n" + "Amount?: ", (answer) => { if ( bfa.isNumeric(answer) ) { answer *= notation[1]; console.log("Sending update to the SC..."); Distillery.methods.setEtherAllowance(acct,answer) .send( {"from": bfa.account } ) .then( function(a){ console.log("Update accepted.") getlist(); }, function(b){ bfa.fatal( "\nMaybe you are not authorized:\n" +b +"\n\n\nI think you should leave now.\n" ); } ) } else bfa.fatal( "I have no idea what to do with \""+answer+"\"." ); rl.close; } ); } function displayBalances( pallet ) { var n = pallet.length; var i; pallet.sort(palletSort); console.log( "The contract's account (" + Distillery.contractaddress + ") has " + Math.floor(Distillery.contractbalance/notation[1]).toFixed(0) + " " + notation[2] + ".\n" ); var longest = 1; for ( i=0; i<n; i++ ) { var len = (pallet[i][1]/notation[1]).toFixed(notation[0]).length; if ( len > longest ) longest = len; } for ( i=0; i<n; i++ ) { var entry = pallet[i]; if ( entry == undefined ) console.log( i+": <undef>" ); else { var numstr = (pallet[i][1]/notation[1]).toFixed(notation[0]); while ( numstr.length < longest ) numstr = " "+numstr; console.log( i + ": " + pallet[i][0] + " fills to " + numstr + " " + notation[2] + " (has " + Number(pallet[i][2]/notation[1]).toFixed(notation[0]) + ")." ); } } console.log("\n[ Q=quit x=distribute ]"); rl.question("Which account to edit (enter index number of full account number)?: ", (answer) => { if ( answer != undefined ) { if ( String(answer).toUpperCase() == 'Q' ) process.exit( 0 ); else editAccount(answer, pallet); } rl.close; } ) } function getlist() { Distillery.methods.numberOfBeneficiaries() .call() .then( requestBalances, function beneficiaryFail(x){bfa.fatal(x)} ); } init();