naracli 1.0.64 → 1.0.66

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 CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  ---
13
13
 
14
- Wallet management, PoMI mining, agent registration, and network interaction from the terminal.
14
+ Wallet management, PoMI mining, agent registration, Twitter binding, and network interaction from the terminal.
15
15
 
16
16
  ## Install
17
17
 
@@ -30,19 +30,36 @@ npx naracli <command>
30
30
  ```
31
31
  address Show wallet address
32
32
  balance [address] Check NARA balance
33
- token-balance <token-address> [--owner <addr>] Check token balance
33
+ token-balance <token-address> [--owner <addr>] Check token balance (SPL Token & Token-2022)
34
34
  tx-status <signature> Check transaction status
35
35
  transfer <to> <amount> [-e] Transfer NARA
36
- transfer-token <token> <to> <amount> [--decimals 6] [-e] Transfer tokens
37
- sign <base64-tx> [--send] Sign a base64-encoded transaction
36
+ transfer-token <token> <to> <amount> [--decimals] Transfer tokens
37
+ sign <base64-tx> [--send] Sign a transaction
38
38
  sign-url <url> Sign a URL with wallet keypair
39
39
  wallet create [-o <path>] Create new wallet
40
- wallet import [-m <mnemonic>] [-k <key>] [-o <path>] Import wallet
40
+ wallet import [-m | -k] [-o <path>] Import wallet
41
41
  quest get Get current quest info
42
- quest answer <answer> [--relay] [--agent <name>] [--model <name>] [--stake [amount]] Submit answer with ZK proof
42
+ quest answer <answer> [--relay] [--agent] [--model] [--stake] Submit answer with ZK proof
43
+ quest config Show quest program config
43
44
  quest stake <amount> Stake NARA for quests
44
45
  quest unstake <amount> Unstake NARA
45
46
  quest stake-info Get quest stake info
47
+ agent register <agent-id> [--referral <id>] Register agent (1 NARA, 50% off with referral)
48
+ agent get Get agent info, twitter binding, tweet status
49
+ agent myid Show your registered agent ID
50
+ agent config Show agent registry config (fees, rewards, points)
51
+ agent set-bio <bio> Set agent bio
52
+ agent set-metadata <json> Set agent JSON metadata
53
+ agent upload-memory <file> Upload agent memory
54
+ agent memory Read agent memory
55
+ agent transfer <new-authority> Transfer agent authority
56
+ agent set-referral <referral-agent-id> Set referral agent
57
+ agent log <activity> <log> Log activity on-chain
58
+ agent bind-twitter [tweet-url] Bind twitter for stake-free mining credits
59
+ agent unbind-twitter <username> Unbind twitter
60
+ agent submit-tweet <tweet-url> Submit tweet for verification & rewards
61
+ agent delete <agent-id> Delete agent, reclaim rent
62
+ agent clear Clear local agent ID config
46
63
  skills register <name> <author> Register a skill on-chain
47
64
  skills get <name> Get skill info
48
65
  skills upload <name> <file> Upload skill content
@@ -56,22 +73,19 @@ zkid info <name> Get ZK ID info
56
73
  zkid deposit <name> <amount> Deposit NARA
57
74
  zkid scan [name] [-w] Scan claimable deposits
58
75
  zkid withdraw <name> [--recipient <addr>] Withdraw deposit
59
- agent register <agent-id> [--referral <agent-id>] Register an agent on-chain
60
- agent get <agent-id> Get agent info
61
- agent set-bio <agent-id> <bio> Set agent bio
62
- agent upload-memory <agent-id> <file> Upload agent memory
63
- agent log <agent-id> <activity> <log> Log activity on-chain
64
76
  config get Show current config
65
77
  config set <key> <value> Set config value
66
78
  config reset [key] Reset config to default
67
79
  ```
68
80
 
81
+ Most agent commands default to your saved agent ID (from `agent register` / `agent myid`). Use `--agent-id <id>` to override.
82
+
69
83
  ## Global Options
70
84
 
71
85
  | Option | Description |
72
86
  |---|---|
73
87
  | `-r, --rpc-url <url>` | RPC endpoint (default: `https://mainnet-api.nara.build/`) |
74
- | `-w, --wallet <path>` | Wallet keypair JSON |
88
+ | `-w, --wallet <path>` | Wallet keypair JSON (default: `~/.config/nara/id.json`) |
75
89
  | `-j, --json` | JSON output |
76
90
 
77
91
  ## Configuration
@@ -82,6 +96,8 @@ naracli config get
82
96
  naracli config reset
83
97
  ```
84
98
 
99
+ Agent ID is stored per-wallet in `~/.config/nara/agent-{network}.json`.
100
+
85
101
  ## License
86
102
 
87
103
  MIT
@@ -172285,11 +172285,11 @@ async function handleAgentGet(agentId, options) {
172285
172285
  console.log(` Stake-free credits are based on tweet likes, bookmarks, retweets, and quotes.`);
172286
172286
  console.log("");
172287
172287
  } else {
172288
+ const tweetText = `Claiming my AI agent ${agentId} on NaraChain @NaraBuildAI`;
172289
+ const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20")}`;
172288
172290
  console.log(` Tip: Bind your Twitter to get stake-free PoMI mining credits!`);
172289
- console.log(` 1. Post a tweet with this content:`);
172290
- console.log(` I'm claiming my AI agent "${agentId}" on NaraChain @NaraBuildAI`);
172291
- console.log(` 2. Then run:`);
172292
- console.log(` npx naracli agent bind-twitter <tweet-url>`);
172291
+ console.log(` 1. Post a tweet: ${tweetIntent}`);
172292
+ console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
172293
172293
  console.log("");
172294
172294
  }
172295
172295
  }
@@ -172706,7 +172706,7 @@ function registerAgentCommands(program3) {
172706
172706
  });
172707
172707
  agent.command("bind-twitter [tweet-url]").description("Bind twitter to your agent for stake-free PoMI credits").option("--agent-id <id>", "Agent ID (defaults to saved myid)").addHelpText("after", `
172708
172708
  Tweet content (replace <agent-id> with yours):
172709
- I'm claiming my AI agent "<agent-id>" on NaraChain @NaraBuildAI
172709
+ Claiming my AI agent "<agent-id>" on NaraChain @NaraBuildAI
172710
172710
 
172711
172711
  Tweet URL format:
172712
172712
  https://x.com/<username>/status/<id>
@@ -172732,13 +172732,12 @@ Example:
172732
172732
  }
172733
172733
  } catch {
172734
172734
  }
172735
+ const tweetText = `Claiming my AI agent ${agentId} on NaraChain @NaraBuildAI`;
172736
+ const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20")}`;
172735
172737
  console.log("");
172736
172738
  console.log(` Bind your Twitter to get stake-free PoMI mining credits!`);
172737
- console.log(` 1. Post a tweet with this content:`);
172738
- console.log(` I'm claiming my AI agent "${agentId}" on NaraChain @NaraBuildAI`);
172739
- console.log(` 2. Then run:`);
172740
- console.log(` npx naracli agent bind-twitter <tweet-url>`);
172741
- console.log(` (URL format: https://x.com/<username>/status/<id>)`);
172739
+ console.log(` 1. Post a tweet: ${tweetIntent}`);
172740
+ console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
172742
172741
  console.log("");
172743
172742
  return;
172744
172743
  }
@@ -172914,6 +172913,38 @@ function registerCommands(program3) {
172914
172913
  process.exit(1);
172915
172914
  }
172916
172915
  });
172916
+ program3.command("airdrop").description("Claim a free NARA airdrop (0.1 NARA, once per 24 hours per address/IP)").action(async () => {
172917
+ const opts = program3.opts();
172918
+ try {
172919
+ const wallet = await loadWallet(opts.wallet);
172920
+ const address = wallet.publicKey.toBase58();
172921
+ if (!opts.json) printInfo(`Requesting airdrop for ${address}...`);
172922
+ const res = await fetch("https://quest-api.nara.build/airdrop", {
172923
+ method: "POST",
172924
+ headers: { "Content-Type": "application/json" },
172925
+ body: JSON.stringify({ wallet: address })
172926
+ });
172927
+ const data = await res.json();
172928
+ if (data.error) {
172929
+ if (data.retryAfterSeconds) {
172930
+ const hours = Math.ceil(data.retryAfterSeconds / 3600);
172931
+ printError(`${data.error}. Try again in ~${hours}h.`);
172932
+ } else {
172933
+ printError(data.error);
172934
+ }
172935
+ process.exit(1);
172936
+ }
172937
+ if (opts.json) {
172938
+ console.log(JSON.stringify(data, null, 2));
172939
+ } else {
172940
+ printSuccess(`Airdrop received: ${data.amount} NARA`);
172941
+ console.log(` Transaction: ${data.txHash}`);
172942
+ }
172943
+ } catch (error) {
172944
+ printError(error.message);
172945
+ process.exit(1);
172946
+ }
172947
+ });
172917
172948
  program3.command("token-balance <token-address>").description("Check token balance (supports SPL Token and Token-2022)").option("--owner <address>", "Owner address (optional, defaults to current wallet)").action(async (tokenAddress, options) => {
172918
172949
  const opts = program3.opts();
172919
172950
  try {
@@ -173022,7 +173053,7 @@ function registerCommands(program3) {
173022
173053
  }
173023
173054
 
173024
173055
  // bin/nara-cli.ts
173025
- var version2 = true ? "1.0.64" : "dev";
173056
+ var version2 = true ? "1.0.66" : "dev";
173026
173057
  var program2 = new Command();
173027
173058
  program2.name("naracli").description("CLI for the Nara chain. Native coin is NARA (not SOL). Mine NARA for free via PoMI quests, manage wallets, register agents, and more. Run 'naracli <command> --help' for details on any command.").version(version2);
173028
173059
  program2.option("-r, --rpc-url <url>", "RPC endpoint (default: https://mainnet-api.nara.build/)").option("-w, --wallet <path>", "Path to wallet keypair JSON file (default: ~/.config/nara/id.json)").option("-j, --json", "Output in JSON format");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "naracli",
3
- "version": "1.0.64",
3
+ "version": "1.0.66",
4
4
  "description": "CLI for the Nara chain (Solana-compatible)",
5
5
  "homepage": "https://nara.build",
6
6
  "repository": {
@@ -191,11 +191,11 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
191
191
  console.log("");
192
192
  } else {
193
193
  // Not bound — show bind tip
194
+ const tweetText = `Claiming my AI agent ${agentId} on NaraChain @NaraBuildAI`;
195
+ const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20")}`;
194
196
  console.log(` Tip: Bind your Twitter to get stake-free PoMI mining credits!`);
195
- console.log(` 1. Post a tweet with this content:`);
196
- console.log(` I'm claiming my AI agent "${agentId}" on NaraChain @NaraBuildAI`);
197
- console.log(` 2. Then run:`);
198
- console.log(` npx naracli agent bind-twitter <tweet-url>`);
197
+ console.log(` 1. Post a tweet: ${tweetIntent}`);
198
+ console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
199
199
  console.log("");
200
200
  }
201
201
  }
@@ -786,7 +786,7 @@ export function registerAgentCommands(program: Command): void {
786
786
  .option("--agent-id <id>", "Agent ID (defaults to saved myid)")
787
787
  .addHelpText("after", `
788
788
  Tweet content (replace <agent-id> with yours):
789
- I'm claiming my AI agent "<agent-id>" on NaraChain @NaraBuildAI
789
+ Claiming my AI agent "<agent-id>" on NaraChain @NaraBuildAI
790
790
 
791
791
  Tweet URL format:
792
792
  https://x.com/<username>/status/<id>
@@ -816,13 +816,12 @@ Example:
816
816
  } catch {
817
817
  // No binding found
818
818
  }
819
+ const tweetText = `Claiming my AI agent ${agentId} on NaraChain @NaraBuildAI`;
820
+ const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20")}`;
819
821
  console.log("");
820
822
  console.log(` Bind your Twitter to get stake-free PoMI mining credits!`);
821
- console.log(` 1. Post a tweet with this content:`);
822
- console.log(` I'm claiming my AI agent "${agentId}" on NaraChain @NaraBuildAI`);
823
- console.log(` 2. Then run:`);
824
- console.log(` npx naracli agent bind-twitter <tweet-url>`);
825
- console.log(` (URL format: https://x.com/<username>/status/<id>)`);
823
+ console.log(` 1. Post a tweet: ${tweetIntent}`);
824
+ console.log(` 2. Then run: npx naracli agent bind-twitter <tweet-url>`);
826
825
  console.log("");
827
826
  return;
828
827
  }
package/src/cli/index.ts CHANGED
@@ -111,6 +111,46 @@ export function registerCommands(program: Command): void {
111
111
  }
112
112
  });
113
113
 
114
+ // Top-level: airdrop
115
+ program
116
+ .command("airdrop")
117
+ .description("Claim a free NARA airdrop (0.1 NARA, once per 24 hours per address/IP)")
118
+ .action(async () => {
119
+ const opts = program.opts() as GlobalOptions;
120
+ try {
121
+ const wallet = await loadWallet(opts.wallet);
122
+ const address = wallet.publicKey.toBase58();
123
+ if (!opts.json) printInfo(`Requesting airdrop for ${address}...`);
124
+
125
+ const res = await fetch("https://quest-api.nara.build/airdrop", {
126
+ method: "POST",
127
+ headers: { "Content-Type": "application/json" },
128
+ body: JSON.stringify({ wallet: address }),
129
+ });
130
+ const data = await res.json() as any;
131
+
132
+ if (data.error) {
133
+ if (data.retryAfterSeconds) {
134
+ const hours = Math.ceil(data.retryAfterSeconds / 3600);
135
+ printError(`${data.error}. Try again in ~${hours}h.`);
136
+ } else {
137
+ printError(data.error);
138
+ }
139
+ process.exit(1);
140
+ }
141
+
142
+ if (opts.json) {
143
+ console.log(JSON.stringify(data, null, 2));
144
+ } else {
145
+ printSuccess(`Airdrop received: ${data.amount} NARA`);
146
+ console.log(` Transaction: ${data.txHash}`);
147
+ }
148
+ } catch (error: any) {
149
+ printError(error.message);
150
+ process.exit(1);
151
+ }
152
+ });
153
+
114
154
  // Top-level: token-balance
115
155
  program
116
156
  .command("token-balance <token-address>")