hufi-cli 0.4.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -4
- package/dist/cli.js +79 -130
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -14,12 +14,12 @@ bun install
|
|
|
14
14
|
# Show help
|
|
15
15
|
bunx hufi-cli --help
|
|
16
16
|
|
|
17
|
-
#
|
|
18
|
-
bunx hufi-cli auth login --private-key 0x...
|
|
19
|
-
|
|
20
|
-
# Generate a new wallet
|
|
17
|
+
# Generate a new wallet (key saved to ~/.hufi-cli/key.json)
|
|
21
18
|
bunx hufi-cli auth generate
|
|
22
19
|
|
|
20
|
+
# Authenticate (uses saved key by default)
|
|
21
|
+
bunx hufi-cli auth login
|
|
22
|
+
|
|
23
23
|
# Check auth status
|
|
24
24
|
bunx hufi-cli auth status
|
|
25
25
|
|
|
@@ -47,6 +47,22 @@ bunx hufi-cli campaign list --limit 20
|
|
|
47
47
|
|
|
48
48
|
Configuration is stored at `~/.hufi-cli/config.json`.
|
|
49
49
|
|
|
50
|
+
## Capabilities
|
|
51
|
+
|
|
52
|
+
### What This CLI Can Do
|
|
53
|
+
|
|
54
|
+
| Module | Commands | Description |
|
|
55
|
+
|--------|----------|-------------|
|
|
56
|
+
| **auth** | login, generate, status | Authentication & wallet management |
|
|
57
|
+
| **exchange** | register, list | Exchange API key management |
|
|
58
|
+
| **campaign** | list, get, joined, join, status, progress, leaderboard | Campaign browsing, joining, and monitoring |
|
|
59
|
+
|
|
60
|
+
### What This CLI Cannot Do
|
|
61
|
+
|
|
62
|
+
- ❌ Execute on-chain transactions
|
|
63
|
+
- ❌ Configure trading strategies
|
|
64
|
+
- ❌ Multi-signature or voting operations
|
|
65
|
+
|
|
50
66
|
## API Endpoints
|
|
51
67
|
|
|
52
68
|
- Recording Oracle: `https://ro.hu.finance`
|
package/dist/cli.js
CHANGED
|
@@ -9339,7 +9339,22 @@ import { homedir } from "node:os";
|
|
|
9339
9339
|
import { join } from "node:path";
|
|
9340
9340
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
9341
9341
|
var CONFIG_DIR = join(homedir(), ".hufi-cli");
|
|
9342
|
-
var
|
|
9342
|
+
var DEFAULT_CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
9343
|
+
var DEFAULT_KEY_FILE = join(CONFIG_DIR, "key.json");
|
|
9344
|
+
var customConfigFile = null;
|
|
9345
|
+
var customKeyFile = null;
|
|
9346
|
+
function setConfigFile(path) {
|
|
9347
|
+
customConfigFile = path;
|
|
9348
|
+
}
|
|
9349
|
+
function setKeyFile(path) {
|
|
9350
|
+
customKeyFile = path;
|
|
9351
|
+
}
|
|
9352
|
+
function configFile() {
|
|
9353
|
+
return customConfigFile ?? DEFAULT_CONFIG_FILE;
|
|
9354
|
+
}
|
|
9355
|
+
function keyFile() {
|
|
9356
|
+
return customKeyFile ?? DEFAULT_KEY_FILE;
|
|
9357
|
+
}
|
|
9343
9358
|
var DEFAULT_CONFIG = {
|
|
9344
9359
|
recordingApiUrl: "https://ro.hu.finance",
|
|
9345
9360
|
launcherApiUrl: "https://cl.hu.finance"
|
|
@@ -9351,11 +9366,11 @@ function ensureConfigDir() {
|
|
|
9351
9366
|
}
|
|
9352
9367
|
function loadConfig() {
|
|
9353
9368
|
ensureConfigDir();
|
|
9354
|
-
if (!existsSync(
|
|
9369
|
+
if (!existsSync(configFile())) {
|
|
9355
9370
|
return { ...DEFAULT_CONFIG };
|
|
9356
9371
|
}
|
|
9357
9372
|
try {
|
|
9358
|
-
const raw = readFileSync(
|
|
9373
|
+
const raw = readFileSync(configFile(), "utf-8");
|
|
9359
9374
|
const parsed = JSON.parse(raw);
|
|
9360
9375
|
return { ...DEFAULT_CONFIG, ...parsed };
|
|
9361
9376
|
} catch {
|
|
@@ -9364,7 +9379,7 @@ function loadConfig() {
|
|
|
9364
9379
|
}
|
|
9365
9380
|
function saveConfig(config) {
|
|
9366
9381
|
ensureConfigDir();
|
|
9367
|
-
writeFileSync(
|
|
9382
|
+
writeFileSync(configFile(), JSON.stringify(config, null, 2) + `
|
|
9368
9383
|
`);
|
|
9369
9384
|
}
|
|
9370
9385
|
function updateConfig(partial) {
|
|
@@ -9373,6 +9388,30 @@ function updateConfig(partial) {
|
|
|
9373
9388
|
saveConfig(merged);
|
|
9374
9389
|
return merged;
|
|
9375
9390
|
}
|
|
9391
|
+
function getConfigPath() {
|
|
9392
|
+
return configFile();
|
|
9393
|
+
}
|
|
9394
|
+
function getKeyPath() {
|
|
9395
|
+
return keyFile();
|
|
9396
|
+
}
|
|
9397
|
+
function keyExists() {
|
|
9398
|
+
return existsSync(keyFile());
|
|
9399
|
+
}
|
|
9400
|
+
function saveKey(key, address) {
|
|
9401
|
+
ensureConfigDir();
|
|
9402
|
+
writeFileSync(keyFile(), JSON.stringify({ address, privateKey: key }, null, 2) + `
|
|
9403
|
+
`);
|
|
9404
|
+
}
|
|
9405
|
+
function loadKey() {
|
|
9406
|
+
if (!existsSync(keyFile()))
|
|
9407
|
+
return null;
|
|
9408
|
+
try {
|
|
9409
|
+
const raw = readFileSync(keyFile(), "utf-8");
|
|
9410
|
+
return JSON.parse(raw).privateKey ?? null;
|
|
9411
|
+
} catch {
|
|
9412
|
+
return null;
|
|
9413
|
+
}
|
|
9414
|
+
}
|
|
9376
9415
|
|
|
9377
9416
|
// src/lib/output.ts
|
|
9378
9417
|
function printJson(data) {
|
|
@@ -9392,11 +9431,16 @@ function maskSecret(value) {
|
|
|
9392
9431
|
// src/commands/auth.ts
|
|
9393
9432
|
function createAuthCommand() {
|
|
9394
9433
|
const auth = new Command("auth").description("Authentication commands");
|
|
9395
|
-
auth.command("login").description("Authenticate with Recording Oracle using a private key").
|
|
9434
|
+
auth.command("login").description("Authenticate with Recording Oracle using a private key").option("-k, --private-key <key>", "EVM private key (uses saved key if not provided)").option("-u, --api-url <url>", "Recording Oracle API URL").option("--json", "Output as JSON").action(async (opts) => {
|
|
9435
|
+
const privateKey = opts.privateKey ?? loadKey();
|
|
9436
|
+
if (!privateKey) {
|
|
9437
|
+
printText("No private key provided. Run: hufi auth login -k <key> or hufi auth generate");
|
|
9438
|
+
process.exit(1);
|
|
9439
|
+
}
|
|
9396
9440
|
const config = loadConfig();
|
|
9397
9441
|
const baseUrl = (opts.apiUrl ?? config.recordingApiUrl).replace(/\/+$/, "");
|
|
9398
9442
|
try {
|
|
9399
|
-
const result = await authenticate(baseUrl,
|
|
9443
|
+
const result = await authenticate(baseUrl, privateKey);
|
|
9400
9444
|
updateConfig({
|
|
9401
9445
|
recordingApiUrl: baseUrl,
|
|
9402
9446
|
address: result.address,
|
|
@@ -9407,7 +9451,7 @@ function createAuthCommand() {
|
|
|
9407
9451
|
printJson({ address: result.address, accessToken: result.accessToken });
|
|
9408
9452
|
} else {
|
|
9409
9453
|
printText(`Authenticated as ${result.address}`);
|
|
9410
|
-
printText(`Token saved to
|
|
9454
|
+
printText(`Token saved to ${getConfigPath()}`);
|
|
9411
9455
|
}
|
|
9412
9456
|
} catch (err) {
|
|
9413
9457
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -9415,13 +9459,31 @@ function createAuthCommand() {
|
|
|
9415
9459
|
process.exitCode = 1;
|
|
9416
9460
|
}
|
|
9417
9461
|
});
|
|
9418
|
-
auth.command("generate").description("Generate a new EVM wallet").option("--json", "Output as JSON").action((opts) => {
|
|
9462
|
+
auth.command("generate").description("Generate a new EVM wallet").option("--json", "Output as JSON").action(async (opts) => {
|
|
9463
|
+
if (keyExists()) {
|
|
9464
|
+
if (!opts.json) {
|
|
9465
|
+
printText(`Key already exists at ${getKeyPath()}. Overwrite? (y/N)`);
|
|
9466
|
+
const answer = await new Promise((resolve) => {
|
|
9467
|
+
process.stdin.resume();
|
|
9468
|
+
process.stdin.once("data", (data) => {
|
|
9469
|
+
process.stdin.pause();
|
|
9470
|
+
resolve(data.toString().trim().toLowerCase());
|
|
9471
|
+
});
|
|
9472
|
+
});
|
|
9473
|
+
if (answer !== "y") {
|
|
9474
|
+
printText("Cancelled.");
|
|
9475
|
+
return;
|
|
9476
|
+
}
|
|
9477
|
+
}
|
|
9478
|
+
}
|
|
9419
9479
|
const wallet = createWallet();
|
|
9480
|
+
saveKey(wallet.privateKey, wallet.address);
|
|
9481
|
+
const keyPath = getKeyPath();
|
|
9420
9482
|
if (opts.json) {
|
|
9421
|
-
printJson(wallet);
|
|
9483
|
+
printJson({ address: wallet.address, keyPath });
|
|
9422
9484
|
} else {
|
|
9423
9485
|
printText(`Address: ${wallet.address}`);
|
|
9424
|
-
printText(`Private key
|
|
9486
|
+
printText(`Private key saved to ${keyPath}`);
|
|
9425
9487
|
}
|
|
9426
9488
|
});
|
|
9427
9489
|
auth.command("status").description("Show current authentication status").option("--json", "Output as JSON").action((opts) => {
|
|
@@ -9781,127 +9843,14 @@ function createCampaignCommand() {
|
|
|
9781
9843
|
}
|
|
9782
9844
|
|
|
9783
9845
|
// src/cli.ts
|
|
9784
|
-
var BASH_COMPLETION = [
|
|
9785
|
-
"_hufi_completions() {",
|
|
9786
|
-
" local cur prev commands",
|
|
9787
|
-
" COMPREPLY=()",
|
|
9788
|
-
' cur="${COMP_WORDS[COMP_CWORD]}"',
|
|
9789
|
-
' prev="${COMP_WORDS[COMP_CWORD-1]}"',
|
|
9790
|
-
"",
|
|
9791
|
-
' commands="auth exchange campaign completion help"',
|
|
9792
|
-
"",
|
|
9793
|
-
' case "$prev" in',
|
|
9794
|
-
" hufi)",
|
|
9795
|
-
' COMPREPLY=( $(compgen -W "$commands" -- "$cur") )',
|
|
9796
|
-
" return 0",
|
|
9797
|
-
" ;;",
|
|
9798
|
-
" auth)",
|
|
9799
|
-
' COMPREPLY=( $(compgen -W "login generate status help" -- "$cur") )',
|
|
9800
|
-
" return 0",
|
|
9801
|
-
" ;;",
|
|
9802
|
-
" exchange)",
|
|
9803
|
-
' COMPREPLY=( $(compgen -W "register list help" -- "$cur") )',
|
|
9804
|
-
" return 0",
|
|
9805
|
-
" ;;",
|
|
9806
|
-
" campaign)",
|
|
9807
|
-
' COMPREPLY=( $(compgen -W "list get joined status join progress leaderboard help" -- "$cur") )',
|
|
9808
|
-
" return 0",
|
|
9809
|
-
" ;;",
|
|
9810
|
-
" esac",
|
|
9811
|
-
"",
|
|
9812
|
-
' COMPREPLY=( $(compgen -W "--help --version --json" -- "$cur") )',
|
|
9813
|
-
" return 0",
|
|
9814
|
-
"}",
|
|
9815
|
-
"",
|
|
9816
|
-
"complete -F _hufi_completions hufi"
|
|
9817
|
-
].join(`
|
|
9818
|
-
`);
|
|
9819
|
-
var ZSH_COMPLETION = [
|
|
9820
|
-
"#compdef hufi",
|
|
9821
|
-
"",
|
|
9822
|
-
"_hufi() {",
|
|
9823
|
-
" local -a commands",
|
|
9824
|
-
" commands=(",
|
|
9825
|
-
" 'auth:Authentication commands'",
|
|
9826
|
-
" 'exchange:Exchange API key management'",
|
|
9827
|
-
" 'campaign:Campaign management'",
|
|
9828
|
-
" 'completion:Generate shell completion script'",
|
|
9829
|
-
" 'help:Display help'",
|
|
9830
|
-
" )",
|
|
9831
|
-
"",
|
|
9832
|
-
" _arguments -C \\",
|
|
9833
|
-
" '1:command:->command' \\",
|
|
9834
|
-
" '*::arg:->args'",
|
|
9835
|
-
"",
|
|
9836
|
-
" case $state in",
|
|
9837
|
-
" command)",
|
|
9838
|
-
" _describe 'command' commands",
|
|
9839
|
-
" ;;",
|
|
9840
|
-
" args)",
|
|
9841
|
-
" case ${words[1]} in",
|
|
9842
|
-
" auth)",
|
|
9843
|
-
" _arguments \\",
|
|
9844
|
-
" '1:subcommand:(login generate status help)'",
|
|
9845
|
-
" ;;",
|
|
9846
|
-
" exchange)",
|
|
9847
|
-
" _arguments \\",
|
|
9848
|
-
" '1:subcommand:(register list help)'",
|
|
9849
|
-
" ;;",
|
|
9850
|
-
" campaign)",
|
|
9851
|
-
" _arguments \\",
|
|
9852
|
-
" '1:subcommand:(list get joined status join progress leaderboard help)'",
|
|
9853
|
-
" ;;",
|
|
9854
|
-
" esac",
|
|
9855
|
-
" ;;",
|
|
9856
|
-
" esac",
|
|
9857
|
-
"}",
|
|
9858
|
-
"",
|
|
9859
|
-
'_hufi "$@"'
|
|
9860
|
-
].join(`
|
|
9861
|
-
`);
|
|
9862
|
-
var FISH_COMPLETION = [
|
|
9863
|
-
"# hufi completions for fish",
|
|
9864
|
-
"complete -c hufi -f",
|
|
9865
|
-
"",
|
|
9866
|
-
"# Top-level commands",
|
|
9867
|
-
"complete -c hufi -n '__fish_use_subcommand' -a auth -d 'Authentication commands'",
|
|
9868
|
-
"complete -c hufi -n '__fish_use_subcommand' -a exchange -d 'Exchange API key management'",
|
|
9869
|
-
"complete -c hufi -n '__fish_use_subcommand' -a campaign -d 'Campaign management'",
|
|
9870
|
-
"complete -c hufi -n '__fish_use_subcommand' -a completion -d 'Generate shell completion script'",
|
|
9871
|
-
"",
|
|
9872
|
-
"# auth subcommands",
|
|
9873
|
-
"complete -c hufi -n '__fish_seen_subcommand_from auth' -a login -d 'Authenticate with private key'",
|
|
9874
|
-
"complete -c hufi -n '__fish_seen_subcommand_from auth' -a generate -d 'Generate a new wallet'",
|
|
9875
|
-
"complete -c hufi -n '__fish_seen_subcommand_from auth' -a status -d 'Show auth status'",
|
|
9876
|
-
"",
|
|
9877
|
-
"# exchange subcommands",
|
|
9878
|
-
"complete -c hufi -n '__fish_seen_subcommand_from exchange' -a register -d 'Register exchange API key'",
|
|
9879
|
-
"complete -c hufi -n '__fish_seen_subcommand_from exchange' -a list -d 'List exchange API keys'",
|
|
9880
|
-
"",
|
|
9881
|
-
"# campaign subcommands",
|
|
9882
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a list -d 'List available campaigns'",
|
|
9883
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a get -d 'Get campaign details'",
|
|
9884
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a joined -d 'List joined campaigns'",
|
|
9885
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a status -d 'Check join status'",
|
|
9886
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a join -d 'Join a campaign'",
|
|
9887
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a progress -d 'Check your progress'",
|
|
9888
|
-
"complete -c hufi -n '__fish_seen_subcommand_from campaign' -a leaderboard -d 'View leaderboard'",
|
|
9889
|
-
"",
|
|
9890
|
-
"# Global options",
|
|
9891
|
-
"complete -c hufi -l help -d 'Show help'",
|
|
9892
|
-
"complete -c hufi -l version -d 'Show version'",
|
|
9893
|
-
"complete -c hufi -l json -d 'Output as JSON'"
|
|
9894
|
-
].join(`
|
|
9895
|
-
`);
|
|
9896
9846
|
var program2 = new Command;
|
|
9897
|
-
program2.name("hufi").description("CLI tool for hu.fi DeFi platform").version("0.
|
|
9898
|
-
|
|
9899
|
-
if (opts.
|
|
9900
|
-
|
|
9901
|
-
}
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
console.log(BASH_COMPLETION);
|
|
9847
|
+
program2.name("hufi").description("CLI tool for hu.fi DeFi platform").version("0.5.2").option("--config-file <path>", "Custom config file path (default: ~/.hufi-cli/config.json)").option("--key-file <path>", "Custom key file path (default: ~/.hufi-cli/key.json)").hook("preAction", (thisCommand) => {
|
|
9848
|
+
const opts = thisCommand.opts();
|
|
9849
|
+
if (opts.configFile) {
|
|
9850
|
+
setConfigFile(opts.configFile);
|
|
9851
|
+
}
|
|
9852
|
+
if (opts.keyFile) {
|
|
9853
|
+
setKeyFile(opts.keyFile);
|
|
9905
9854
|
}
|
|
9906
9855
|
});
|
|
9907
9856
|
program2.addCommand(createAuthCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hufi-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"hufi": "./dist/cli.js"
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"build": "bun build ./src/cli.ts --outfile ./dist/cli.js --target node",
|
|
11
11
|
"prepublishOnly": "bun run build",
|
|
12
12
|
"test": "bun test",
|
|
13
|
-
"typecheck": "bunx tsc --noEmit"
|
|
13
|
+
"typecheck": "bunx tsc --noEmit",
|
|
14
|
+
"test:cli": "./test-cli.sh"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"commander": "^12.0.0",
|