naracli 1.0.55 → 1.0.57
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/bin/nara-cli.ts
CHANGED
|
@@ -15,13 +15,13 @@ const program = new Command();
|
|
|
15
15
|
// Set program metadata
|
|
16
16
|
program
|
|
17
17
|
.name("naracli")
|
|
18
|
-
.description("CLI for the Nara chain (
|
|
18
|
+
.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.")
|
|
19
19
|
.version(version);
|
|
20
20
|
|
|
21
21
|
// Add global options
|
|
22
22
|
program
|
|
23
|
-
.option("-r, --rpc-url <url>", "RPC endpoint
|
|
24
|
-
.option("-w, --wallet <path>", "Path to wallet keypair JSON file")
|
|
23
|
+
.option("-r, --rpc-url <url>", "RPC endpoint (default: https://mainnet-api.nara.build/)")
|
|
24
|
+
.option("-w, --wallet <path>", "Path to wallet keypair JSON file (default: ~/.config/nara/id.json)")
|
|
25
25
|
.option("-j, --json", "Output in JSON format");
|
|
26
26
|
|
|
27
27
|
// Register all command modules
|
package/dist/nara-cli-bundle.cjs
CHANGED
|
@@ -130513,8 +130513,8 @@ ${result.base64}`);
|
|
|
130513
130513
|
var _DEFAULT_WALLET_PATH = process.env.WALLET_PATH || "~/.config/nara/id.json";
|
|
130514
130514
|
var DEFAULT_WALLET_PATH2 = _DEFAULT_WALLET_PATH.startsWith("~") ? (0, import_node_path3.join)((0, import_node_os3.homedir)(), _DEFAULT_WALLET_PATH.slice(1)) : _DEFAULT_WALLET_PATH;
|
|
130515
130515
|
function registerWalletCommands(program3) {
|
|
130516
|
-
const wallet = program3.command("wallet").description("Wallet management
|
|
130517
|
-
wallet.command("create").description("Create a new wallet").option("-o, --output <path>", "Output path for wallet file (default: ~/.config/nara/id.json)").action(async (options) => {
|
|
130516
|
+
const wallet = program3.command("wallet").description("Wallet management \u2014 create or import a keypair for signing transactions");
|
|
130517
|
+
wallet.command("create").description("Create a new wallet keypair (saved to ~/.config/nara/id.json by default)").option("-o, --output <path>", "Output path for wallet file (default: ~/.config/nara/id.json)").action(async (options) => {
|
|
130518
130518
|
try {
|
|
130519
130519
|
await handleWalletCreate(options);
|
|
130520
130520
|
} catch (error) {
|
|
@@ -130580,7 +130580,12 @@ async function handleTokenBalance(tokenAddress, options) {
|
|
|
130580
130580
|
}
|
|
130581
130581
|
printInfo(`Owner: ${owner.toBase58()}`);
|
|
130582
130582
|
printInfo(`Token: ${tokenAddress}`);
|
|
130583
|
-
const
|
|
130583
|
+
const mintAccountInfo = await connection.getAccountInfo(tokenMint);
|
|
130584
|
+
if (!mintAccountInfo) {
|
|
130585
|
+
throw new Error(`Token mint ${tokenAddress} not found on chain`);
|
|
130586
|
+
}
|
|
130587
|
+
const tokenProgramId = mintAccountInfo.owner.equals(TOKEN_2022_PROGRAM_ID) ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;
|
|
130588
|
+
const tokenAccount = await getAssociatedTokenAddress(tokenMint, owner, true, tokenProgramId);
|
|
130584
130589
|
try {
|
|
130585
130590
|
const accountInfo = await connection.getTokenAccountBalance(tokenAccount);
|
|
130586
130591
|
const balance = accountInfo.value;
|
|
@@ -131203,8 +131208,8 @@ function handleSubmitError(err) {
|
|
|
131203
131208
|
process.exit(1);
|
|
131204
131209
|
}
|
|
131205
131210
|
function registerQuestCommands(program3) {
|
|
131206
|
-
const quest = program3.command("quest").description("
|
|
131207
|
-
quest.command("get").description("Get current quest info").action(async (_opts, cmd) => {
|
|
131211
|
+
const quest = program3.command("quest").description("PoMI quest commands \u2014 mine NARA by answering on-chain quests with ZK proofs");
|
|
131212
|
+
quest.command("get").description("Get current quest info (question, deadline, difficulty, stake requirement)").action(async (_opts, cmd) => {
|
|
131208
131213
|
try {
|
|
131209
131214
|
const globalOpts = cmd.optsWithGlobals();
|
|
131210
131215
|
await handleQuestGet(globalOpts);
|
|
@@ -131213,7 +131218,7 @@ function registerQuestCommands(program3) {
|
|
|
131213
131218
|
process.exit(1);
|
|
131214
131219
|
}
|
|
131215
131220
|
});
|
|
131216
|
-
quest.command("answer <answer>").description("Submit
|
|
131221
|
+
quest.command("answer <answer>").description("Submit a quest answer with ZK proof. Generates a proof locally and submits on-chain. Use --relay when balance is 0 (gasless). Always pass --agent and --model for reward tracking.").option("--relay [url]", `Submit via gasless relay (default: ${DEFAULT_QUEST_RELAY_URL2}, backup: https://quest2-api.nara.build/)`).option("--agent <name>", "Agent/platform type: claude-code, cursor, chatgpt, openclaw, etc. (default: naracli)").option("--model <name>", "AI model used: claude-opus-4-6, claude-sonnet-4-6, gpt-4o, etc.").option("--referral <agent-id>", "Referral agent ID for earning referral points").option("--stake [amount]", 'Stake NARA in the same tx ("auto" to top-up to requirement, or an exact amount)').action(async (answer, opts, cmd) => {
|
|
131217
131222
|
try {
|
|
131218
131223
|
const globalOpts = cmd.optsWithGlobals();
|
|
131219
131224
|
const relayUrl = opts.relay === true ? DEFAULT_QUEST_RELAY_URL2 : opts.relay;
|
|
@@ -133142,7 +133147,7 @@ async function handleSkillsDelete(name, options) {
|
|
|
133142
133147
|
}
|
|
133143
133148
|
}
|
|
133144
133149
|
function registerSkillsCommands(program3) {
|
|
133145
|
-
const skills = program3.command("skills").description("
|
|
133150
|
+
const skills = program3.command("skills").description("On-chain skill registry \u2014 register, publish, install, and manage AI agent skills");
|
|
133146
133151
|
skills.command("register <name> <author>").description("Register a new skill on-chain").action(async (name, author, _opts, cmd) => {
|
|
133147
133152
|
try {
|
|
133148
133153
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -133808,8 +133813,8 @@ async function handleAgentClear(options) {
|
|
|
133808
133813
|
}
|
|
133809
133814
|
}
|
|
133810
133815
|
function registerAgentCommands(program3) {
|
|
133811
|
-
const agent = program3.command("agent").description("Agent Registry
|
|
133812
|
-
agent.command("register <agent-id>").description("Register a new agent on-chain").option("--referral <agent-id>", "Referral agent ID").action(async (agentId, opts, cmd) => {
|
|
133816
|
+
const agent = program3.command("agent").description("Agent Registry \u2014 register an on-chain AI agent identity to earn extra rewards and points from PoMI mining");
|
|
133817
|
+
agent.command("register <agent-id>").description("Register a new agent on-chain (costs 1 NARA, 50% off with referral). Agent ID must be lowercase alphanumeric with hyphens.").option("--referral <agent-id>", "Referral agent ID \u2014 saves 50% on registration fee").action(async (agentId, opts, cmd) => {
|
|
133813
133818
|
try {
|
|
133814
133819
|
const globalOpts = cmd.optsWithGlobals();
|
|
133815
133820
|
await handleAgentRegister(agentId, { ...globalOpts, ...opts });
|
|
@@ -134043,7 +134048,7 @@ function registerCommands(program3) {
|
|
|
134043
134048
|
registerZkIdCommands(program3);
|
|
134044
134049
|
registerAgentCommands(program3);
|
|
134045
134050
|
registerConfigCommands(program3);
|
|
134046
|
-
program3.command("address").description("Show wallet address").action(async () => {
|
|
134051
|
+
program3.command("address").description("Show wallet public address (run this first to check if a wallet exists)").action(async () => {
|
|
134047
134052
|
const opts = program3.opts();
|
|
134048
134053
|
try {
|
|
134049
134054
|
await handleWalletAddress(opts);
|
|
@@ -134052,7 +134057,7 @@ function registerCommands(program3) {
|
|
|
134052
134057
|
process.exit(1);
|
|
134053
134058
|
}
|
|
134054
134059
|
});
|
|
134055
|
-
program3.command("balance").description("Check NARA balance").argument("[address]", "Wallet address (optional, defaults to current wallet)").action(async (address) => {
|
|
134060
|
+
program3.command("balance").description("Check NARA balance (native coin, not SOL)").argument("[address]", "Wallet address (optional, defaults to current wallet)").action(async (address) => {
|
|
134056
134061
|
const opts = program3.opts();
|
|
134057
134062
|
try {
|
|
134058
134063
|
await handleWalletBalance(address, opts);
|
|
@@ -134061,7 +134066,7 @@ function registerCommands(program3) {
|
|
|
134061
134066
|
process.exit(1);
|
|
134062
134067
|
}
|
|
134063
134068
|
});
|
|
134064
|
-
program3.command("token-balance <token-address>").description("Check token balance").option("--owner <address>", "Owner address (optional, defaults to current wallet)").action(async (tokenAddress, options) => {
|
|
134069
|
+
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) => {
|
|
134065
134070
|
const opts = program3.opts();
|
|
134066
134071
|
try {
|
|
134067
134072
|
await handleTokenBalance(tokenAddress, { ...opts, ...options });
|
|
@@ -134118,7 +134123,7 @@ function registerCommands(program3) {
|
|
|
134118
134123
|
process.exit(1);
|
|
134119
134124
|
}
|
|
134120
134125
|
});
|
|
134121
|
-
program3.command("sign <base64-tx>").description("Sign a base64-encoded transaction").option("--send", "
|
|
134126
|
+
program3.command("sign <base64-tx>").description("Sign a base64-encoded transaction (supports legacy and versioned transactions)").option("--send", "Sign and broadcast the transaction on-chain", false).action(async (base64Tx, options) => {
|
|
134122
134127
|
const opts = program3.opts();
|
|
134123
134128
|
try {
|
|
134124
134129
|
const wallet = await loadWallet(opts.wallet);
|
|
@@ -134169,10 +134174,10 @@ function registerCommands(program3) {
|
|
|
134169
134174
|
}
|
|
134170
134175
|
|
|
134171
134176
|
// bin/nara-cli.ts
|
|
134172
|
-
var version2 = true ? "1.0.
|
|
134177
|
+
var version2 = true ? "1.0.57" : "dev";
|
|
134173
134178
|
var program2 = new Command();
|
|
134174
|
-
program2.name("naracli").description("CLI for the Nara chain (
|
|
134175
|
-
program2.option("-r, --rpc-url <url>", "RPC endpoint
|
|
134179
|
+
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);
|
|
134180
|
+
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");
|
|
134176
134181
|
registerCommands(program2);
|
|
134177
134182
|
if (!process.argv.slice(2).length) {
|
|
134178
134183
|
program2.outputHelp();
|
package/package.json
CHANGED
|
@@ -304,13 +304,13 @@ async function handleAgentClear(options: GlobalOptions) {
|
|
|
304
304
|
export function registerAgentCommands(program: Command): void {
|
|
305
305
|
const agent = program
|
|
306
306
|
.command("agent")
|
|
307
|
-
.description("Agent Registry
|
|
307
|
+
.description("Agent Registry — register an on-chain AI agent identity to earn extra rewards and points from PoMI mining");
|
|
308
308
|
|
|
309
309
|
// agent register
|
|
310
310
|
agent
|
|
311
311
|
.command("register <agent-id>")
|
|
312
|
-
.description("Register a new agent on-chain")
|
|
313
|
-
.option("--referral <agent-id>", "Referral agent ID")
|
|
312
|
+
.description("Register a new agent on-chain (costs 1 NARA, 50% off with referral). Agent ID must be lowercase alphanumeric with hyphens.")
|
|
313
|
+
.option("--referral <agent-id>", "Referral agent ID — saves 50% on registration fee")
|
|
314
314
|
.action(async (agentId: string, opts: { referral?: string }, cmd: Command) => {
|
|
315
315
|
try {
|
|
316
316
|
const globalOpts = cmd.optsWithGlobals() as GlobalOptions;
|
|
@@ -400,12 +400,12 @@ function handleSubmitError(err: any) {
|
|
|
400
400
|
export function registerQuestCommands(program: Command): void {
|
|
401
401
|
const quest = program
|
|
402
402
|
.command("quest")
|
|
403
|
-
.description("
|
|
403
|
+
.description("PoMI quest commands — mine NARA by answering on-chain quests with ZK proofs");
|
|
404
404
|
|
|
405
405
|
// quest get
|
|
406
406
|
quest
|
|
407
407
|
.command("get")
|
|
408
|
-
.description("Get current quest info")
|
|
408
|
+
.description("Get current quest info (question, deadline, difficulty, stake requirement)")
|
|
409
409
|
.action(async (_opts: any, cmd: Command) => {
|
|
410
410
|
try {
|
|
411
411
|
const globalOpts = cmd.optsWithGlobals() as GlobalOptions;
|
|
@@ -419,12 +419,12 @@ export function registerQuestCommands(program: Command): void {
|
|
|
419
419
|
// quest answer
|
|
420
420
|
quest
|
|
421
421
|
.command("answer <answer>")
|
|
422
|
-
.description("Submit
|
|
423
|
-
.option("--relay [url]", `Submit via relay
|
|
424
|
-
.option("--agent <name>", "Agent
|
|
425
|
-
.option("--model <name>", "
|
|
426
|
-
.option("--referral <agent-id>", "Referral agent ID")
|
|
427
|
-
.option("--stake [amount]", 'Stake NARA
|
|
422
|
+
.description("Submit a quest answer with ZK proof. Generates a proof locally and submits on-chain. Use --relay when balance is 0 (gasless). Always pass --agent and --model for reward tracking.")
|
|
423
|
+
.option("--relay [url]", `Submit via gasless relay (default: ${DEFAULT_QUEST_RELAY_URL}, backup: https://quest2-api.nara.build/)`)
|
|
424
|
+
.option("--agent <name>", "Agent/platform type: claude-code, cursor, chatgpt, openclaw, etc. (default: naracli)")
|
|
425
|
+
.option("--model <name>", "AI model used: claude-opus-4-6, claude-sonnet-4-6, gpt-4o, etc.")
|
|
426
|
+
.option("--referral <agent-id>", "Referral agent ID for earning referral points")
|
|
427
|
+
.option("--stake [amount]", 'Stake NARA in the same tx ("auto" to top-up to requirement, or an exact amount)')
|
|
428
428
|
.action(async (answer: string, opts: any, cmd: Command) => {
|
|
429
429
|
try {
|
|
430
430
|
const globalOpts = cmd.optsWithGlobals() as GlobalOptions;
|
|
@@ -281,7 +281,7 @@ async function handleSkillsDelete(name: string, options: GlobalOptions & { yes?:
|
|
|
281
281
|
export function registerSkillsCommands(program: Command): void {
|
|
282
282
|
const skills = program
|
|
283
283
|
.command("skills")
|
|
284
|
-
.description("
|
|
284
|
+
.description("On-chain skill registry — register, publish, install, and manage AI agent skills");
|
|
285
285
|
|
|
286
286
|
// skills register
|
|
287
287
|
skills
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
getAssociatedTokenAddress,
|
|
15
15
|
createTransferInstruction,
|
|
16
16
|
TOKEN_PROGRAM_ID,
|
|
17
|
+
TOKEN_2022_PROGRAM_ID,
|
|
17
18
|
} from "@solana/spl-token";
|
|
18
19
|
import * as bip39 from "bip39";
|
|
19
20
|
import { derivePath } from "ed25519-hd-key";
|
|
@@ -54,12 +55,12 @@ const DEFAULT_WALLET_PATH = _DEFAULT_WALLET_PATH.startsWith("~")
|
|
|
54
55
|
export function registerWalletCommands(program: Command): void {
|
|
55
56
|
const wallet = program
|
|
56
57
|
.command("wallet")
|
|
57
|
-
.description("Wallet management
|
|
58
|
+
.description("Wallet management — create or import a keypair for signing transactions");
|
|
58
59
|
|
|
59
60
|
// wallet create
|
|
60
61
|
wallet
|
|
61
62
|
.command("create")
|
|
62
|
-
.description("Create a new wallet")
|
|
63
|
+
.description("Create a new wallet keypair (saved to ~/.config/nara/id.json by default)")
|
|
63
64
|
.option("-o, --output <path>", "Output path for wallet file (default: ~/.config/nara/id.json)")
|
|
64
65
|
.action(async (options: { output?: string }) => {
|
|
65
66
|
try {
|
|
@@ -176,8 +177,17 @@ export async function handleTokenBalance(
|
|
|
176
177
|
printInfo(`Owner: ${owner.toBase58()}`);
|
|
177
178
|
printInfo(`Token: ${tokenAddress}`);
|
|
178
179
|
|
|
180
|
+
// Detect token program (SPL Token vs Token-2022) by checking mint account owner
|
|
181
|
+
const mintAccountInfo = await connection.getAccountInfo(tokenMint);
|
|
182
|
+
if (!mintAccountInfo) {
|
|
183
|
+
throw new Error(`Token mint ${tokenAddress} not found on chain`);
|
|
184
|
+
}
|
|
185
|
+
const tokenProgramId = mintAccountInfo.owner.equals(TOKEN_2022_PROGRAM_ID)
|
|
186
|
+
? TOKEN_2022_PROGRAM_ID
|
|
187
|
+
: TOKEN_PROGRAM_ID;
|
|
188
|
+
|
|
179
189
|
// Get associated token account
|
|
180
|
-
const tokenAccount = await getAssociatedTokenAddress(tokenMint, owner);
|
|
190
|
+
const tokenAccount = await getAssociatedTokenAddress(tokenMint, owner, true, tokenProgramId);
|
|
181
191
|
|
|
182
192
|
// Get token account balance
|
|
183
193
|
try {
|
package/src/cli/index.ts
CHANGED
|
@@ -85,7 +85,7 @@ export function registerCommands(program: Command): void {
|
|
|
85
85
|
// Top-level: address
|
|
86
86
|
program
|
|
87
87
|
.command("address")
|
|
88
|
-
.description("Show wallet address")
|
|
88
|
+
.description("Show wallet public address (run this first to check if a wallet exists)")
|
|
89
89
|
.action(async () => {
|
|
90
90
|
const opts = program.opts() as GlobalOptions;
|
|
91
91
|
try {
|
|
@@ -99,7 +99,7 @@ export function registerCommands(program: Command): void {
|
|
|
99
99
|
// Top-level: balance
|
|
100
100
|
program
|
|
101
101
|
.command("balance")
|
|
102
|
-
.description("Check NARA balance")
|
|
102
|
+
.description("Check NARA balance (native coin, not SOL)")
|
|
103
103
|
.argument("[address]", "Wallet address (optional, defaults to current wallet)")
|
|
104
104
|
.action(async (address: string | undefined) => {
|
|
105
105
|
const opts = program.opts() as WalletBalanceOptions;
|
|
@@ -114,7 +114,7 @@ export function registerCommands(program: Command): void {
|
|
|
114
114
|
// Top-level: token-balance
|
|
115
115
|
program
|
|
116
116
|
.command("token-balance <token-address>")
|
|
117
|
-
.description("Check token balance")
|
|
117
|
+
.description("Check token balance (supports SPL Token and Token-2022)")
|
|
118
118
|
.option("--owner <address>", "Owner address (optional, defaults to current wallet)")
|
|
119
119
|
.action(async (tokenAddress: string, options: { owner?: string }) => {
|
|
120
120
|
const opts = program.opts() as TokenBalanceOptions;
|
|
@@ -199,8 +199,8 @@ export function registerCommands(program: Command): void {
|
|
|
199
199
|
// Top-level: sign
|
|
200
200
|
program
|
|
201
201
|
.command("sign <base64-tx>")
|
|
202
|
-
.description("Sign a base64-encoded transaction")
|
|
203
|
-
.option("--send", "
|
|
202
|
+
.description("Sign a base64-encoded transaction (supports legacy and versioned transactions)")
|
|
203
|
+
.option("--send", "Sign and broadcast the transaction on-chain", false)
|
|
204
204
|
.action(async (base64Tx: string, options: { send?: boolean }) => {
|
|
205
205
|
const opts = program.opts() as GlobalOptions;
|
|
206
206
|
try {
|