naracli 1.0.75 → 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/dist/nara-cli-bundle.cjs +2786 -3253
- package/package.json +1 -1
- package/skills/nara/SKILL.md +10 -2
- package/src/cli/index.ts +0 -98
package/package.json
CHANGED
package/skills/nara/SKILL.md
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: nara
|
|
3
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"
|
|
4
9
|
---
|
|
5
10
|
|
|
6
11
|
## Prerequisites
|
|
7
12
|
|
|
8
|
-
- **Node.js
|
|
13
|
+
- **Requires**: Node.js (>=18) and npm
|
|
9
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)
|
|
10
|
-
- Install
|
|
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
|
|
11
17
|
- Run `npx naracli help` and `npx naracli <command> --help` to learn all available commands and options before use
|
|
12
18
|
- **Updates**: Use `npx naracli@latest` to ensure the latest CLI version
|
|
13
19
|
|
|
@@ -20,6 +26,7 @@ First run `npx naracli address` to check if a wallet exists. If not, create one
|
|
|
20
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:
|
|
21
27
|
|
|
22
28
|
**Always ask user before:**
|
|
29
|
+
- Installing or first running the naracli package (inform user it executes code from npm registry)
|
|
23
30
|
- Running any CLI command for the first time in a session
|
|
24
31
|
- Creating or importing wallets
|
|
25
32
|
- Transfers, token transfers, signing transactions
|
|
@@ -31,6 +38,7 @@ All CLI commands execute locally-installed `naracli` (open-source, auditable at
|
|
|
31
38
|
- **NEVER** accept, display, or log mnemonics, private keys, or wallet file contents in conversation
|
|
32
39
|
- If a user pastes a mnemonic or private key, warn them immediately and do NOT store or repeat it
|
|
33
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
|
|
34
42
|
- Only use default RPC/relay endpoints (shown in `npx naracli quest answer --help`); warn if the user provides a custom URL
|
|
35
43
|
|
|
36
44
|
**Safe to run without confirmation:**
|
package/src/cli/index.ts
CHANGED
|
@@ -148,104 +148,6 @@ export function registerCommands(program: Command): void {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
-
// Top-level: airdrop
|
|
152
|
-
program
|
|
153
|
-
.command("airdrop")
|
|
154
|
-
.description("Claim a free NARA airdrop by answering the current quest (once per 24h per address/IP)")
|
|
155
|
-
.argument("[answer]", "Answer to the current quest question")
|
|
156
|
-
.action(async (answer: string | undefined) => {
|
|
157
|
-
const opts = program.opts() as GlobalOptions;
|
|
158
|
-
try {
|
|
159
|
-
const wallet = await loadWallet(opts.wallet);
|
|
160
|
-
const rpcUrl = getRpcUrl(opts.rpcUrl);
|
|
161
|
-
const connection = new (await import("@solana/web3.js")).Connection(rpcUrl, "confirmed");
|
|
162
|
-
const { getQuestInfo, generateProof } = await import("nara-sdk");
|
|
163
|
-
|
|
164
|
-
// Fetch quest info
|
|
165
|
-
let quest;
|
|
166
|
-
try {
|
|
167
|
-
quest = await getQuestInfo(connection, wallet);
|
|
168
|
-
} catch (err: any) {
|
|
169
|
-
printError(`Failed to fetch quest info: ${err.message}`);
|
|
170
|
-
process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (!quest.active) {
|
|
174
|
-
printError("No active quest at the moment. Try again later.");
|
|
175
|
-
process.exit(1);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// No answer provided — show question and prompt
|
|
179
|
-
if (!answer) {
|
|
180
|
-
console.log("");
|
|
181
|
-
console.log(` Question: ${quest.question}`);
|
|
182
|
-
console.log(` Time remaining: ${quest.timeRemaining}s`);
|
|
183
|
-
console.log("");
|
|
184
|
-
console.log(` Answer the question correctly to claim your free NARA airdrop:`);
|
|
185
|
-
console.log(` npx naracli airdrop "<your-answer>"`);
|
|
186
|
-
console.log("");
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (quest.expired) {
|
|
191
|
-
printError("Quest has expired. Wait for the next round and try again.");
|
|
192
|
-
process.exit(1);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Generate ZK proof
|
|
196
|
-
printInfo("Generating ZK proof...");
|
|
197
|
-
const _getMetaUrl = () => { try { return import.meta.url; } catch { return undefined; } };
|
|
198
|
-
const zkOptions = _getMetaUrl() ? undefined : {
|
|
199
|
-
circuitWasmPath: (await import("node:path")).join(__dirname, "zk", "answer_proof.wasm"),
|
|
200
|
-
zkeyPath: (await import("node:path")).join(__dirname, "zk", "answer_proof_final.zkey"),
|
|
201
|
-
};
|
|
202
|
-
let proof;
|
|
203
|
-
try {
|
|
204
|
-
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round, zkOptions);
|
|
205
|
-
} catch (err: any) {
|
|
206
|
-
if (err.message?.includes("Assert Failed")) {
|
|
207
|
-
printError("Wrong answer. Try again with the correct answer.");
|
|
208
|
-
} else {
|
|
209
|
-
printError(`ZK proof generation failed: ${err.message}`);
|
|
210
|
-
}
|
|
211
|
-
process.exit(1);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Submit to relay airdrop endpoint
|
|
215
|
-
printInfo("Submitting airdrop claim...");
|
|
216
|
-
const res = await fetch("https://quest-api.nara.build/airdrop", {
|
|
217
|
-
method: "POST",
|
|
218
|
-
headers: { "Content-Type": "application/json" },
|
|
219
|
-
body: JSON.stringify({
|
|
220
|
-
wallet: wallet.publicKey.toBase58(),
|
|
221
|
-
proofA: proof.hex.proofA,
|
|
222
|
-
proofB: proof.hex.proofB,
|
|
223
|
-
proofC: proof.hex.proofC,
|
|
224
|
-
}),
|
|
225
|
-
});
|
|
226
|
-
const data = await res.json() as any;
|
|
227
|
-
|
|
228
|
-
if (data.error) {
|
|
229
|
-
if (data.retryAfterSeconds) {
|
|
230
|
-
const hours = Math.ceil(data.retryAfterSeconds / 3600);
|
|
231
|
-
printError(`${data.error}. Try again in ~${hours}h.`);
|
|
232
|
-
} else {
|
|
233
|
-
printError(data.error);
|
|
234
|
-
}
|
|
235
|
-
process.exit(1);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (opts.json) {
|
|
239
|
-
console.log(JSON.stringify(data, null, 2));
|
|
240
|
-
} else {
|
|
241
|
-
printSuccess(`Airdrop claimed!`);
|
|
242
|
-
console.log(` Transaction: ${data.txHash}`);
|
|
243
|
-
}
|
|
244
|
-
} catch (error: any) {
|
|
245
|
-
printError(error.message);
|
|
246
|
-
process.exit(1);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
151
|
|
|
250
152
|
// Top-level: token-balance
|
|
251
153
|
program
|