let shadowPath = Path.join(HOME, `${configdir}/shadow`);
let defaultWifPath = Path.join(HOME, `${configdir}/default`);
+function debug() {
+ //@ts-ignore
+ console.error.apply(console, arguments);
+}
+
function showVersion() {
console.info(`${pkg.name} v${pkg.version} - ${pkg.description}`);
console.info();
" crowdnode http SetReferral ./privkey.wif <referral-id> <signature>",
);
console.info("");
+ console.info("Official CrowdNode Resources");
+ console.info("");
+ console.info("Homepage:");
+ console.info(" https://crowdnode.io/");
+ console.info("");
+ console.info("Terms of Service:");
+ console.info(" https://crowdnode.io/terms/");
+ console.info("");
+ console.info("BlockChain API Guide:");
+ console.info(
+ " https://knowledge.crowdnode.io/en/articles/5963880-blockchain-api-guide",
+ );
+ console.info("");
}
let cmds = {};
}
if ("list" === subcommand) {
- await listKeys({ dashApi }, args);
+ await listKeys({ dashApi, defaultAddr }, args);
process.exit(0);
return;
}
}
if ("import" === subcommand) {
- await importKey(null, args);
+ let keypath = args.shift() || "";
+ await importKey({ keypath });
process.exit(0);
return;
}
// keeping rm for backwards compat
if ("rm" === subcommand || "delete" === subcommand) {
await initCrowdNode(insightBaseUrl);
- await removeKey({ defaultAddr, dashApi, insightBaseUrl }, args);
+ let [addr, filepath] = await mustGetAddr({ defaultAddr }, args);
+ await removeKey({ addr, dashApi, filepath, insightBaseUrl }, args);
process.exit(0);
return;
}
if ("balance" === subcommand) {
- await getBalance({ dashApi, defaultAddr }, args);
+ if (args.length) {
+ await getBalance({ dashApi, defaultAddr }, args);
+ process.exit(0);
+ return;
+ }
+
+ await getAllBalances({ dashApi, defaultAddr }, args);
process.exit(0);
return;
}
let err = await Fs.access(args[0]).catch(Object);
let addr;
if (!err) {
- addr = await importKey(null, [args[0]]);
+ let keypath = args.shift() || "";
+ addr = await importKey({ keypath });
} else if (forceGenerate) {
addr = await generateKey({ defaultKey: defaultAddr }, []);
} else {
if (!state.status?.accept) {
if (!state.status?.signup) {
- await sendSignup({ dashApi, defaultAddr: addr, insightBaseUrl }, []);
+ await sendSignup({ dashApi, defaultAddr: addr, insightBaseUrl }, [addr]);
}
- await acceptTerms({ dashApi, defaultAddr: addr, insightBaseUrl }, []);
+ await acceptTerms({ dashApi, defaultAddr: addr, insightBaseUrl }, [addr]);
}
await depositDash(
{ dashApi, defaultAddr: addr, insightBaseUrl, noReserve },
- args,
+ [addr].concat(args),
);
}
}
if (defaultWif && !shownDefault) {
shownDefault = true;
- console.info(`Selected default staking key ${defaultAddr}`);
+ debug(`Selected default staking key ${defaultAddr}`);
return defaultWif;
}
/**
* Import and Encrypt
- * @param {Null} _
- * @param {Array<String>} args
+ * @param {Object} opts
+ * @param {String} opts.keypath
*/
-async function importKey(_, args) {
- let keypath = args.shift() || "";
+async function importKey({ keypath }) {
let key = await maybeReadKeyFileRaw(keypath);
if (!key?.wif) {
console.error(`no key found for '${keypath}'`);
/**
* @param {Object} opts
* @param {any} opts.dashApi - TODO
+ * @param {String} opts.defaultAddr
* @param {Array<String>} args
*/
-async function listKeys({ dashApi }, args) {
+async function listKeys({ dashApi, defaultAddr }, args) {
let wifnames = await listManagedKeynames();
+ if (wifnames) {
+ // to print 'default staking key' message
+ await mustGetAddr({ defaultAddr }, args);
+ }
+
/**
* @type Array<{ node: String, error: Error }>
*/
let warns = [];
- console.info(``);
- console.info(`🔑Holdings 🪧 Stakings 💸Earnings`);
- console.info(``);
- console.info(`Staking keys: (in ${keysDirRel}/)`);
- console.info(``);
+ // console.error because console.debug goes to stdout, not stderr
+ debug(``);
+ debug(`Staking keys: (in ${keysDirRel}/)`);
+ debug(``);
+
+ await wifnames.reduce(async function (promise, wifname) {
+ await promise;
+
+ let wifpath = Path.join(keysDir, wifname);
+ let addr = await maybeReadKeyFile(wifpath, { wif: false }).catch(function (
+ err,
+ ) {
+ warns.push({ node: wifname, error: err });
+ return "";
+ });
+ if (!addr) {
+ return;
+ }
+
+ console.info(`${addr}`);
+ }, Promise.resolve());
+ debug(``);
+
+ if (warns.length) {
+ console.warn(`Warnings:`);
+ warns.forEach(function (warn) {
+ console.warn(`${warn.node}: ${warn.error.message}`);
+ });
+ console.warn(``);
+ }
+}
+
+/**
+ * @param {Object} opts
+ * @param {any} opts.dashApi - TODO
+ * @param {String} opts.defaultAddr
+ * @param {Array<String>} args
+ */
+async function getAllBalances({ dashApi, defaultAddr }, args) {
+ let wifnames = await listManagedKeynames();
+ let totals = {
+ key: 0,
+ stake: 0,
+ dividend: 0,
+ keyDash: "",
+ stakeDash: "",
+ dividendDash: "",
+ };
+
+ if (wifnames.length) {
+ // to print 'default staking key' message
+ await mustGetAddr({ defaultAddr }, args);
+ }
+
+ /**
+ * @type Array<{ node: String, error: Error }>
+ */
+ let warns = [];
+ // console.error because console.debug goes to stdout, not stderr
+ debug(``);
+ debug(`Staking keys: (in ${keysDirRel}/)`);
+ debug(``);
+ console.info(
+ `| | 🔑 Holdings | 🪧 Stakings | 💸 Earnings |`,
+ );
+ console.info(
+ `| ---------------------------------: | ------------: | ------------: | ------------: |`,
+ );
if (!wifnames.length) {
console.info(` (none)`);
}
}
*/
- process.stdout.write(`${addr}: `);
+ process.stdout.write(`| ${addr} |`);
let balanceInfo = await dashApi.getInstantBalance(addr);
let balanceDASH = toDASH(balanceInfo.balanceSat);
let crowdNodeDivNum = toDuff(crowdNodeBalance.TotalDividend);
let crowdNodeDivDASH = toDASH(crowdNodeDivNum);
process.stdout.write(
- `${balanceDASH}🔑 ${crowdNodeDASH}🪧 ${crowdNodeDivDASH}💸`,
+ ` ${balanceDASH} | ${crowdNodeDASH} | ${crowdNodeDivDASH} |`,
);
+ totals.key += balanceInfo.balanceSat;
+ totals.dividend += crowdNodeBalance.TotalDividend;
+ totals.stake += crowdNodeBalance.TotalBalance;
+
console.info();
}, Promise.resolve());
- console.info(``);
+ console.info(
+ `| | | | |`,
+ );
+ let total = `| Totals`;
+ totals.keyDash = toDASH(toDuff(totals.key.toString()));
+ totals.stakeDash = toDASH(toDuff(totals.stake.toString()));
+ totals.dividendDash = toDASH(toDuff(totals.dividend.toString()));
+ console.info(
+ `${total} | ${totals.stakeDash} | ${totals.stakeDash} | ${totals.dividendDash} |`,
+ );
+ debug(``);
if (warns.length) {
console.warn(`Warnings:`);
/**
* @param {Object} opts
* @param {any} opts.dashApi - TODO
- * @param {String} opts.defaultAddr
+ * @param {String} opts.addr
+ * @param {String} opts.filepath
* @param {String} opts.insightBaseUrl
* @param {Array<String>} args
*/
-async function removeKey({ dashApi, defaultAddr, insightBaseUrl }, args) {
- let [addr, name] = await mustGetAddr({ defaultAddr }, args);
+async function removeKey({ addr, dashApi, filepath, insightBaseUrl }, args) {
let balanceInfo = await dashApi.getInstantBalance(addr);
let balanceDash = toDash(balanceInfo.balanceSat);
}
let wifname = await findWif(addr);
- let filepath = Path.join(keysDir, wifname);
- let wif = await maybeReadKeyPaths(name, { wif: true });
+ let fullpath = Path.join(keysDir, wifname);
+ let wif = await maybeReadKeyPaths(filepath, { wif: true });
- await Fs.unlink(filepath).catch(function (err) {
+ await Fs.unlink(fullpath).catch(function (err) {
console.error(`could not remove ${filepath}: ${err.message}`);
process.exit(1);
});
console.info(``);
} else {
let newAddr = wifnames[0];
- console.info(`Selected ${newAddr} as new default staking key.`);
+ debug(`Selected ${newAddr} as new default staking key.`);
await Fs.writeFile(defaultWifPath, addr.replace(".wif", ""), "utf8");
console.info(``);
}
}
let realPercentStr = (permil / 10).toFixed(1);
- console.info(`Initiating withdrawal of ${realPercentStr}...`);
+ console.info(`Initiating withdrawal of ${realPercentStr}%...`);
let wifname = await findWif(addr);
let filepath = Path.join(keysDir, wifname);
*/
function toDASH(duffs) {
let dash = (duffs / DUFFS).toFixed(8);
- return `Đ${dash}`.padStart(13, " ");
+ return `Đ` + dash.padStart(12, " ");
}
/**