Skip to content

Commit

Permalink
Add cli
Browse files Browse the repository at this point in the history
  • Loading branch information
ronanyeah committed May 12, 2024
1 parent b9af661 commit 1fb432c
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 0 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/pack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: CLI publish

on:
push:
tags:
- "v*"

permissions:
contents: write
actions: write
packages: write

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install dependencies
run: npm install

- name: Build project
run: npm run build:cli

- name: Zip files [linux]
run: zip -j cli/linux.zip cli/mineral-linux cli/README.md

- name: Zip files [win]
run: zip -j cli/windows.zip cli/mineral-win.exe cli/README.md

- name: Zip files [macos]
run: zip -j cli/macos.zip cli/mineral-macos cli/README.md

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: Upload Release Asset [win]
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./cli/windows.zip
asset_name: windows.zip
asset_content_type: application/zip

- name: Upload Release Asset [linux]
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./cli/linux.zip
asset_name: linux.zip
asset_content_type: application/zip

- name: Upload Release Asset [macos]
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./cli/macos.zip
asset_name: macos.zip
asset_content_type: application/zip
176 changes: 176 additions & 0 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* eslint-disable fp/no-loops, fp/no-mutation, fp/no-mutating-methods, fp/no-let, no-constant-condition */

import { program } from "commander";
import {
getProof,
formatBig,
runner,
getOrCreateMiner,
fetchBus,
CONFIG,
} from "../common";
import { Config, MINE } from "../codegen/mineral/mine/structs";
import { Miner } from "../codegen/mineral/miner/structs";
import { decodeSuiPrivateKey } from "@mysten/sui.js/cryptography";
import { SuiClient, getFullnodeUrl } from "@mysten/sui.js/client";
import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519";
import { SUI_TYPE_ARG, SUI_DECIMALS } from "@mysten/sui.js/utils";
import chalk from "chalk";

const { WALLET, RPC } = process.env;

const START_TIME = 1715534935000;
const USAGE_GUIDE =
"https://github.com/ronanyeah/mineral-app/blob/master/cli/README.md";
const SETUP_PROMPT =
"Wallet not found. Consult the setup guide: " + USAGE_GUIDE;

const settings = (() => {
return {
wallet: (() => {
if (!WALLET) {
return null;
}
return Ed25519Keypair.fromSecretKey(
decodeSuiPrivateKey(WALLET).secretKey
);
})(),
rpc: new SuiClient({
url: RPC || getFullnodeUrl("mainnet"),
}),
};
})();

program
.name("mineral")
.description("Mineral CLI Miner\nhttps://mineral.supply/")
.version("1.0.0");

program
.command("profile")
.description("View your mining stats")
.action((_options) =>
(async () => {
if (!settings.wallet) {
return program.error(SETUP_PROMPT);
}
const pub = settings.wallet.toSuiAddress();
console.log(chalk.green("Wallet:"), pub);
const minerAcct = await getProof(settings.rpc, pub);
if (minerAcct) {
console.log(chalk.green("Miner:"), minerAcct);
}
const results = await Promise.all([
(async () => {
const bal = await settings.rpc.getBalance({
owner: pub,
coinType: SUI_TYPE_ARG,
});
const val = formatBig(BigInt(bal.totalBalance), SUI_DECIMALS);
return [`💧 Sui Balance: ${val} SUI`];
})(),
(async () => {
const bal = await settings.rpc.getBalance({
owner: pub,
coinType: MINE.$typeName,
});
const val = formatBig(BigInt(bal.totalBalance), SUI_DECIMALS);
return [`⛏️ Mineral Balance: ${val} $MINE`];
})(),
(async () => {
const proof = await getProof(settings.rpc, pub);
if (!proof) {
return [];
}
const miner = await Miner.fetch(settings.rpc, proof);
return [
`💰 Lifetime rewards: ${formatBig(miner.totalRewards, 9)} $MINE`,
`🏭 Lifetime hashes: ${miner.totalHashes}`,
];
})(),
]);
results.flat().forEach((val) => console.log(val));
})().catch(console.error)
);

program
.command("stats")
.description("View global Mineral stats")
.action((_options) =>
(async () => {
const config = await Config.fetch(settings.rpc, CONFIG);
const bus = await fetchBus(settings.rpc);
console.log(
"Total distributed rewards:",
Number(config.totalRewards) / 1_000_000_000,
"$MINE"
);
console.log("Total hashes processed:", Number(config.totalHashes));
console.log(
"Current reward rate:",
Number(bus.rewardRate) / 1_000_000_000,
"$MINE / hash"
);
console.log("Current difficulty:", bus.difficulty);
})().catch(console.error)
);

program
.command("create-wallet")
.description("Create a new Sui wallet")
.action(async (_options) => {
const wallet = new Ed25519Keypair();
console.log(chalk.green("Wallet created:"), wallet.toSuiAddress());
console.log(chalk.red("Private key:"), wallet.getSecretKey());
console.log(chalk.blue("Mineral CLI usage guide:"), USAGE_GUIDE);
});

program
.command("mine")
.description("Start mining ⛏️")
.action((_options) =>
(async () => {
if (!settings.wallet) {
return program.error(SETUP_PROMPT);
}
const bal = await settings.rpc.getBalance({
owner: settings.wallet.toSuiAddress(),
coinType: SUI_TYPE_ARG,
});
if (Number(bal.totalBalance) < 0.1) {
console.log(
chalk.red("Low balance"),
"in wallet",
settings.wallet.toSuiAddress()
);
console.log("Send some SUI to this wallet to enable mining.");
}

if (Date.now() < START_TIME) {
return program.error("⚠️ Mining has not started yet!");
}

console.error(
chalk.green("Mining with wallet:"),
settings.wallet.toSuiAddress()
);
const minerAccount = await getOrCreateMiner(
settings.wallet,
settings.rpc
);
const bus = await fetchBus(settings.rpc);

if (!minerAccount) {
return program.error("Miner account not created!");
}
runner(
settings.rpc,
bus.difficulty,
settings.wallet,
minerAccount,
console.log
);
})().catch(console.error)
);

program.parse(process.argv);
31 changes: 31 additions & 0 deletions webpack.cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const webpack = require("webpack");
const { resolve } = require("path");

const outFolder = resolve("./cli");

module.exports = {
target: "node",
mode: "production",
entry: "./src/cli/index.ts",
output: {
filename: "index.js",
path: outFolder,
},
stats: "normal",
infrastructureLogging: {
level: "warn",
},
module: {
rules: [
{
test: /\.ts$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".ts", ".js"],
},
plugins: [new webpack.NoEmitOnErrorsPlugin()],
};

0 comments on commit 1fb432c

Please sign in to comment.