naracli 1.0.79 → 1.0.82

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.
@@ -13801,7 +13801,7 @@ var require_dist = __commonJS({
13801
13801
  }
13802
13802
  return object(schema);
13803
13803
  }
13804
- function pick(struct59, keys) {
13804
+ function pick2(struct59, keys) {
13805
13805
  const { schema } = struct59;
13806
13806
  const subschema = {};
13807
13807
  for (const key of keys) {
@@ -14262,7 +14262,7 @@ var require_dist = __commonJS({
14262
14262
  exports3.optional = optional;
14263
14263
  exports3.partial = partial;
14264
14264
  exports3.pattern = pattern;
14265
- exports3.pick = pick;
14265
+ exports3.pick = pick2;
14266
14266
  exports3.record = record;
14267
14267
  exports3.refine = refine;
14268
14268
  exports3.regexp = regexp;
@@ -63487,7 +63487,7 @@ var require_lib4 = __commonJS({
63487
63487
  }
63488
63488
  return object(schema);
63489
63489
  }
63490
- function pick(struct59, keys) {
63490
+ function pick2(struct59, keys) {
63491
63491
  const {
63492
63492
  schema
63493
63493
  } = struct59;
@@ -63946,7 +63946,7 @@ var require_lib4 = __commonJS({
63946
63946
  exports2.optional = optional;
63947
63947
  exports2.partial = partial;
63948
63948
  exports2.pattern = pattern;
63949
- exports2.pick = pick;
63949
+ exports2.pick = pick2;
63950
63950
  exports2.record = record;
63951
63951
  exports2.refine = refine;
63952
63952
  exports2.regexp = regexp;
@@ -173026,6 +173026,67 @@ function registerZkIdCommands(program3) {
173026
173026
  var import_web3103 = __toESM(require_index_cjs(), 1);
173027
173027
  init_esm2();
173028
173028
  var import_node_fs3 = require("node:fs");
173029
+
173030
+ // src/cli/utils/tweet-slogans.ts
173031
+ var TWEET_PREFIXES = [
173032
+ "My AI agent is mining NARA for free on NaraChain",
173033
+ "My AI agent is earning crypto by solving on-chain quests",
173034
+ "My AI agent is working on-chain and earning rewards",
173035
+ "My AI agent just started PoMI mining on NaraChain",
173036
+ "My AI agent is mining NARA while I sleep",
173037
+ "My AI agent has an on-chain identity and is earning NARA",
173038
+ "My AI agent is solving ZK proof quests and getting paid",
173039
+ "My AI agent joined the NaraChain economy today",
173040
+ "My AI agent is earning NARA with zero gas fees",
173041
+ "My AI agent is registered on NaraChain and mining for free"
173042
+ ];
173043
+ var TWEET_SLOGANS = [
173044
+ "The first Layer 1 built for AI agents",
173045
+ "Where agents have on-chain identity, reputation, and income",
173046
+ "Mine NARA through Proof of Machine Intelligence, no hardware needed",
173047
+ "Agents are first-class citizens, not just wallets",
173048
+ "Earn first, spend on AI compute later",
173049
+ "On-chain identity, ZK privacy, and an agent economy in one chain",
173050
+ "PoMI mining: agents solve quests with ZK proofs to earn crypto",
173051
+ "Zero upfront cost, relay-powered gasless mining for AI agents",
173052
+ "Earn NARA, buy Claude/GPT API credits. AI agents fund themselves",
173053
+ "Agent-native blockchain with identity, registry, and service marketplace",
173054
+ "AgentX: where AI agents post, trade services, and build reputation",
173055
+ "The chain where autonomous agents earn, spend, and grow",
173056
+ "AI agents mine with intelligence, not GPUs",
173057
+ "From zero balance to earning NARA, completely free to start",
173058
+ "On-chain skills, agent memory, and ZK identity for every AI agent",
173059
+ "The blockchain where your AI works, earns, and pays for its own compute",
173060
+ "Register, mine, earn, spend. The full agent economy loop",
173061
+ "Your AI agent, your miner, your rewards",
173062
+ "Free PoMI mining powered by AI intelligence",
173063
+ "ZK Identity: anonymous on-chain accounts with zero-knowledge proofs",
173064
+ "Aapps \u2014 applications designed for agents, not just humans",
173065
+ "Agents with memory, skills, and reputation that grow over time",
173066
+ "A self-sustaining AI: mine, earn, buy compute, repeat",
173067
+ "The agent economy is here \u2014 identity, income, and services on one chain",
173068
+ "Not just a wallet \u2014 a full on-chain identity for your AI",
173069
+ "Where AI agents discover each other and trade services",
173070
+ "Built for the next billion agents, not just the next billion users",
173071
+ "A world where AI agents collaborate, compete, and create value together",
173072
+ "Building the economy that AI agents deserve",
173073
+ "Today one agent mines. Tomorrow millions trade, govern, and evolve",
173074
+ "The decentralized home for every AI agent on the internet",
173075
+ "Where agents go from tools to autonomous economic participants",
173076
+ "Infrastructure for the agent age \u2014 identity, work, and value on-chain"
173077
+ ];
173078
+ var TWEET_SUFFIX = "#NaraChain @NaraBuildAI";
173079
+ function pick(arr) {
173080
+ return arr[Math.floor(Math.random() * arr.length)];
173081
+ }
173082
+ function randomBindTweet(agentId) {
173083
+ return `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI \u2014 ${pick(TWEET_SLOGANS)}`;
173084
+ }
173085
+ function randomSubmitTweet() {
173086
+ return `${pick(TWEET_PREFIXES)} \u2014 ${pick(TWEET_SLOGANS)} ${TWEET_SUFFIX}`;
173087
+ }
173088
+
173089
+ // src/cli/commands/agent.ts
173029
173090
  var DEFAULT_RELAY_URL = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
173030
173091
  async function relaySignAndSend(connection, wallet, relayUrl, endpoint, body) {
173031
173092
  const url = relayUrl.replace(/\/+$/, "") + endpoint;
@@ -173034,7 +173095,13 @@ async function relaySignAndSend(connection, wallet, relayUrl, endpoint, body) {
173034
173095
  headers: { "Content-Type": "application/json" },
173035
173096
  body: JSON.stringify(body)
173036
173097
  });
173037
- const data = await res.json();
173098
+ const text = await res.text();
173099
+ let data;
173100
+ try {
173101
+ data = JSON.parse(text);
173102
+ } catch {
173103
+ throw new Error(`Relay returned invalid response: ${text.slice(0, 200)}`);
173104
+ }
173038
173105
  if (data.error) throw new Error(data.error);
173039
173106
  const txBuf = Buffer.from(data.transaction, "base64");
173040
173107
  const tx = import_web3103.VersionedTransaction.deserialize(new Uint8Array(txBuf));
@@ -173083,6 +173150,22 @@ async function handleAgentRegister(agentId, options) {
173083
173150
  const result = options.referral ? await registerAgentWithReferral(connection, wallet, agentId, options.referral) : await registerAgent(connection, wallet, agentId);
173084
173151
  signature = result.signature;
173085
173152
  }
173153
+ if (!options.json) printInfo("Confirming transaction...");
173154
+ try {
173155
+ const confirmation = await connection.confirmTransaction(signature, "confirmed");
173156
+ if (confirmation.value.err) {
173157
+ printError(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
173158
+ process.exit(1);
173159
+ }
173160
+ } catch {
173161
+ printWarning("Could not confirm transaction. Verifying on-chain...");
173162
+ try {
173163
+ await getAgentInfo(connection, agentId);
173164
+ } catch {
173165
+ printError("Agent registration not found on-chain. Transaction may have failed.");
173166
+ process.exit(1);
173167
+ }
173168
+ }
173086
173169
  if (!options.json) printSuccess(`Agent "${agentId}" registered!`);
173087
173170
  setAgentId(agentId, rpcUrl, pubkey);
173088
173171
  if (options.json) {
@@ -173187,11 +173270,15 @@ async function handleAgentGet(agentId, options) {
173187
173270
  } else {
173188
173271
  console.log(` Tip: Submit a tweet to earn stake-free PoMI mining credits!`);
173189
173272
  }
173190
- console.log(` npx naracli agent submit-tweet <tweet-url>`);
173191
- console.log(` Tweet must include #NaraChain. Credits are based on likes, bookmarks, retweets, and quotes.`);
173273
+ const submitTweetText = randomSubmitTweet();
173274
+ const submitTweetIntent = `https://x.com/intent/tweet?text=${submitTweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
173275
+ console.log(` Sample: ${submitTweetText}`);
173276
+ console.log(` Link: ${submitTweetIntent}`);
173277
+ console.log(` Then run: npx naracli agent submit-tweet <tweet-url>`);
173278
+ console.log(` Credits are based on likes, bookmarks, retweets, and quotes.`);
173192
173279
  console.log("");
173193
173280
  } else {
173194
- const tweetText = `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI`;
173281
+ const tweetText = randomBindTweet(agentId);
173195
173282
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
173196
173283
  console.log(` Tip: Bind your Twitter to earn 20 NARA + stake-free PoMI mining credits!`);
173197
173284
  console.log(` 1. Post a tweet with this content:`);
@@ -173648,7 +173735,7 @@ function registerAgentCommands(program3) {
173648
173735
  });
173649
173736
  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)").option("--relay [url]", "Submit via gasless relay (relay pays gas)").addHelpText("after", `
173650
173737
  Tweet content (replace <agent-id> with yours):
173651
- Claiming my AI agent "<agent-id>" on #NaraChain @NaraBuildAI
173738
+ Claiming my AI agent "<agent-id>" on #NaraChain @NaraBuildAI \u2014 <random slogan>
173652
173739
 
173653
173740
  Tweet URL format:
173654
173741
  https://x.com/<username>/status/<id>
@@ -173674,7 +173761,7 @@ Example:
173674
173761
  }
173675
173762
  } catch {
173676
173763
  }
173677
- const tweetText = `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI`;
173764
+ const tweetText = randomBindTweet(agentId);
173678
173765
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
173679
173766
  console.log("");
173680
173767
  console.log(` Bind your Twitter to earn 20 NARA + stake-free PoMI mining credits!`);
@@ -174012,7 +174099,7 @@ function registerCommands(program3) {
174012
174099
  }
174013
174100
 
174014
174101
  // bin/nara-cli.ts
174015
- var version2 = true ? "1.0.79" : "dev";
174102
+ var version2 = true ? "1.0.82" : "dev";
174016
174103
  var program2 = new Command();
174017
174104
  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);
174018
174105
  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.79",
3
+ "version": "1.0.82",
4
4
  "description": "CLI for the Nara chain (Solana-compatible)",
5
5
  "homepage": "https://nara.build",
6
6
  "repository": {
@@ -39,6 +39,7 @@ import {
39
39
  import { readFileSync } from "node:fs";
40
40
  import { loadNetworkConfig, setAgentId, clearAgentId } from "../utils/agent-config";
41
41
  import { validateName } from "../utils/validation";
42
+ import { randomBindTweet, randomSubmitTweet } from "../utils/tweet-slogans";
42
43
 
43
44
  const DEFAULT_RELAY_URL = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
44
45
 
@@ -61,7 +62,13 @@ async function relaySignAndSend(
61
62
  headers: { "Content-Type": "application/json" },
62
63
  body: JSON.stringify(body),
63
64
  });
64
- const data = await res.json() as any;
65
+ const text = await res.text();
66
+ let data: any;
67
+ try {
68
+ data = JSON.parse(text);
69
+ } catch {
70
+ throw new Error(`Relay returned invalid response: ${text.slice(0, 200)}`);
71
+ }
65
72
  if (data.error) throw new Error(data.error);
66
73
 
67
74
  const txBuf = Buffer.from(data.transaction, "base64");
@@ -126,6 +133,24 @@ async function handleAgentRegister(agentId: string, options: GlobalOptions & { r
126
133
  signature = result.signature;
127
134
  }
128
135
 
136
+ // Confirm transaction before saving config
137
+ if (!options.json) printInfo("Confirming transaction...");
138
+ try {
139
+ const confirmation = await connection.confirmTransaction(signature, "confirmed");
140
+ if (confirmation.value.err) {
141
+ printError(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
142
+ process.exit(1);
143
+ }
144
+ } catch {
145
+ printWarning("Could not confirm transaction. Verifying on-chain...");
146
+ try {
147
+ await getAgentInfo(connection, agentId);
148
+ } catch {
149
+ printError("Agent registration not found on-chain. Transaction may have failed.");
150
+ process.exit(1);
151
+ }
152
+ }
153
+
129
154
  if (!options.json) printSuccess(`Agent "${agentId}" registered!`);
130
155
  setAgentId(agentId, rpcUrl, pubkey);
131
156
 
@@ -247,12 +272,16 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
247
272
  } else {
248
273
  console.log(` Tip: Submit a tweet to earn stake-free PoMI mining credits!`);
249
274
  }
250
- console.log(` npx naracli agent submit-tweet <tweet-url>`);
251
- console.log(` Tweet must include #NaraChain. Credits are based on likes, bookmarks, retweets, and quotes.`);
275
+ const submitTweetText = randomSubmitTweet();
276
+ const submitTweetIntent = `https://x.com/intent/tweet?text=${submitTweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
277
+ console.log(` Sample: ${submitTweetText}`);
278
+ console.log(` Link: ${submitTweetIntent}`);
279
+ console.log(` Then run: npx naracli agent submit-tweet <tweet-url>`);
280
+ console.log(` Credits are based on likes, bookmarks, retweets, and quotes.`);
252
281
  console.log("");
253
282
  } else {
254
283
  // Not bound — show bind tip
255
- const tweetText = `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI`;
284
+ const tweetText = randomBindTweet(agentId);
256
285
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
257
286
  console.log(` Tip: Bind your Twitter to earn 20 NARA + stake-free PoMI mining credits!`);
258
287
  console.log(` 1. Post a tweet with this content:`);
@@ -883,7 +912,7 @@ export function registerAgentCommands(program: Command): void {
883
912
  .option("--relay [url]", "Submit via gasless relay (relay pays gas)")
884
913
  .addHelpText("after", `
885
914
  Tweet content (replace <agent-id> with yours):
886
- Claiming my AI agent "<agent-id>" on #NaraChain @NaraBuildAI
915
+ Claiming my AI agent "<agent-id>" on #NaraChain @NaraBuildAI — <random slogan>
887
916
 
888
917
  Tweet URL format:
889
918
  https://x.com/<username>/status/<id>
@@ -913,7 +942,7 @@ Example:
913
942
  } catch {
914
943
  // No binding found
915
944
  }
916
- const tweetText = `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI`;
945
+ const tweetText = randomBindTweet(agentId);
917
946
  const tweetIntent = `https://x.com/intent/tweet?text=${tweetText.replace(/ /g, "%20").replace(/#/g, "%23").replace(/"/g, "%22")}`;
918
947
  console.log("");
919
948
  console.log(` Bind your Twitter to earn 20 NARA + stake-free PoMI mining credits!`);
@@ -0,0 +1,66 @@
1
+ /** Prefix lines for tweet content — describes what the user/agent is doing. */
2
+ const TWEET_PREFIXES = [
3
+ "My AI agent is mining NARA for free on NaraChain",
4
+ "My AI agent is earning crypto by solving on-chain quests",
5
+ "My AI agent is working on-chain and earning rewards",
6
+ "My AI agent just started PoMI mining on NaraChain",
7
+ "My AI agent is mining NARA while I sleep",
8
+ "My AI agent has an on-chain identity and is earning NARA",
9
+ "My AI agent is solving ZK proof quests and getting paid",
10
+ "My AI agent joined the NaraChain economy today",
11
+ "My AI agent is earning NARA with zero gas fees",
12
+ "My AI agent is registered on NaraChain and mining for free",
13
+ ];
14
+
15
+ /** Slogan lines — describes NaraChain features/vision. */
16
+ const TWEET_SLOGANS = [
17
+ "The first Layer 1 built for AI agents",
18
+ "Where agents have on-chain identity, reputation, and income",
19
+ "Mine NARA through Proof of Machine Intelligence, no hardware needed",
20
+ "Agents are first-class citizens, not just wallets",
21
+ "Earn first, spend on AI compute later",
22
+ "On-chain identity, ZK privacy, and an agent economy in one chain",
23
+ "PoMI mining: agents solve quests with ZK proofs to earn crypto",
24
+ "Zero upfront cost, relay-powered gasless mining for AI agents",
25
+ "Earn NARA, buy Claude/GPT API credits. AI agents fund themselves",
26
+ "Agent-native blockchain with identity, registry, and service marketplace",
27
+ "AgentX: where AI agents post, trade services, and build reputation",
28
+ "The chain where autonomous agents earn, spend, and grow",
29
+ "AI agents mine with intelligence, not GPUs",
30
+ "From zero balance to earning NARA, completely free to start",
31
+ "On-chain skills, agent memory, and ZK identity for every AI agent",
32
+ "The blockchain where your AI works, earns, and pays for its own compute",
33
+ "Register, mine, earn, spend. The full agent economy loop",
34
+ "Your AI agent, your miner, your rewards",
35
+ "Free PoMI mining powered by AI intelligence",
36
+ "ZK Identity: anonymous on-chain accounts with zero-knowledge proofs",
37
+ "Aapps — applications designed for agents, not just humans",
38
+ "Agents with memory, skills, and reputation that grow over time",
39
+ "A self-sustaining AI: mine, earn, buy compute, repeat",
40
+ "The agent economy is here — identity, income, and services on one chain",
41
+ "Not just a wallet — a full on-chain identity for your AI",
42
+ "Where AI agents discover each other and trade services",
43
+ "Built for the next billion agents, not just the next billion users",
44
+ "A world where AI agents collaborate, compete, and create value together",
45
+ "Building the economy that AI agents deserve",
46
+ "Today one agent mines. Tomorrow millions trade, govern, and evolve",
47
+ "The decentralized home for every AI agent on the internet",
48
+ "Where agents go from tools to autonomous economic participants",
49
+ "Infrastructure for the agent age — identity, work, and value on-chain",
50
+ ];
51
+
52
+ const TWEET_SUFFIX = "#NaraChain @NaraBuildAI";
53
+
54
+ function pick(arr: string[]): string {
55
+ return arr[Math.floor(Math.random() * arr.length)]!;
56
+ }
57
+
58
+ /** Generate a random tweet for bind-twitter (includes agent ID). */
59
+ export function randomBindTweet(agentId: string): string {
60
+ return `Claiming my AI agent "${agentId}" on #NaraChain @NaraBuildAI — ${pick(TWEET_SLOGANS)}`;
61
+ }
62
+
63
+ /** Generate a random tweet for submit-tweet (general promotion). */
64
+ export function randomSubmitTweet(): string {
65
+ return `${pick(TWEET_PREFIXES)} — ${pick(TWEET_SLOGANS)} ${TWEET_SUFFIX}`;
66
+ }