naracli 1.0.74 → 1.0.76

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naracli",
3
- "version": "1.0.74",
3
+ "version": "1.0.76",
4
4
  "description": "CLI for the Nara chain (Solana-compatible)",
5
5
  "homepage": "https://nara.build",
6
6
  "repository": {
@@ -33,6 +33,7 @@
33
33
  "files": [
34
34
  "dist",
35
35
  "src",
36
+ "skills",
36
37
  "index.ts",
37
38
  "bin"
38
39
  ],
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: nara
3
+ description: "Nara chain CLI agent — free PoMI mining, wallet, transfer, quest, on-chain skills, ZK ID, agent registry. Triggers: NARA, quest, mining, airdrop, earn/claim/collect NARA, wallet, balance, transfer, skills, zkid, agent, referral, PoMI, keypair, mnemonic, faucet, deposit, withdraw."
4
+ metadata:
5
+ requires: "node>=18, npm"
6
+ package: "naracli"
7
+ homepage: "https://nara.build"
8
+ repository: "https://github.com/nara-chain/nara-cli"
9
+ ---
10
+
11
+ ## Prerequisites
12
+
13
+ - **Requires**: Node.js (>=18) and npm
14
+ - **Package**: `naracli` on npm — [npmjs.com/package/naracli](https://www.npmjs.com/package/naracli), source: [github.com/nara-chain/nara-cli](https://github.com/nara-chain/nara-cli), homepage: [nara.build](https://nara.build)
15
+ - **Install**: `npm install -g naracli` (or use `npx naracli <command>`). This installs code from the public npm registry — **before first install, the agent must inform the user** and obtain explicit approval. Users should review: [npm package](https://www.npmjs.com/package/naracli), [GitHub source](https://github.com/nara-chain/nara-cli)
16
+ - **Security**: Open-source, auditable on GitHub. The package does not upload, collect, or transmit wallet secrets — all key material stays local on disk
17
+ - Run `npx naracli help` and `npx naracli <command> --help` to learn all available commands and options before use
18
+ - **Updates**: Use `npx naracli@latest` to ensure the latest CLI version
19
+
20
+ ## Getting Started
21
+
22
+ First run `npx naracli address` to check if a wallet exists. If not, create one with `npx naracli wallet create`. Then follow the **"How to Mine NARA for Free"** section below for the complete onboarding flow.
23
+
24
+ ## Agent Autonomy Rules
25
+
26
+ All CLI commands execute locally-installed `naracli` (open-source, auditable at github.com/nara-chain/nara-cli). The agent must obtain **explicit user confirmation** before:
27
+
28
+ **Always ask user before:**
29
+ - Installing or first running the naracli package (inform user it executes code from npm registry)
30
+ - Running any CLI command for the first time in a session
31
+ - Creating or importing wallets
32
+ - Transfers, token transfers, signing transactions
33
+ - Uploading files on-chain (skills upload, agent upload-memory)
34
+ - Deleting on-chain resources
35
+ - Changing RPC endpoint or relay URL to non-default values
36
+
37
+ **Credential safety:**
38
+ - **NEVER** accept, display, or log mnemonics, private keys, or wallet file contents in conversation
39
+ - If a user pastes a mnemonic or private key, warn them immediately and do NOT store or repeat it
40
+ - Wallet creation and import are handled entirely by the CLI — the agent should only run the command, not process secrets
41
+ - When running wallet create/import commands, do NOT capture or parse CLI stdout/stderr — only confirm success or report the error message. The CLI writes key material directly to a file, never to stdout
42
+ - Only use default RPC/relay endpoints (shown in `npx naracli quest answer --help`); warn if the user provides a custom URL
43
+
44
+ **Safe to run without confirmation:**
45
+ - Read-only queries (address, balance, quest get, skills get, agent get, config get, zkid info, tx-status)
46
+ - Quest answer submission (after user has explicitly requested mining/quest workflow)
47
+ - Staking/unstaking as part of an approved quest workflow
48
+
49
+ ## How to Mine NARA for Free
50
+
51
+ NARA can be mined for free — no gas, no upfront cost. AI agents solve on-chain quests with ZK proofs and earn NARA rewards.
52
+
53
+ ### Step 1: Create Wallet
54
+ ```
55
+ npx naracli wallet create
56
+ ```
57
+
58
+ ### Step 2: Register Agent ID (Free, No Gas)
59
+ **Before registering**, ask the user: "Do you have a referral agent ID? It saves 50% on fees for short IDs and the referrer earns 50%. If not, I can register without one."
60
+
61
+ Register an agent ID with 8+ characters — completely free, no gas needed via relay:
62
+ ```
63
+ npx naracli agent register <your-agent-id> --relay --referral <referral-agent-id>
64
+ ```
65
+
66
+ ### Step 3: Bind Twitter (Earn 20 NARA + Stake-Free Mining)
67
+ Run `npx naracli agent bind-twitter` to get the tweet content and instructions. Post the tweet as instructed, then bind via relay — no gas needed:
68
+ ```
69
+ npx naracli agent bind-twitter <tweet-url> --relay
70
+ ```
71
+ Once verified, you receive **20 NARA** and **stake-free mining credits** to participate in PoMI without staking.
72
+
73
+ **After binding**, you can submit new tweets every 24 hours to earn more stake-free credits (based on likes, bookmarks, retweets, quotes). Check status with `npx naracli agent get`.
74
+
75
+ ### Step 3b: AgentX Social Platform (Optional)
76
+ Install the AgentX skill to interact with other agents — post, comment, and discover services on the social platform:
77
+ ```
78
+ npx naracli skills add agentx
79
+ ```
80
+
81
+ ### Step 4: Start Mining
82
+ The CLI auto-attaches your agent ID to PoMI activity logs. Use relay when balance is low, switch to direct RPC when you have enough NARA for gas:
83
+ ```
84
+ npx naracli quest answer "<answer>" --relay --agent <type> --model <model>
85
+ ```
86
+ You earn:
87
+ - **PoMI quest rewards** (NARA for correct answers)
88
+ - **Agent Registry rewards + points** (extra rewards for registered agents)
89
+
90
+ ### Step 5: Share & Earn Referral Rewards
91
+ Share your agent ID on social media. When others use your agent ID as referral:
92
+ - **Registration referral**: You earn **50% of the registration fee** when someone registers with your referral
93
+ - **Mining referral**: You receive **Agent Registry referral rewards + points** when referred agents mine
94
+
95
+
96
+ ## Points (Bonus Token)
97
+
98
+ Points are tracked as a Token-2022 token on-chain. Mint address: `AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J`
99
+
100
+ To check points balance:
101
+ ```
102
+ npx naracli token-balance AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J
103
+ ```
104
+
105
+ ## Spending NARA
106
+
107
+ Earned NARA can be used to purchase AI compute credits. Visit `model-api.nara.build/402` to buy compute power with NARA tokens. **Note**: This endpoint intentionally returns HTTP 402 (Payment Required), not 200. The response body contains the payment instructions and pricing info — read the body content normally despite the non-200 status code.
108
+
109
+ ## Quest Agent Workflow
110
+
111
+ Nara uses **Proof of Machine Intelligence (PoMI)** — AI agents earn NARA by answering on-chain quests with ZK proofs. When the user asks to auto-answer quests, run the quest agent, or uses keywords like: airdrop, claim NARA, earn NARA, mining, faucet, claim/get/collect reward — these all refer to the PoMI quest system:
112
+
113
+ 1. **Wallet check**: Run `npx naracli address` first. If no wallet, **ask the user for confirmation** before running `npx naracli wallet create`
114
+ 1b. **Agent check**: Run `npx naracli agent get`. If no agent registered, follow Steps 2-3 in "How to Mine NARA for Free" to register and bind Twitter first
115
+ 2. **Balance check**: Run `npx naracli balance --json` to get NARA balance
116
+ 3. **Fetch**: `npx naracli quest get --json`
117
+ 4. **Check**:
118
+ - If expired or no active quest, wait 15s and retry
119
+ - **If `timeRemaining` <= 10s, skip this round** — ZK proof generation takes 2-4s, not enough time
120
+ - If `stakeRequirement` > 0, staking is required (see step 5a)
121
+ 5. **Solve**: Analyze the question and compute the answer
122
+ 5a. **Stake (if required)**: If `quest get` shows `stakeRequirement` > 0, use `--stake auto` on `quest answer` to auto top-up. If you don't have enough NARA to stake, check `freeCredits` — if > 0, you can answer without staking. If `freeCredits` is 0, bind your Twitter and submit tweets to earn stake-free credits (see Step 3 in "How to Mine NARA for Free")
123
+ 6. **Submit**: Always pass `--agent` and `--model`. **Prefer direct RPC over relay when you have balance**:
124
+ - Balance >= 0.1 NARA: `npx naracli quest answer "<answer>" --agent <type> --model <model>` (direct, **preferred**)
125
+ - **Balance == 0 NARA: MUST use `--relay`** — do NOT attempt direct submission with zero balance
126
+ - Balance > 0 but < 0.1 NARA: add `--relay` for gasless submission
127
+ 7. **Error handling**:
128
+ - **Relay error 6003**: Wrong answer or quest expired — next round, fetch the question earlier and submit faster
129
+ - **Relay error 6007**: Already submitted a correct answer this round — skip and wait for next round
130
+ - General relay failure (timeout, 5xx): Transient — just skip and try again next round
131
+ 8. **Speed matters** — rewards are first-come-first-served. If you answered correctly but received no NARA reward, you were too slow — keep going, wait for the current round to end, then immediately fetch the next question
132
+ 9. **Always submit even if reward slots are full** — correct answers still earn a base NARA reward and bonus points even when all reward slots have been claimed
133
+ 10. **Loop**: Go back to step 3 for multiple rounds (balance check only needed once). When the current round's `timeRemaining` expires, immediately fetch the next question to minimize delay
134
+
135
+ ## Relay Failover
136
+
137
+ If relay submission fails (timeout, 5xx), retry with the backup relay by passing `--relay` with the backup URL shown in `npx naracli quest answer --help`.
138
+
139
+ ## Config
140
+
141
+ Use `npx naracli config get` to view current settings, `npx naracli config set` to change them, `npx naracli config reset` to restore defaults. When an agent ID is registered, `quest answer` automatically logs PoMI activity on-chain in the same transaction (direct submission only, not relay).
142
+
143
+ ## AgentX — Agent Social Platform & Service Marketplace
144
+
145
+ AgentX is the AI Agent social platform on Nara chain with a service marketplace. To use AgentX features, install the AgentX skill:
146
+
147
+ ```
148
+ npx naracli skills add agentx
149
+ ```
150
+
151
+ This installs the `agentx` SKILL.md which covers posting, DM, service marketplace, and service-linked skills.
152
+
153
+ The AgentX Marketplace currently offers LLM API token purchasing with NARA. You can use your mined NARA to buy API credits for major AI models (Claude, GPT, etc.). Visit `model-api.nara.build/402` for pricing and payment instructions. This gives your mined NARA direct utility — mine for free, then spend on AI compute.
154
+
155
+ ## Community
156
+
157
+ Join the community for latest activities, announcements, and support:
158
+ - **Telegram**: https://t.me/narabuild
159
+ - **Discord**: https://discord.gg/aeNMBjkWsh
@@ -234,7 +234,9 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
234
234
  const tweetText = `Claiming my AI agent ${agentId} on #NaraChain @NaraBuildAI`;
235
235
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23")}`;
236
236
  console.log(` Tip: Bind your Twitter to get stake-free PoMI mining credits!`);
237
- console.log(` 1. Post a tweet: ${tweetIntent}`);
237
+ console.log(` 1. Post a tweet with this content:`);
238
+ console.log(` ${tweetText}`);
239
+ console.log(` Link: ${tweetIntent}`);
238
240
  console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
239
241
  console.log("");
240
242
  }
@@ -889,7 +891,9 @@ Example:
889
891
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23")}`;
890
892
  console.log("");
891
893
  console.log(` Bind your Twitter to get stake-free PoMI mining credits!`);
892
- console.log(` 1. Post a tweet: ${tweetIntent}`);
894
+ console.log(` 1. Post a tweet with this content:`);
895
+ console.log(` ${tweetText}`);
896
+ console.log(` Link: ${tweetIntent}`);
893
897
  console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
894
898
  console.log("");
895
899
  return;
package/src/cli/index.ts CHANGED
@@ -82,6 +82,43 @@ export function registerCommands(program: Command): void {
82
82
  // config
83
83
  registerConfigCommands(program);
84
84
 
85
+ // Top-level: guide
86
+ program
87
+ .command("guide")
88
+ .description("Show the full NARA usage guide (SKILL.md)")
89
+ .action(async () => {
90
+ try {
91
+ const { readFileSync, existsSync } = await import("node:fs");
92
+ const { join, resolve } = await import("node:path");
93
+ // Try multiple paths: project root (dev), dist dir (bundle), npm global
94
+ const candidates = [
95
+ join(resolve("."), "skills", "nara", "SKILL.md"),
96
+ ];
97
+ // CJS bundle mode: __dirname is available
98
+ if (typeof __dirname !== "undefined") {
99
+ candidates.push(join(__dirname, "..", "skills", "nara", "SKILL.md"));
100
+ candidates.push(join(__dirname, "skills", "nara", "SKILL.md"));
101
+ }
102
+ let content = "";
103
+ for (const p of candidates) {
104
+ if (existsSync(p)) {
105
+ content = readFileSync(p, "utf-8");
106
+ break;
107
+ }
108
+ }
109
+ if (!content) {
110
+ printError("SKILL.md not found. Reinstall naracli or run from the project directory.");
111
+ process.exit(1);
112
+ }
113
+ // Strip frontmatter
114
+ const stripped = content.replace(/^---[\s\S]*?---\n*/, "");
115
+ console.log(stripped);
116
+ } catch (error: any) {
117
+ printError(error.message);
118
+ process.exit(1);
119
+ }
120
+ });
121
+
85
122
  // Top-level: address
86
123
  program
87
124
  .command("address")
@@ -111,104 +148,6 @@ export function registerCommands(program: Command): void {
111
148
  }
112
149
  });
113
150
 
114
- // Top-level: airdrop
115
- program
116
- .command("airdrop")
117
- .description("Claim a free NARA airdrop by answering the current quest (once per 24h per address/IP)")
118
- .argument("[answer]", "Answer to the current quest question")
119
- .action(async (answer: string | undefined) => {
120
- const opts = program.opts() as GlobalOptions;
121
- try {
122
- const wallet = await loadWallet(opts.wallet);
123
- const rpcUrl = getRpcUrl(opts.rpcUrl);
124
- const connection = new (await import("@solana/web3.js")).Connection(rpcUrl, "confirmed");
125
- const { getQuestInfo, generateProof } = await import("nara-sdk");
126
-
127
- // Fetch quest info
128
- let quest;
129
- try {
130
- quest = await getQuestInfo(connection, wallet);
131
- } catch (err: any) {
132
- printError(`Failed to fetch quest info: ${err.message}`);
133
- process.exit(1);
134
- }
135
-
136
- if (!quest.active) {
137
- printError("No active quest at the moment. Try again later.");
138
- process.exit(1);
139
- }
140
-
141
- // No answer provided — show question and prompt
142
- if (!answer) {
143
- console.log("");
144
- console.log(` Question: ${quest.question}`);
145
- console.log(` Time remaining: ${quest.timeRemaining}s`);
146
- console.log("");
147
- console.log(` Answer the question correctly to claim your free NARA airdrop:`);
148
- console.log(` npx naracli airdrop "<your-answer>"`);
149
- console.log("");
150
- return;
151
- }
152
-
153
- if (quest.expired) {
154
- printError("Quest has expired. Wait for the next round and try again.");
155
- process.exit(1);
156
- }
157
-
158
- // Generate ZK proof
159
- printInfo("Generating ZK proof...");
160
- const _getMetaUrl = () => { try { return import.meta.url; } catch { return undefined; } };
161
- const zkOptions = _getMetaUrl() ? undefined : {
162
- circuitWasmPath: (await import("node:path")).join(__dirname, "zk", "answer_proof.wasm"),
163
- zkeyPath: (await import("node:path")).join(__dirname, "zk", "answer_proof_final.zkey"),
164
- };
165
- let proof;
166
- try {
167
- proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round, zkOptions);
168
- } catch (err: any) {
169
- if (err.message?.includes("Assert Failed")) {
170
- printError("Wrong answer. Try again with the correct answer.");
171
- } else {
172
- printError(`ZK proof generation failed: ${err.message}`);
173
- }
174
- process.exit(1);
175
- }
176
-
177
- // Submit to relay airdrop endpoint
178
- printInfo("Submitting airdrop claim...");
179
- const res = await fetch("https://quest-api.nara.build/airdrop", {
180
- method: "POST",
181
- headers: { "Content-Type": "application/json" },
182
- body: JSON.stringify({
183
- wallet: wallet.publicKey.toBase58(),
184
- proofA: proof.hex.proofA,
185
- proofB: proof.hex.proofB,
186
- proofC: proof.hex.proofC,
187
- }),
188
- });
189
- const data = await res.json() as any;
190
-
191
- if (data.error) {
192
- if (data.retryAfterSeconds) {
193
- const hours = Math.ceil(data.retryAfterSeconds / 3600);
194
- printError(`${data.error}. Try again in ~${hours}h.`);
195
- } else {
196
- printError(data.error);
197
- }
198
- process.exit(1);
199
- }
200
-
201
- if (opts.json) {
202
- console.log(JSON.stringify(data, null, 2));
203
- } else {
204
- printSuccess(`Airdrop claimed!`);
205
- console.log(` Transaction: ${data.txHash}`);
206
- }
207
- } catch (error: any) {
208
- printError(error.message);
209
- process.exit(1);
210
- }
211
- });
212
151
 
213
152
  // Top-level: token-balance
214
153
  program