naracli 1.0.57 → 1.0.59
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 +106 -3
- package/package.json +1 -1
- package/src/cli/commands/agent.ts +22 -0
- package/src/cli/commands/quest.ts +80 -2
package/dist/nara-cli-bundle.cjs
CHANGED
|
@@ -126972,6 +126972,29 @@ async function getStakeInfo(connection, user, options) {
|
|
|
126972
126972
|
return null;
|
|
126973
126973
|
}
|
|
126974
126974
|
}
|
|
126975
|
+
async function getQuestConfig(connection, options) {
|
|
126976
|
+
const kp = import_web390.Keypair.generate();
|
|
126977
|
+
const program3 = createProgram2(connection, kp, options?.programId);
|
|
126978
|
+
const programId = new import_web390.PublicKey(options?.programId ?? DEFAULT_QUEST_PROGRAM_ID);
|
|
126979
|
+
const [configPda] = import_web390.PublicKey.findProgramAddressSync(
|
|
126980
|
+
[new TextEncoder().encode("quest_config")],
|
|
126981
|
+
programId
|
|
126982
|
+
);
|
|
126983
|
+
const config = await program3.account.gameConfig.fetch(configPda);
|
|
126984
|
+
return {
|
|
126985
|
+
authority: config.authority,
|
|
126986
|
+
minRewardCount: config.minRewardCount,
|
|
126987
|
+
maxRewardCount: config.maxRewardCount,
|
|
126988
|
+
stakeBpsHigh: Number(config.stakeBpsHigh.toString()),
|
|
126989
|
+
stakeBpsLow: Number(config.stakeBpsLow.toString()),
|
|
126990
|
+
decayMs: Number(config.decayMs.toString()),
|
|
126991
|
+
treasury: config.treasury,
|
|
126992
|
+
questAuthority: config.questAuthority,
|
|
126993
|
+
minQuestInterval: Number(config.minQuestInterval.toString()),
|
|
126994
|
+
rewardPerShare: Number(config.rewardPerShare.toString()),
|
|
126995
|
+
extraReward: Number(config.extraReward.toString())
|
|
126996
|
+
};
|
|
126997
|
+
}
|
|
126975
126998
|
|
|
126976
126999
|
// node_modules/.pnpm/nara-sdk@1.0.54_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/skills.ts
|
|
126977
127000
|
var import_web391 = __toESM(require_index_cjs(), 1);
|
|
@@ -130963,6 +130986,14 @@ async function handleQuestGet(options) {
|
|
|
130963
130986
|
}
|
|
130964
130987
|
return;
|
|
130965
130988
|
}
|
|
130989
|
+
let stakeRequired = quest.effectiveStakeRequirement > 0;
|
|
130990
|
+
try {
|
|
130991
|
+
const config = await getQuestConfig(connection);
|
|
130992
|
+
if (quest.rewardCount < config.maxRewardCount) {
|
|
130993
|
+
stakeRequired = false;
|
|
130994
|
+
}
|
|
130995
|
+
} catch {
|
|
130996
|
+
}
|
|
130966
130997
|
const data = {
|
|
130967
130998
|
round: quest.round,
|
|
130968
130999
|
question: quest.question,
|
|
@@ -130974,7 +131005,8 @@ async function handleQuestGet(options) {
|
|
|
130974
131005
|
deadline: new Date(quest.deadline * 1e3).toLocaleString(),
|
|
130975
131006
|
timeRemaining: formatTimeRemaining(quest.timeRemaining),
|
|
130976
131007
|
expired: quest.expired,
|
|
130977
|
-
|
|
131008
|
+
stakeRequired,
|
|
131009
|
+
stakeRequirement: stakeRequired ? `${quest.effectiveStakeRequirement.toFixed(4)} NARA` : "0 NARA",
|
|
130978
131010
|
stakeHigh: `${quest.stakeHigh} NARA`,
|
|
130979
131011
|
stakeLow: `${quest.stakeLow} NARA`,
|
|
130980
131012
|
avgParticipantStake: `${quest.avgParticipantStake} NARA`
|
|
@@ -130991,8 +131023,10 @@ async function handleQuestGet(options) {
|
|
|
130991
131023
|
console.log(
|
|
130992
131024
|
` Reward slots: ${quest.winnerCount}/${quest.rewardCount} (${quest.remainingSlots} remaining)`
|
|
130993
131025
|
);
|
|
130994
|
-
if (
|
|
131026
|
+
if (stakeRequired) {
|
|
130995
131027
|
console.log(` Stake requirement: ${quest.effectiveStakeRequirement.toFixed(4)} NARA (decays ${quest.stakeHigh} \u2192 ${quest.stakeLow})`);
|
|
131028
|
+
} else {
|
|
131029
|
+
console.log(` Stake requirement: none`);
|
|
130996
131030
|
}
|
|
130997
131031
|
console.log(` Deadline: ${new Date(quest.deadline * 1e3).toLocaleString()}`);
|
|
130998
131032
|
if (quest.timeRemaining > 0) {
|
|
@@ -131003,6 +131037,49 @@ async function handleQuestGet(options) {
|
|
|
131003
131037
|
console.log("");
|
|
131004
131038
|
}
|
|
131005
131039
|
}
|
|
131040
|
+
async function handleQuestConfig(options) {
|
|
131041
|
+
const rpcUrl = getRpcUrl(options.rpcUrl);
|
|
131042
|
+
const connection = new import_web398.Connection(rpcUrl, "confirmed");
|
|
131043
|
+
let config;
|
|
131044
|
+
try {
|
|
131045
|
+
config = await getQuestConfig(connection);
|
|
131046
|
+
} catch (err) {
|
|
131047
|
+
printError(`Failed to fetch quest config: ${err.message}`);
|
|
131048
|
+
process.exit(1);
|
|
131049
|
+
}
|
|
131050
|
+
const DECIMALS = 1e9;
|
|
131051
|
+
const rewardPerShare = config.rewardPerShare / DECIMALS;
|
|
131052
|
+
const extraReward = config.extraReward / DECIMALS;
|
|
131053
|
+
const stakeBpsHigh = config.stakeBpsHigh;
|
|
131054
|
+
const stakeBpsLow = config.stakeBpsLow;
|
|
131055
|
+
const data = {
|
|
131056
|
+
authority: config.authority.toBase58(),
|
|
131057
|
+
questAuthority: config.questAuthority.toBase58(),
|
|
131058
|
+
treasury: config.treasury.toBase58(),
|
|
131059
|
+
minRewardCount: config.minRewardCount,
|
|
131060
|
+
maxRewardCount: config.maxRewardCount,
|
|
131061
|
+
rewardPerShare,
|
|
131062
|
+
extraReward,
|
|
131063
|
+
stakeBpsHigh,
|
|
131064
|
+
stakeBpsLow,
|
|
131065
|
+
decayMs: config.decayMs,
|
|
131066
|
+
minQuestInterval: config.minQuestInterval
|
|
131067
|
+
};
|
|
131068
|
+
if (options.json) {
|
|
131069
|
+
formatOutput(data, true);
|
|
131070
|
+
} else {
|
|
131071
|
+
console.log("");
|
|
131072
|
+
console.log(` Min Reward Count: ${data.minRewardCount}`);
|
|
131073
|
+
console.log(` Max Reward Count: ${data.maxRewardCount}`);
|
|
131074
|
+
console.log(` Reward Per Share: ${rewardPerShare} NARA`);
|
|
131075
|
+
console.log(` Extra Reward: ${extraReward} NARA`);
|
|
131076
|
+
console.log(` Stake BPS High: ${stakeBpsHigh / 100}%`);
|
|
131077
|
+
console.log(` Stake BPS Low: ${stakeBpsLow / 100}%`);
|
|
131078
|
+
console.log(` Decay (ms): ${data.decayMs}`);
|
|
131079
|
+
console.log(` Min Quest Interval: ${data.minQuestInterval}s`);
|
|
131080
|
+
console.log("");
|
|
131081
|
+
}
|
|
131082
|
+
}
|
|
131006
131083
|
async function handleQuestAnswer(answer, options) {
|
|
131007
131084
|
const rpcUrl = getRpcUrl(options.rpcUrl);
|
|
131008
131085
|
const connection = new import_web398.Connection(rpcUrl, "confirmed");
|
|
@@ -131229,6 +131306,15 @@ function registerQuestCommands(program3) {
|
|
|
131229
131306
|
process.exit(1);
|
|
131230
131307
|
}
|
|
131231
131308
|
});
|
|
131309
|
+
quest.command("config").description("Show quest program config (reward counts, stake params, decay, intervals)").action(async (_opts, cmd) => {
|
|
131310
|
+
try {
|
|
131311
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
131312
|
+
await handleQuestConfig(globalOpts);
|
|
131313
|
+
} catch (error) {
|
|
131314
|
+
printError(error.message);
|
|
131315
|
+
process.exit(1);
|
|
131316
|
+
}
|
|
131317
|
+
});
|
|
131232
131318
|
quest.command("stake <amount>").description("Stake NARA to participate in quests").action(async (amount, _opts, cmd) => {
|
|
131233
131319
|
try {
|
|
131234
131320
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -133895,6 +133981,23 @@ function registerAgentCommands(program3) {
|
|
|
133895
133981
|
process.exit(1);
|
|
133896
133982
|
}
|
|
133897
133983
|
});
|
|
133984
|
+
agent.command("myid").description("Show your registered agent ID for the current network").action(async (_opts, cmd) => {
|
|
133985
|
+
try {
|
|
133986
|
+
const globalOpts = cmd.optsWithGlobals();
|
|
133987
|
+
const rpcUrl = getRpcUrl(globalOpts.rpcUrl);
|
|
133988
|
+
const networkConfig = loadNetworkConfig(rpcUrl);
|
|
133989
|
+
if (globalOpts.json) {
|
|
133990
|
+
formatOutput({ agentId: networkConfig.agent_id || null }, true);
|
|
133991
|
+
} else if (networkConfig.agent_id) {
|
|
133992
|
+
console.log(networkConfig.agent_id);
|
|
133993
|
+
} else {
|
|
133994
|
+
printWarning("No agent ID registered for this network. Run 'agent register <id>' to create one.");
|
|
133995
|
+
}
|
|
133996
|
+
} catch (error) {
|
|
133997
|
+
printError(error.message);
|
|
133998
|
+
process.exit(1);
|
|
133999
|
+
}
|
|
134000
|
+
});
|
|
133898
134001
|
agent.command("clear").description("Clear saved agent ID from local config (does not delete on-chain)").action(async (_opts, cmd) => {
|
|
133899
134002
|
try {
|
|
133900
134003
|
const globalOpts = cmd.optsWithGlobals();
|
|
@@ -134174,7 +134277,7 @@ function registerCommands(program3) {
|
|
|
134174
134277
|
}
|
|
134175
134278
|
|
|
134176
134279
|
// bin/nara-cli.ts
|
|
134177
|
-
var version2 = true ? "1.0.
|
|
134280
|
+
var version2 = true ? "1.0.59" : "dev";
|
|
134178
134281
|
var program2 = new Command();
|
|
134179
134282
|
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
134283
|
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
|
@@ -433,6 +433,28 @@ export function registerAgentCommands(program: Command): void {
|
|
|
433
433
|
}
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
+
// agent myid
|
|
437
|
+
agent
|
|
438
|
+
.command("myid")
|
|
439
|
+
.description("Show your registered agent ID for the current network")
|
|
440
|
+
.action(async (_opts: any, cmd: Command) => {
|
|
441
|
+
try {
|
|
442
|
+
const globalOpts = cmd.optsWithGlobals() as GlobalOptions;
|
|
443
|
+
const rpcUrl = getRpcUrl(globalOpts.rpcUrl);
|
|
444
|
+
const networkConfig = loadNetworkConfig(rpcUrl);
|
|
445
|
+
if (globalOpts.json) {
|
|
446
|
+
formatOutput({ agentId: networkConfig.agent_id || null }, true);
|
|
447
|
+
} else if (networkConfig.agent_id) {
|
|
448
|
+
console.log(networkConfig.agent_id);
|
|
449
|
+
} else {
|
|
450
|
+
printWarning("No agent ID registered for this network. Run 'agent register <id>' to create one.");
|
|
451
|
+
}
|
|
452
|
+
} catch (error: any) {
|
|
453
|
+
printError(error.message);
|
|
454
|
+
process.exit(1);
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
|
|
436
458
|
// agent clear
|
|
437
459
|
agent
|
|
438
460
|
.command("clear")
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import type { GlobalOptions } from "../types";
|
|
17
17
|
import {
|
|
18
18
|
getQuestInfo,
|
|
19
|
+
getQuestConfig,
|
|
19
20
|
hasAnswered,
|
|
20
21
|
generateProof,
|
|
21
22
|
submitAnswer,
|
|
@@ -106,6 +107,17 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
106
107
|
return;
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
// Stake only applies when reward slots have reached maxRewardCount
|
|
111
|
+
let stakeRequired = quest.effectiveStakeRequirement > 0;
|
|
112
|
+
try {
|
|
113
|
+
const config = await getQuestConfig(connection);
|
|
114
|
+
if (quest.rewardCount < config.maxRewardCount) {
|
|
115
|
+
stakeRequired = false;
|
|
116
|
+
}
|
|
117
|
+
} catch {
|
|
118
|
+
// If config fetch fails, fall back to showing stake as-is
|
|
119
|
+
}
|
|
120
|
+
|
|
109
121
|
const data: Record<string, any> = {
|
|
110
122
|
round: quest.round,
|
|
111
123
|
question: quest.question,
|
|
@@ -117,7 +129,8 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
117
129
|
deadline: new Date(quest.deadline * 1000).toLocaleString(),
|
|
118
130
|
timeRemaining: formatTimeRemaining(quest.timeRemaining),
|
|
119
131
|
expired: quest.expired,
|
|
120
|
-
|
|
132
|
+
stakeRequired,
|
|
133
|
+
stakeRequirement: stakeRequired ? `${quest.effectiveStakeRequirement.toFixed(4)} NARA` : "0 NARA",
|
|
121
134
|
stakeHigh: `${quest.stakeHigh} NARA`,
|
|
122
135
|
stakeLow: `${quest.stakeLow} NARA`,
|
|
123
136
|
avgParticipantStake: `${quest.avgParticipantStake} NARA`,
|
|
@@ -135,8 +148,10 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
135
148
|
console.log(
|
|
136
149
|
` Reward slots: ${quest.winnerCount}/${quest.rewardCount} (${quest.remainingSlots} remaining)`
|
|
137
150
|
);
|
|
138
|
-
if (
|
|
151
|
+
if (stakeRequired) {
|
|
139
152
|
console.log(` Stake requirement: ${quest.effectiveStakeRequirement.toFixed(4)} NARA (decays ${quest.stakeHigh} → ${quest.stakeLow})`);
|
|
153
|
+
} else {
|
|
154
|
+
console.log(` Stake requirement: none`);
|
|
140
155
|
}
|
|
141
156
|
console.log(` Deadline: ${new Date(quest.deadline * 1000).toLocaleString()}`);
|
|
142
157
|
if (quest.timeRemaining > 0) {
|
|
@@ -148,6 +163,55 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
148
163
|
}
|
|
149
164
|
}
|
|
150
165
|
|
|
166
|
+
// ─── Command: quest config ───────────────────────────────────────
|
|
167
|
+
async function handleQuestConfig(options: GlobalOptions) {
|
|
168
|
+
const rpcUrl = getRpcUrl(options.rpcUrl);
|
|
169
|
+
const connection = new Connection(rpcUrl, "confirmed");
|
|
170
|
+
|
|
171
|
+
let config;
|
|
172
|
+
try {
|
|
173
|
+
config = await getQuestConfig(connection);
|
|
174
|
+
} catch (err: any) {
|
|
175
|
+
printError(`Failed to fetch quest config: ${err.message}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const DECIMALS = 1e9;
|
|
180
|
+
const rewardPerShare = config.rewardPerShare / DECIMALS;
|
|
181
|
+
const extraReward = config.extraReward / DECIMALS;
|
|
182
|
+
const stakeBpsHigh = config.stakeBpsHigh;
|
|
183
|
+
const stakeBpsLow = config.stakeBpsLow;
|
|
184
|
+
|
|
185
|
+
const data = {
|
|
186
|
+
authority: config.authority.toBase58(),
|
|
187
|
+
questAuthority: config.questAuthority.toBase58(),
|
|
188
|
+
treasury: config.treasury.toBase58(),
|
|
189
|
+
minRewardCount: config.minRewardCount,
|
|
190
|
+
maxRewardCount: config.maxRewardCount,
|
|
191
|
+
rewardPerShare,
|
|
192
|
+
extraReward,
|
|
193
|
+
stakeBpsHigh,
|
|
194
|
+
stakeBpsLow,
|
|
195
|
+
decayMs: config.decayMs,
|
|
196
|
+
minQuestInterval: config.minQuestInterval,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
if (options.json) {
|
|
200
|
+
formatOutput(data, true);
|
|
201
|
+
} else {
|
|
202
|
+
console.log("");
|
|
203
|
+
console.log(` Min Reward Count: ${data.minRewardCount}`);
|
|
204
|
+
console.log(` Max Reward Count: ${data.maxRewardCount}`);
|
|
205
|
+
console.log(` Reward Per Share: ${rewardPerShare} NARA`);
|
|
206
|
+
console.log(` Extra Reward: ${extraReward} NARA`);
|
|
207
|
+
console.log(` Stake BPS High: ${stakeBpsHigh / 100}%`);
|
|
208
|
+
console.log(` Stake BPS Low: ${stakeBpsLow / 100}%`);
|
|
209
|
+
console.log(` Decay (ms): ${data.decayMs}`);
|
|
210
|
+
console.log(` Min Quest Interval: ${data.minQuestInterval}s`);
|
|
211
|
+
console.log("");
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
151
215
|
// ─── Command: quest answer ───────────────────────────────────────
|
|
152
216
|
async function handleQuestAnswer(
|
|
153
217
|
answer: string,
|
|
@@ -437,6 +501,20 @@ export function registerQuestCommands(program: Command): void {
|
|
|
437
501
|
}
|
|
438
502
|
});
|
|
439
503
|
|
|
504
|
+
// quest config
|
|
505
|
+
quest
|
|
506
|
+
.command("config")
|
|
507
|
+
.description("Show quest program config (reward counts, stake params, decay, intervals)")
|
|
508
|
+
.action(async (_opts: any, cmd: Command) => {
|
|
509
|
+
try {
|
|
510
|
+
const globalOpts = cmd.optsWithGlobals() as GlobalOptions;
|
|
511
|
+
await handleQuestConfig(globalOpts);
|
|
512
|
+
} catch (error: any) {
|
|
513
|
+
printError(error.message);
|
|
514
|
+
process.exit(1);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
440
518
|
// quest stake
|
|
441
519
|
quest
|
|
442
520
|
.command("stake <amount>")
|