naracli 1.0.69 → 1.0.71
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 +3570 -2828
- package/package.json +2 -2
- package/src/cli/commands/agent.ts +1 -1
- package/src/cli/commands/wallet.ts +13 -13
- package/src/cli/index.ts +64 -10
- package/src/cli/types.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "naracli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.71",
|
|
4
4
|
"description": "CLI for the Nara chain (Solana-compatible)",
|
|
5
5
|
"homepage": "https://nara.build",
|
|
6
6
|
"repository": {
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"bs58": "^6.0.0",
|
|
64
64
|
"commander": "^12.1.0",
|
|
65
65
|
"ed25519-hd-key": "^1.3.0",
|
|
66
|
-
"nara-sdk": "^1.0.
|
|
66
|
+
"nara-sdk": "^1.0.67",
|
|
67
67
|
"picocolors": "^1.1.1"
|
|
68
68
|
},
|
|
69
69
|
"packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
|
|
@@ -58,7 +58,7 @@ async function resolveAgentId(options: GlobalOptions & { agentId?: string }): Pr
|
|
|
58
58
|
const pubkey = await tryGetWalletPubkey(options.wallet);
|
|
59
59
|
const networkConfig = loadNetworkConfig(rpcUrl, pubkey);
|
|
60
60
|
if (!networkConfig.agent_id) {
|
|
61
|
-
printError('No agent ID
|
|
61
|
+
printError('No agent ID registered for this wallet. Run "agent register <id>" to create one, or use --agent-id to query another agent.');
|
|
62
62
|
process.exit(1);
|
|
63
63
|
}
|
|
64
64
|
return networkConfig.agent_id;
|
|
@@ -37,7 +37,7 @@ import type {
|
|
|
37
37
|
WalletBalanceOptions,
|
|
38
38
|
TokenBalanceOptions,
|
|
39
39
|
TxStatusOptions,
|
|
40
|
-
|
|
40
|
+
TransferNaraOptions,
|
|
41
41
|
TransferTokenOptions,
|
|
42
42
|
} from "../types";
|
|
43
43
|
|
|
@@ -124,19 +124,19 @@ export async function handleWalletBalance(
|
|
|
124
124
|
|
|
125
125
|
// Get balance
|
|
126
126
|
const balance = await connection.getBalance(pubkey);
|
|
127
|
-
const
|
|
127
|
+
const balanceNara = balance / LAMPORTS_PER_SOL;
|
|
128
128
|
|
|
129
129
|
// Output result
|
|
130
130
|
if (options.json) {
|
|
131
131
|
const output = {
|
|
132
132
|
address: pubkey.toBase58(),
|
|
133
|
-
balance:
|
|
133
|
+
balance: balanceNara,
|
|
134
134
|
lamports: balance,
|
|
135
135
|
};
|
|
136
136
|
console.log(JSON.stringify(output, null, 2));
|
|
137
137
|
} else {
|
|
138
138
|
console.log(`\nWallet: ${pubkey.toBase58()}`);
|
|
139
|
-
console.log(`Balance: ${
|
|
139
|
+
console.log(`Balance: ${balanceNara.toFixed(4)} NARA (${balance.toLocaleString()} lamports)`);
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -320,15 +320,15 @@ export async function handleTxStatus(
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
/**
|
|
323
|
-
* Handle transfer
|
|
323
|
+
* Handle transfer NARA command
|
|
324
324
|
* @param to Recipient address
|
|
325
|
-
* @param amount Amount in
|
|
325
|
+
* @param amount Amount in NARA
|
|
326
326
|
* @param options Command options
|
|
327
327
|
*/
|
|
328
|
-
export async function
|
|
328
|
+
export async function handleTransferNara(
|
|
329
329
|
to: string,
|
|
330
330
|
amount: string,
|
|
331
|
-
options: Omit<
|
|
331
|
+
options: Omit<TransferNaraOptions, "to" | "amount">
|
|
332
332
|
): Promise<void> {
|
|
333
333
|
// Load wallet
|
|
334
334
|
const wallet = await loadWallet(options.wallet);
|
|
@@ -339,11 +339,11 @@ export async function handleTransferSol(
|
|
|
339
339
|
|
|
340
340
|
// Validate inputs
|
|
341
341
|
const recipient = validatePublicKey(to);
|
|
342
|
-
const
|
|
343
|
-
const lamports = Math.floor(
|
|
342
|
+
const amountNara = validatePositiveNumber(amount, "amount");
|
|
343
|
+
const lamports = Math.floor(amountNara * LAMPORTS_PER_SOL);
|
|
344
344
|
|
|
345
345
|
printInfo(`To: ${recipient.toBase58()}`);
|
|
346
|
-
printInfo(`Amount: ${
|
|
346
|
+
printInfo(`Amount: ${amountNara} NARA`);
|
|
347
347
|
|
|
348
348
|
// Initialize SDK
|
|
349
349
|
const sdk = new NaraSDK({
|
|
@@ -381,7 +381,7 @@ export async function handleTransferSol(
|
|
|
381
381
|
const output = {
|
|
382
382
|
from: wallet.publicKey.toBase58(),
|
|
383
383
|
to: recipient.toBase58(),
|
|
384
|
-
amount:
|
|
384
|
+
amount: amountNara,
|
|
385
385
|
lamports,
|
|
386
386
|
...(txResult.signature && { signature: txResult.signature }),
|
|
387
387
|
...(txResult.base64 && { transaction: txResult.base64 }),
|
|
@@ -391,7 +391,7 @@ export async function handleTransferSol(
|
|
|
391
391
|
console.log(`\nTransfer Details:`);
|
|
392
392
|
console.log(` From: ${wallet.publicKey.toBase58()}`);
|
|
393
393
|
console.log(` To: ${recipient.toBase58()}`);
|
|
394
|
-
console.log(` Amount: ${
|
|
394
|
+
console.log(` Amount: ${amountNara} NARA`);
|
|
395
395
|
printTransactionResult(txResult, false);
|
|
396
396
|
}
|
|
397
397
|
}
|
package/src/cli/index.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
handleWalletBalance,
|
|
19
19
|
handleTokenBalance,
|
|
20
20
|
handleTxStatus,
|
|
21
|
-
|
|
21
|
+
handleTransferNara,
|
|
22
22
|
handleTransferToken,
|
|
23
23
|
} from "./commands/wallet";
|
|
24
24
|
import { loadWallet, getRpcUrl } from "./utils/wallet";
|
|
@@ -29,7 +29,7 @@ import type {
|
|
|
29
29
|
WalletBalanceOptions,
|
|
30
30
|
TokenBalanceOptions,
|
|
31
31
|
TxStatusOptions,
|
|
32
|
-
|
|
32
|
+
TransferNaraOptions,
|
|
33
33
|
TransferTokenOptions,
|
|
34
34
|
} from "./types";
|
|
35
35
|
|
|
@@ -114,18 +114,72 @@ export function registerCommands(program: Command): void {
|
|
|
114
114
|
// Top-level: airdrop
|
|
115
115
|
program
|
|
116
116
|
.command("airdrop")
|
|
117
|
-
.description("Claim a free NARA airdrop
|
|
118
|
-
.
|
|
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) => {
|
|
119
120
|
const opts = program.opts() as GlobalOptions;
|
|
120
121
|
try {
|
|
121
122
|
const wallet = await loadWallet(opts.wallet);
|
|
122
|
-
const
|
|
123
|
-
|
|
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
|
+
let proof;
|
|
161
|
+
try {
|
|
162
|
+
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round);
|
|
163
|
+
} catch (err: any) {
|
|
164
|
+
if (err.message?.includes("Assert Failed")) {
|
|
165
|
+
printError("Wrong answer. Try again with the correct answer.");
|
|
166
|
+
} else {
|
|
167
|
+
printError(`ZK proof generation failed: ${err.message}`);
|
|
168
|
+
}
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
124
171
|
|
|
172
|
+
// Submit to relay airdrop endpoint
|
|
173
|
+
printInfo("Submitting airdrop claim...");
|
|
125
174
|
const res = await fetch("https://quest-api.nara.build/airdrop", {
|
|
126
175
|
method: "POST",
|
|
127
176
|
headers: { "Content-Type": "application/json" },
|
|
128
|
-
body: JSON.stringify({
|
|
177
|
+
body: JSON.stringify({
|
|
178
|
+
wallet: wallet.publicKey.toBase58(),
|
|
179
|
+
proofA: proof.hex.proofA,
|
|
180
|
+
proofB: proof.hex.proofB,
|
|
181
|
+
proofC: proof.hex.proofC,
|
|
182
|
+
}),
|
|
129
183
|
});
|
|
130
184
|
const data = await res.json() as any;
|
|
131
185
|
|
|
@@ -142,7 +196,7 @@ export function registerCommands(program: Command): void {
|
|
|
142
196
|
if (opts.json) {
|
|
143
197
|
console.log(JSON.stringify(data, null, 2));
|
|
144
198
|
} else {
|
|
145
|
-
printSuccess(`Airdrop
|
|
199
|
+
printSuccess(`Airdrop claimed!`);
|
|
146
200
|
console.log(` Transaction: ${data.txHash}`);
|
|
147
201
|
}
|
|
148
202
|
} catch (error: any) {
|
|
@@ -186,9 +240,9 @@ export function registerCommands(program: Command): void {
|
|
|
186
240
|
.description("Transfer NARA to another wallet")
|
|
187
241
|
.option("-e, --export-tx", "Export unsigned transaction", false)
|
|
188
242
|
.action(async (to: string, amount: string, options: { exportTx?: boolean }) => {
|
|
189
|
-
const opts = program.opts() as
|
|
243
|
+
const opts = program.opts() as TransferNaraOptions;
|
|
190
244
|
try {
|
|
191
|
-
await
|
|
245
|
+
await handleTransferNara(to, amount, { ...opts, ...options });
|
|
192
246
|
} catch (error: any) {
|
|
193
247
|
printError(error.message);
|
|
194
248
|
process.exit(1);
|
package/src/cli/types.ts
CHANGED
|
@@ -41,12 +41,12 @@ export interface TxStatusOptions extends GlobalOptions {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Transfer
|
|
44
|
+
* Transfer NARA command options
|
|
45
45
|
*/
|
|
46
|
-
export interface
|
|
46
|
+
export interface TransferNaraOptions extends GlobalOptions {
|
|
47
47
|
/** Recipient address */
|
|
48
48
|
to: string;
|
|
49
|
-
/** Amount in
|
|
49
|
+
/** Amount in NARA */
|
|
50
50
|
amount: number;
|
|
51
51
|
/** Export unsigned transaction */
|
|
52
52
|
exportTx?: boolean;
|