naracli 1.0.45 → 1.0.47
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 +312 -168
- package/package.json +3 -2
- package/src/cli/commands/quest.ts +21 -6
- package/src/tests/quest-relay.test.ts +91 -0
- package/src/tests/quest.test.ts +1 -1
package/dist/nara-cli-bundle.cjs
CHANGED
|
@@ -32114,7 +32114,7 @@ Message: ${transactionMessage}.
|
|
|
32114
32114
|
* @internal
|
|
32115
32115
|
*/
|
|
32116
32116
|
static checkProgramId(programId) {
|
|
32117
|
-
if (!programId.equals(
|
|
32117
|
+
if (!programId.equals(ComputeBudgetProgram2.programId)) {
|
|
32118
32118
|
throw new Error("invalid instruction; programId is not ComputeBudgetProgram");
|
|
32119
32119
|
}
|
|
32120
32120
|
}
|
|
@@ -32137,7 +32137,7 @@ Message: ${transactionMessage}.
|
|
|
32137
32137
|
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u8("instruction"), u642("microLamports")])
|
|
32138
32138
|
}
|
|
32139
32139
|
});
|
|
32140
|
-
var
|
|
32140
|
+
var ComputeBudgetProgram2 = class {
|
|
32141
32141
|
/**
|
|
32142
32142
|
* @internal
|
|
32143
32143
|
*/
|
|
@@ -32188,7 +32188,7 @@ Message: ${transactionMessage}.
|
|
|
32188
32188
|
});
|
|
32189
32189
|
}
|
|
32190
32190
|
};
|
|
32191
|
-
|
|
32191
|
+
ComputeBudgetProgram2.programId = new PublicKey30("ComputeBudget111111111111111111111111111111");
|
|
32192
32192
|
var PRIVATE_KEY_BYTES$1 = 64;
|
|
32193
32193
|
var PUBLIC_KEY_BYTES$1 = 32;
|
|
32194
32194
|
var SIGNATURE_BYTES = 64;
|
|
@@ -33688,7 +33688,7 @@ Message: ${transactionMessage}.
|
|
|
33688
33688
|
exports2.BpfLoader = BpfLoader;
|
|
33689
33689
|
exports2.COMPUTE_BUDGET_INSTRUCTION_LAYOUTS = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS;
|
|
33690
33690
|
exports2.ComputeBudgetInstruction = ComputeBudgetInstruction;
|
|
33691
|
-
exports2.ComputeBudgetProgram =
|
|
33691
|
+
exports2.ComputeBudgetProgram = ComputeBudgetProgram2;
|
|
33692
33692
|
exports2.Connection = Connection13;
|
|
33693
33693
|
exports2.Ed25519Program = Ed25519Program;
|
|
33694
33694
|
exports2.Enum = Enum;
|
|
@@ -33817,7 +33817,7 @@ var require_bindings = __commonJS({
|
|
|
33817
33817
|
var fs = require("fs");
|
|
33818
33818
|
var path = require("path");
|
|
33819
33819
|
var fileURLToPath = require_file_uri_to_path();
|
|
33820
|
-
var
|
|
33820
|
+
var join6 = path.join;
|
|
33821
33821
|
var dirname2 = path.dirname;
|
|
33822
33822
|
var exists = fs.accessSync && function(path2) {
|
|
33823
33823
|
try {
|
|
@@ -33877,7 +33877,7 @@ var require_bindings = __commonJS({
|
|
|
33877
33877
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
|
|
33878
33878
|
var tries = [], i = 0, l = opts.try.length, n, b, err;
|
|
33879
33879
|
for (; i < l; i++) {
|
|
33880
|
-
n =
|
|
33880
|
+
n = join6.apply(
|
|
33881
33881
|
null,
|
|
33882
33882
|
opts.try[i].map(function(p) {
|
|
33883
33883
|
return opts[p] || p;
|
|
@@ -33938,7 +33938,7 @@ var require_bindings = __commonJS({
|
|
|
33938
33938
|
if (dir === ".") {
|
|
33939
33939
|
dir = process.cwd();
|
|
33940
33940
|
}
|
|
33941
|
-
if (exists(
|
|
33941
|
+
if (exists(join6(dir, "package.json")) || exists(join6(dir, "node_modules"))) {
|
|
33942
33942
|
return dir;
|
|
33943
33943
|
}
|
|
33944
33944
|
if (prev === dir) {
|
|
@@ -33947,7 +33947,7 @@ var require_bindings = __commonJS({
|
|
|
33947
33947
|
);
|
|
33948
33948
|
}
|
|
33949
33949
|
prev = dir;
|
|
33950
|
-
dir =
|
|
33950
|
+
dir = join6(dir, "..");
|
|
33951
33951
|
}
|
|
33952
33952
|
};
|
|
33953
33953
|
}
|
|
@@ -60397,7 +60397,35 @@ async function loadAlt(connection) {
|
|
|
60397
60397
|
_cachedAltAddress = addr;
|
|
60398
60398
|
return _cachedAlt;
|
|
60399
60399
|
}
|
|
60400
|
+
async function getRecentPriorityFee(connection) {
|
|
60401
|
+
const fees = await connection.getRecentPrioritizationFees();
|
|
60402
|
+
if (!fees.length) return 0;
|
|
60403
|
+
const nonZero = fees.filter((f) => f.prioritizationFee > 0);
|
|
60404
|
+
if (!nonZero.length) return 0;
|
|
60405
|
+
const avg = nonZero.reduce((s, f) => s + f.prioritizationFee, 0) / nonZero.length;
|
|
60406
|
+
return Math.ceil(avg);
|
|
60407
|
+
}
|
|
60400
60408
|
async function sendTx(connection, payer, instructions, signers, opts) {
|
|
60409
|
+
const budgetIxs = [];
|
|
60410
|
+
if (opts?.computeUnitLimit) {
|
|
60411
|
+
budgetIxs.push(
|
|
60412
|
+
import_web388.ComputeBudgetProgram.setComputeUnitLimit({ units: opts.computeUnitLimit })
|
|
60413
|
+
);
|
|
60414
|
+
}
|
|
60415
|
+
if (opts?.computeUnitPrice !== void 0) {
|
|
60416
|
+
let price;
|
|
60417
|
+
if (opts.computeUnitPrice === "auto") {
|
|
60418
|
+
price = await getRecentPriorityFee(connection);
|
|
60419
|
+
} else {
|
|
60420
|
+
price = opts.computeUnitPrice;
|
|
60421
|
+
}
|
|
60422
|
+
if (price > 0) {
|
|
60423
|
+
budgetIxs.push(
|
|
60424
|
+
import_web388.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: price })
|
|
60425
|
+
);
|
|
60426
|
+
}
|
|
60427
|
+
}
|
|
60428
|
+
const allInstructions = [...budgetIxs, ...instructions];
|
|
60401
60429
|
const alt = await loadAlt(connection);
|
|
60402
60430
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
60403
60431
|
let signature;
|
|
@@ -60405,7 +60433,7 @@ async function sendTx(connection, payer, instructions, signers, opts) {
|
|
|
60405
60433
|
const message = new import_web388.TransactionMessage({
|
|
60406
60434
|
payerKey: payer.publicKey,
|
|
60407
60435
|
recentBlockhash: blockhash,
|
|
60408
|
-
instructions
|
|
60436
|
+
instructions: allInstructions
|
|
60409
60437
|
}).compileToV0Message([alt]);
|
|
60410
60438
|
const tx = new import_web388.VersionedTransaction(message);
|
|
60411
60439
|
const allSigners = [payer, ...signers ?? []];
|
|
@@ -60425,7 +60453,7 @@ async function sendTx(connection, payer, instructions, signers, opts) {
|
|
|
60425
60453
|
tx.recentBlockhash = blockhash;
|
|
60426
60454
|
tx.lastValidBlockHeight = lastValidBlockHeight;
|
|
60427
60455
|
tx.feePayer = payer.publicKey;
|
|
60428
|
-
for (const ix of
|
|
60456
|
+
for (const ix of allInstructions) tx.add(ix);
|
|
60429
60457
|
const allSigners = [payer, ...signers ?? []];
|
|
60430
60458
|
const seen = /* @__PURE__ */ new Set();
|
|
60431
60459
|
const uniqueSigners = allSigners.filter((s) => {
|
|
@@ -60439,16 +60467,31 @@ async function sendTx(connection, payer, instructions, signers, opts) {
|
|
|
60439
60467
|
skipPreflight: opts?.skipPreflight ?? false
|
|
60440
60468
|
});
|
|
60441
60469
|
}
|
|
60442
|
-
const
|
|
60443
|
-
|
|
60444
|
-
|
|
60445
|
-
)
|
|
60446
|
-
|
|
60447
|
-
|
|
60448
|
-
|
|
60449
|
-
|
|
60470
|
+
const startTime = Date.now();
|
|
60471
|
+
const TIMEOUT_MS = 2e4;
|
|
60472
|
+
const POLL_INTERVAL_MS = 1e3;
|
|
60473
|
+
while (Date.now() - startTime < TIMEOUT_MS) {
|
|
60474
|
+
const currentBlockHeight = await connection.getBlockHeight("confirmed");
|
|
60475
|
+
if (currentBlockHeight > lastValidBlockHeight) {
|
|
60476
|
+
throw new Error(
|
|
60477
|
+
`Transaction ${signature} expired: block height exceeded`
|
|
60478
|
+
);
|
|
60479
|
+
}
|
|
60480
|
+
const statusResult = await connection.getSignatureStatuses([signature]);
|
|
60481
|
+
const status = statusResult?.value?.[0];
|
|
60482
|
+
if (status) {
|
|
60483
|
+
if (status.err) {
|
|
60484
|
+
throw new Error(
|
|
60485
|
+
`Transaction ${signature} failed: ${JSON.stringify(status.err)}`
|
|
60486
|
+
);
|
|
60487
|
+
}
|
|
60488
|
+
if (status.confirmationStatus === "confirmed" || status.confirmationStatus === "finalized") {
|
|
60489
|
+
return signature;
|
|
60490
|
+
}
|
|
60491
|
+
}
|
|
60492
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
60450
60493
|
}
|
|
60451
|
-
|
|
60494
|
+
throw new Error(`Transaction ${signature} confirmation timeout`);
|
|
60452
60495
|
}
|
|
60453
60496
|
var import_web388, _cachedAlt, _cachedAltAddress, _overrideAltAddress;
|
|
60454
60497
|
var init_tx = __esm({
|
|
@@ -95380,7 +95423,7 @@ var require_buffer_list = __commonJS({
|
|
|
95380
95423
|
}
|
|
95381
95424
|
}, {
|
|
95382
95425
|
key: "join",
|
|
95383
|
-
value: function
|
|
95426
|
+
value: function join6(s) {
|
|
95384
95427
|
if (this.length === 0) return "";
|
|
95385
95428
|
var p = this.head;
|
|
95386
95429
|
var ret = "" + p.data;
|
|
@@ -124721,16 +124764,16 @@ var nara_quest_default = {
|
|
|
124721
124764
|
args: []
|
|
124722
124765
|
},
|
|
124723
124766
|
{
|
|
124724
|
-
name: "
|
|
124767
|
+
name: "set_reward_config",
|
|
124725
124768
|
discriminator: [
|
|
124726
|
-
|
|
124727
|
-
|
|
124728
|
-
|
|
124729
|
-
|
|
124730
|
-
|
|
124731
|
-
|
|
124732
|
-
|
|
124733
|
-
|
|
124769
|
+
163,
|
|
124770
|
+
34,
|
|
124771
|
+
211,
|
|
124772
|
+
14,
|
|
124773
|
+
25,
|
|
124774
|
+
118,
|
|
124775
|
+
181,
|
|
124776
|
+
233
|
|
124734
124777
|
],
|
|
124735
124778
|
accounts: [
|
|
124736
124779
|
{
|
|
@@ -124764,6 +124807,10 @@ var nara_quest_default = {
|
|
|
124764
124807
|
}
|
|
124765
124808
|
],
|
|
124766
124809
|
args: [
|
|
124810
|
+
{
|
|
124811
|
+
name: "min_reward_count",
|
|
124812
|
+
type: "u32"
|
|
124813
|
+
},
|
|
124767
124814
|
{
|
|
124768
124815
|
name: "max_reward_count",
|
|
124769
124816
|
type: "u32"
|
|
@@ -124771,16 +124818,16 @@ var nara_quest_default = {
|
|
|
124771
124818
|
]
|
|
124772
124819
|
},
|
|
124773
124820
|
{
|
|
124774
|
-
name: "
|
|
124821
|
+
name: "set_stake_config",
|
|
124775
124822
|
discriminator: [
|
|
124776
|
-
|
|
124777
|
-
|
|
124778
|
-
|
|
124779
|
-
|
|
124780
|
-
|
|
124781
|
-
|
|
124782
|
-
|
|
124783
|
-
|
|
124823
|
+
84,
|
|
124824
|
+
37,
|
|
124825
|
+
76,
|
|
124826
|
+
39,
|
|
124827
|
+
236,
|
|
124828
|
+
111,
|
|
124829
|
+
214,
|
|
124830
|
+
191
|
|
124784
124831
|
],
|
|
124785
124832
|
accounts: [
|
|
124786
124833
|
{
|
|
@@ -124815,8 +124862,16 @@ var nara_quest_default = {
|
|
|
124815
124862
|
],
|
|
124816
124863
|
args: [
|
|
124817
124864
|
{
|
|
124818
|
-
name: "
|
|
124819
|
-
type: "
|
|
124865
|
+
name: "bps_high",
|
|
124866
|
+
type: "u64"
|
|
124867
|
+
},
|
|
124868
|
+
{
|
|
124869
|
+
name: "bps_low",
|
|
124870
|
+
type: "u64"
|
|
124871
|
+
},
|
|
124872
|
+
{
|
|
124873
|
+
name: "decay_ms",
|
|
124874
|
+
type: "i64"
|
|
124820
124875
|
}
|
|
124821
124876
|
]
|
|
124822
124877
|
},
|
|
@@ -125015,6 +125070,30 @@ var nara_quest_default = {
|
|
|
125015
125070
|
48
|
|
125016
125071
|
],
|
|
125017
125072
|
accounts: [
|
|
125073
|
+
{
|
|
125074
|
+
name: "game_config",
|
|
125075
|
+
pda: {
|
|
125076
|
+
seeds: [
|
|
125077
|
+
{
|
|
125078
|
+
kind: "const",
|
|
125079
|
+
value: [
|
|
125080
|
+
113,
|
|
125081
|
+
117,
|
|
125082
|
+
101,
|
|
125083
|
+
115,
|
|
125084
|
+
116,
|
|
125085
|
+
95,
|
|
125086
|
+
99,
|
|
125087
|
+
111,
|
|
125088
|
+
110,
|
|
125089
|
+
102,
|
|
125090
|
+
105,
|
|
125091
|
+
103
|
|
125092
|
+
]
|
|
125093
|
+
}
|
|
125094
|
+
]
|
|
125095
|
+
}
|
|
125096
|
+
},
|
|
125018
125097
|
{
|
|
125019
125098
|
name: "pool",
|
|
125020
125099
|
writable: true,
|
|
@@ -125709,12 +125788,12 @@ var nara_quest_default = {
|
|
|
125709
125788
|
{
|
|
125710
125789
|
code: 6008,
|
|
125711
125790
|
name: "InvalidMinRewardCount",
|
|
125712
|
-
msg: "
|
|
125791
|
+
msg: "Invalid reward config: need 0 < min <= max"
|
|
125713
125792
|
},
|
|
125714
125793
|
{
|
|
125715
125794
|
code: 6009,
|
|
125716
|
-
name: "
|
|
125717
|
-
msg: "
|
|
125795
|
+
name: "InvalidStakeConfig",
|
|
125796
|
+
msg: "Stake config values must be > 0"
|
|
125718
125797
|
},
|
|
125719
125798
|
{
|
|
125720
125799
|
code: 6010,
|
|
@@ -125725,6 +125804,11 @@ var nara_quest_default = {
|
|
|
125725
125804
|
code: 6011,
|
|
125726
125805
|
name: "InsufficientStakeBalance",
|
|
125727
125806
|
msg: "Unstake amount exceeds staked balance"
|
|
125807
|
+
},
|
|
125808
|
+
{
|
|
125809
|
+
code: 6012,
|
|
125810
|
+
name: "InsufficientStake",
|
|
125811
|
+
msg: "Stake does not meet dynamic requirement"
|
|
125728
125812
|
}
|
|
125729
125813
|
],
|
|
125730
125814
|
types: [
|
|
@@ -125777,6 +125861,18 @@ var nara_quest_default = {
|
|
|
125777
125861
|
name: "max_reward_count",
|
|
125778
125862
|
type: "u32"
|
|
125779
125863
|
},
|
|
125864
|
+
{
|
|
125865
|
+
name: "stake_bps_high",
|
|
125866
|
+
type: "u64"
|
|
125867
|
+
},
|
|
125868
|
+
{
|
|
125869
|
+
name: "stake_bps_low",
|
|
125870
|
+
type: "u64"
|
|
125871
|
+
},
|
|
125872
|
+
{
|
|
125873
|
+
name: "decay_ms",
|
|
125874
|
+
type: "i64"
|
|
125875
|
+
},
|
|
125780
125876
|
{
|
|
125781
125877
|
name: "_padding",
|
|
125782
125878
|
type: {
|
|
@@ -125836,11 +125932,19 @@ var nara_quest_default = {
|
|
|
125836
125932
|
type: "u32"
|
|
125837
125933
|
},
|
|
125838
125934
|
{
|
|
125839
|
-
name: "
|
|
125935
|
+
name: "created_at",
|
|
125936
|
+
type: "i64"
|
|
125937
|
+
},
|
|
125938
|
+
{
|
|
125939
|
+
name: "stake_high",
|
|
125840
125940
|
type: "u64"
|
|
125841
125941
|
},
|
|
125842
125942
|
{
|
|
125843
|
-
name: "
|
|
125943
|
+
name: "stake_low",
|
|
125944
|
+
type: "u64"
|
|
125945
|
+
},
|
|
125946
|
+
{
|
|
125947
|
+
name: "avg_participant_stake",
|
|
125844
125948
|
type: "u64"
|
|
125845
125949
|
},
|
|
125846
125950
|
{
|
|
@@ -125905,18 +126009,11 @@ var import_meta = {};
|
|
|
125905
126009
|
var BN254_FIELD = 21888242871839275222246405745257275088696311157297823662689037894645226208583n;
|
|
125906
126010
|
async function resolveDefaultZkPaths() {
|
|
125907
126011
|
const { fileURLToPath } = await import("url");
|
|
125908
|
-
const { dirname: dirname2, join:
|
|
125909
|
-
|
|
125910
|
-
if (import_meta.url) {
|
|
125911
|
-
dir = dirname2(fileURLToPath(import_meta.url));
|
|
125912
|
-
} else {
|
|
125913
|
-
const { createRequire } = await import("module");
|
|
125914
|
-
const req = createRequire(process.cwd() + "/");
|
|
125915
|
-
dir = dirname2(req.resolve("nara-sdk/package.json")) + "/src";
|
|
125916
|
-
}
|
|
126012
|
+
const { dirname: dirname2, join: join6 } = await import("path");
|
|
126013
|
+
const dir = dirname2(fileURLToPath(import_meta.url));
|
|
125917
126014
|
return {
|
|
125918
|
-
wasm:
|
|
125919
|
-
zkey:
|
|
126015
|
+
wasm: join6(dir, "zk", "answer_proof.wasm"),
|
|
126016
|
+
zkey: join6(dir, "zk", "answer_proof_final.zkey")
|
|
125920
126017
|
};
|
|
125921
126018
|
}
|
|
125922
126019
|
function hexFromBytes(bytes) {
|
|
@@ -126031,6 +126128,14 @@ var WSOL_MINT = new import_web390.PublicKey("So111111111111111111111111111111111
|
|
|
126031
126128
|
function getStakeTokenAccount(stakeRecordPda) {
|
|
126032
126129
|
return getAssociatedTokenAddressSync(WSOL_MINT, stakeRecordPda, true);
|
|
126033
126130
|
}
|
|
126131
|
+
function computeEffectiveStake(stakeHigh, stakeLow, createdAt, decayMs, nowMs) {
|
|
126132
|
+
if (decayMs <= 0) return stakeLow;
|
|
126133
|
+
const elapsedMs = nowMs - createdAt;
|
|
126134
|
+
if (elapsedMs >= decayMs) return stakeLow;
|
|
126135
|
+
const range = stakeHigh - stakeLow;
|
|
126136
|
+
const ratio = elapsedMs / decayMs;
|
|
126137
|
+
return stakeHigh - range * ratio * ratio;
|
|
126138
|
+
}
|
|
126034
126139
|
async function getQuestInfo(connection, wallet, options) {
|
|
126035
126140
|
const kp = wallet ?? import_web390.Keypair.generate();
|
|
126036
126141
|
const program3 = createProgram2(connection, kp, options?.programId);
|
|
@@ -126040,6 +126145,25 @@ async function getQuestInfo(connection, wallet, options) {
|
|
|
126040
126145
|
const deadline = pool.deadline.toNumber();
|
|
126041
126146
|
const secsLeft = deadline - now;
|
|
126042
126147
|
const active = pool.question.length > 0 && secsLeft > 0;
|
|
126148
|
+
const stakeHigh = Number(pool.stakeHigh.toString()) / import_web390.LAMPORTS_PER_SOL;
|
|
126149
|
+
const stakeLow = Number(pool.stakeLow.toString()) / import_web390.LAMPORTS_PER_SOL;
|
|
126150
|
+
const createdAt = pool.createdAt.toNumber();
|
|
126151
|
+
const programId = new import_web390.PublicKey(options?.programId ?? DEFAULT_QUEST_PROGRAM_ID);
|
|
126152
|
+
const [configPda] = import_web390.PublicKey.findProgramAddressSync(
|
|
126153
|
+
[new TextEncoder().encode("quest_config")],
|
|
126154
|
+
programId
|
|
126155
|
+
);
|
|
126156
|
+
const config = await program3.account.gameConfig.fetch(configPda);
|
|
126157
|
+
const decayMs = Number(config.decayMs.toString());
|
|
126158
|
+
const nowMs = Date.now();
|
|
126159
|
+
const createdAtMs = createdAt * 1e3;
|
|
126160
|
+
const effectiveStakeRequirement = computeEffectiveStake(
|
|
126161
|
+
stakeHigh,
|
|
126162
|
+
stakeLow,
|
|
126163
|
+
createdAtMs,
|
|
126164
|
+
decayMs,
|
|
126165
|
+
nowMs
|
|
126166
|
+
);
|
|
126043
126167
|
return {
|
|
126044
126168
|
active,
|
|
126045
126169
|
round: pool.round.toString(),
|
|
@@ -126054,8 +126178,11 @@ async function getQuestInfo(connection, wallet, options) {
|
|
|
126054
126178
|
deadline,
|
|
126055
126179
|
timeRemaining: secsLeft,
|
|
126056
126180
|
expired: secsLeft <= 0,
|
|
126057
|
-
|
|
126058
|
-
|
|
126181
|
+
stakeHigh,
|
|
126182
|
+
stakeLow,
|
|
126183
|
+
avgParticipantStake: Number(pool.avgParticipantStake.toString()) / import_web390.LAMPORTS_PER_SOL,
|
|
126184
|
+
createdAt,
|
|
126185
|
+
effectiveStakeRequirement
|
|
126059
126186
|
};
|
|
126060
126187
|
}
|
|
126061
126188
|
async function hasAnswered(connection, wallet, options) {
|
|
@@ -126105,7 +126232,7 @@ async function submitAnswer(connection, wallet, proof, agent = "", model = "", o
|
|
|
126105
126232
|
if (options.stake === "auto") {
|
|
126106
126233
|
const quest = await getQuestInfo(connection, wallet, options);
|
|
126107
126234
|
const stakeInfo = await getStakeInfo(connection, wallet.publicKey, options);
|
|
126108
|
-
const required = quest.
|
|
126235
|
+
const required = quest.effectiveStakeRequirement;
|
|
126109
126236
|
const current = stakeInfo?.amount ?? 0;
|
|
126110
126237
|
const deficit = required - current;
|
|
126111
126238
|
if (deficit > 0) {
|
|
@@ -128972,13 +129099,13 @@ var BN254_PRIME = 21888242871839275222246405745257275088696311157297823662689037
|
|
|
128972
129099
|
var MERKLE_LEVELS = 64;
|
|
128973
129100
|
async function resolveDefaultZkPaths2() {
|
|
128974
129101
|
const { fileURLToPath } = await import("url");
|
|
128975
|
-
const { dirname: dirname2, join:
|
|
129102
|
+
const { dirname: dirname2, join: join6 } = await import("path");
|
|
128976
129103
|
const dir = dirname2(fileURLToPath(import_meta2.url));
|
|
128977
129104
|
return {
|
|
128978
|
-
withdrawWasm:
|
|
128979
|
-
withdrawZkey:
|
|
128980
|
-
ownershipWasm:
|
|
128981
|
-
ownershipZkey:
|
|
129105
|
+
withdrawWasm: join6(dir, "zk", "withdraw.wasm"),
|
|
129106
|
+
withdrawZkey: join6(dir, "zk", "withdraw_final.zkey"),
|
|
129107
|
+
ownershipWasm: join6(dir, "zk", "ownership.wasm"),
|
|
129108
|
+
ownershipZkey: join6(dir, "zk", "ownership_final.zkey")
|
|
128982
129109
|
};
|
|
128983
129110
|
}
|
|
128984
129111
|
var ZKID_DENOMINATIONS = {
|
|
@@ -130023,6 +130150,22 @@ async function handleWalletAddress(options) {
|
|
|
130023
130150
|
|
|
130024
130151
|
// src/cli/commands/quest.ts
|
|
130025
130152
|
var import_web398 = __toESM(require_index_cjs(), 1);
|
|
130153
|
+
var import_node_path4 = require("node:path");
|
|
130154
|
+
var import_meta3 = {};
|
|
130155
|
+
var _getMetaUrl = () => {
|
|
130156
|
+
try {
|
|
130157
|
+
return import_meta3.url;
|
|
130158
|
+
} catch {
|
|
130159
|
+
return void 0;
|
|
130160
|
+
}
|
|
130161
|
+
};
|
|
130162
|
+
function getZkOptions() {
|
|
130163
|
+
if (_getMetaUrl()) return void 0;
|
|
130164
|
+
return {
|
|
130165
|
+
circuitWasmPath: (0, import_node_path4.join)(__dirname, "zk", "answer_proof.wasm"),
|
|
130166
|
+
zkeyPath: (0, import_node_path4.join)(__dirname, "zk", "answer_proof_final.zkey")
|
|
130167
|
+
};
|
|
130168
|
+
}
|
|
130026
130169
|
var DEFAULT_QUEST_RELAY_URL2 = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
|
|
130027
130170
|
var QUEST_ERRORS = {
|
|
130028
130171
|
6e3: "unauthorized",
|
|
@@ -130087,8 +130230,10 @@ async function handleQuestGet(options) {
|
|
|
130087
130230
|
deadline: new Date(quest.deadline * 1e3).toLocaleString(),
|
|
130088
130231
|
timeRemaining: formatTimeRemaining(quest.timeRemaining),
|
|
130089
130232
|
expired: quest.expired,
|
|
130090
|
-
stakeRequirement: `${quest.
|
|
130091
|
-
|
|
130233
|
+
stakeRequirement: `${quest.effectiveStakeRequirement.toFixed(4)} NARA`,
|
|
130234
|
+
stakeHigh: `${quest.stakeHigh} NARA`,
|
|
130235
|
+
stakeLow: `${quest.stakeLow} NARA`,
|
|
130236
|
+
avgParticipantStake: `${quest.avgParticipantStake} NARA`
|
|
130092
130237
|
};
|
|
130093
130238
|
if (options.json) {
|
|
130094
130239
|
formatOutput(data, true);
|
|
@@ -130102,9 +130247,8 @@ async function handleQuestGet(options) {
|
|
|
130102
130247
|
console.log(
|
|
130103
130248
|
` Reward slots: ${quest.winnerCount}/${quest.rewardCount} (${quest.remainingSlots} remaining)`
|
|
130104
130249
|
);
|
|
130105
|
-
if (quest.
|
|
130106
|
-
console.log(` Stake requirement: ${quest.
|
|
130107
|
-
console.log(` Min winner stake: ${quest.minWinnerStake} NARA`);
|
|
130250
|
+
if (quest.effectiveStakeRequirement > 0) {
|
|
130251
|
+
console.log(` Stake requirement: ${quest.effectiveStakeRequirement.toFixed(4)} NARA (decays ${quest.stakeHigh} \u2192 ${quest.stakeLow})`);
|
|
130108
130252
|
}
|
|
130109
130253
|
console.log(` Deadline: ${new Date(quest.deadline * 1e3).toLocaleString()}`);
|
|
130110
130254
|
if (quest.timeRemaining > 0) {
|
|
@@ -130147,7 +130291,7 @@ async function handleQuestAnswer(answer, options) {
|
|
|
130147
130291
|
printInfo("Generating ZK proof...");
|
|
130148
130292
|
let proof;
|
|
130149
130293
|
try {
|
|
130150
|
-
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round);
|
|
130294
|
+
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round, getZkOptions());
|
|
130151
130295
|
} catch (err) {
|
|
130152
130296
|
if (err.message?.includes("Assert Failed")) {
|
|
130153
130297
|
printError("Wrong answer");
|
|
@@ -131434,266 +131578,266 @@ async function searchMultiselect(options) {
|
|
|
131434
131578
|
// src/cli/commands/skillsInstall.ts
|
|
131435
131579
|
var import_promises2 = require("node:fs/promises");
|
|
131436
131580
|
var import_node_fs2 = require("node:fs");
|
|
131437
|
-
var
|
|
131581
|
+
var import_node_path5 = require("node:path");
|
|
131438
131582
|
var import_node_os4 = require("node:os");
|
|
131439
131583
|
var import_web399 = __toESM(require_index_cjs(), 1);
|
|
131440
131584
|
var home = (0, import_node_os4.homedir)();
|
|
131441
|
-
var xdgConfig = process.env.XDG_CONFIG_HOME || (0,
|
|
131442
|
-
var claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || (0,
|
|
131443
|
-
var codexHome = process.env.CODEX_HOME?.trim() || (0,
|
|
131585
|
+
var xdgConfig = process.env.XDG_CONFIG_HOME || (0, import_node_path5.join)(home, ".config");
|
|
131586
|
+
var claudeHome = process.env.CLAUDE_CONFIG_DIR?.trim() || (0, import_node_path5.join)(home, ".claude");
|
|
131587
|
+
var codexHome = process.env.CODEX_HOME?.trim() || (0, import_node_path5.join)(home, ".codex");
|
|
131444
131588
|
function openClawGlobalDir() {
|
|
131445
|
-
if ((0, import_node_fs2.existsSync)((0,
|
|
131446
|
-
if ((0, import_node_fs2.existsSync)((0,
|
|
131447
|
-
if ((0, import_node_fs2.existsSync)((0,
|
|
131448
|
-
return (0,
|
|
131589
|
+
if ((0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".openclaw"))) return (0, import_node_path5.join)(home, ".openclaw/skills");
|
|
131590
|
+
if ((0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".clawdbot"))) return (0, import_node_path5.join)(home, ".clawdbot/skills");
|
|
131591
|
+
if ((0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".moltbot"))) return (0, import_node_path5.join)(home, ".moltbot/skills");
|
|
131592
|
+
return (0, import_node_path5.join)(home, ".openclaw/skills");
|
|
131449
131593
|
}
|
|
131450
131594
|
var AGENT_CONFIGS = {
|
|
131451
131595
|
// ── Universal agents (share .agents/skills) ───────────────────
|
|
131452
131596
|
amp: {
|
|
131453
131597
|
displayName: "Amp",
|
|
131454
131598
|
projectDir: ".agents/skills",
|
|
131455
|
-
globalDir: (0,
|
|
131456
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131599
|
+
globalDir: (0, import_node_path5.join)(xdgConfig, "agents/skills"),
|
|
131600
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(xdgConfig, "amp"))
|
|
131457
131601
|
},
|
|
131458
131602
|
cline: {
|
|
131459
131603
|
displayName: "Cline",
|
|
131460
131604
|
projectDir: ".agents/skills",
|
|
131461
|
-
globalDir: (0,
|
|
131462
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131605
|
+
globalDir: (0, import_node_path5.join)(home, ".agents/skills"),
|
|
131606
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".cline"))
|
|
131463
131607
|
},
|
|
131464
131608
|
codex: {
|
|
131465
131609
|
displayName: "Codex",
|
|
131466
131610
|
projectDir: ".agents/skills",
|
|
131467
|
-
globalDir: (0,
|
|
131611
|
+
globalDir: (0, import_node_path5.join)(codexHome, "skills"),
|
|
131468
131612
|
detect: () => (0, import_node_fs2.existsSync)(codexHome) || (0, import_node_fs2.existsSync)("/etc/codex")
|
|
131469
131613
|
},
|
|
131470
131614
|
cursor: {
|
|
131471
131615
|
displayName: "Cursor",
|
|
131472
131616
|
projectDir: ".agents/skills",
|
|
131473
|
-
globalDir: (0,
|
|
131474
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131617
|
+
globalDir: (0, import_node_path5.join)(home, ".cursor/skills"),
|
|
131618
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".cursor"))
|
|
131475
131619
|
},
|
|
131476
131620
|
"gemini-cli": {
|
|
131477
131621
|
displayName: "Gemini CLI",
|
|
131478
131622
|
projectDir: ".agents/skills",
|
|
131479
|
-
globalDir: (0,
|
|
131480
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131623
|
+
globalDir: (0, import_node_path5.join)(home, ".gemini/skills"),
|
|
131624
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".gemini"))
|
|
131481
131625
|
},
|
|
131482
131626
|
"github-copilot": {
|
|
131483
131627
|
displayName: "GitHub Copilot",
|
|
131484
131628
|
projectDir: ".agents/skills",
|
|
131485
|
-
globalDir: (0,
|
|
131486
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131629
|
+
globalDir: (0, import_node_path5.join)(home, ".copilot/skills"),
|
|
131630
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".copilot"))
|
|
131487
131631
|
},
|
|
131488
131632
|
"kimi-cli": {
|
|
131489
131633
|
displayName: "Kimi Code CLI",
|
|
131490
131634
|
projectDir: ".agents/skills",
|
|
131491
|
-
globalDir: (0,
|
|
131492
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131635
|
+
globalDir: (0, import_node_path5.join)(home, ".config/agents/skills"),
|
|
131636
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".kimi"))
|
|
131493
131637
|
},
|
|
131494
131638
|
opencode: {
|
|
131495
131639
|
displayName: "OpenCode",
|
|
131496
131640
|
projectDir: ".agents/skills",
|
|
131497
|
-
globalDir: (0,
|
|
131498
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131641
|
+
globalDir: (0, import_node_path5.join)(xdgConfig, "opencode/skills"),
|
|
131642
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(xdgConfig, "opencode"))
|
|
131499
131643
|
},
|
|
131500
131644
|
replit: {
|
|
131501
131645
|
displayName: "Replit",
|
|
131502
131646
|
projectDir: ".agents/skills",
|
|
131503
|
-
globalDir: (0,
|
|
131504
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131647
|
+
globalDir: (0, import_node_path5.join)(xdgConfig, "agents/skills"),
|
|
131648
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(process.cwd(), ".replit")),
|
|
131505
131649
|
showInUniversalList: false
|
|
131506
131650
|
},
|
|
131507
131651
|
// ── Additional agents (custom skill dirs) ─────────────────────
|
|
131508
131652
|
adal: {
|
|
131509
131653
|
displayName: "AdaL",
|
|
131510
131654
|
projectDir: ".adal/skills",
|
|
131511
|
-
globalDir: (0,
|
|
131512
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131655
|
+
globalDir: (0, import_node_path5.join)(home, ".adal/skills"),
|
|
131656
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".adal"))
|
|
131513
131657
|
},
|
|
131514
131658
|
antigravity: {
|
|
131515
131659
|
displayName: "Antigravity",
|
|
131516
131660
|
projectDir: ".agent/skills",
|
|
131517
|
-
globalDir: (0,
|
|
131518
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131661
|
+
globalDir: (0, import_node_path5.join)(home, ".gemini/antigravity/skills"),
|
|
131662
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".gemini/antigravity"))
|
|
131519
131663
|
},
|
|
131520
131664
|
augment: {
|
|
131521
131665
|
displayName: "Augment",
|
|
131522
131666
|
projectDir: ".augment/skills",
|
|
131523
|
-
globalDir: (0,
|
|
131524
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131667
|
+
globalDir: (0, import_node_path5.join)(home, ".augment/skills"),
|
|
131668
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".augment"))
|
|
131525
131669
|
},
|
|
131526
131670
|
"claude-code": {
|
|
131527
131671
|
displayName: "Claude Code",
|
|
131528
131672
|
projectDir: ".claude/skills",
|
|
131529
|
-
globalDir: (0,
|
|
131673
|
+
globalDir: (0, import_node_path5.join)(claudeHome, "skills"),
|
|
131530
131674
|
detect: () => (0, import_node_fs2.existsSync)(claudeHome)
|
|
131531
131675
|
},
|
|
131532
131676
|
codebuddy: {
|
|
131533
131677
|
displayName: "CodeBuddy",
|
|
131534
131678
|
projectDir: ".codebuddy/skills",
|
|
131535
|
-
globalDir: (0,
|
|
131536
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131679
|
+
globalDir: (0, import_node_path5.join)(home, ".codebuddy/skills"),
|
|
131680
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(process.cwd(), ".codebuddy")) || (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".codebuddy"))
|
|
131537
131681
|
},
|
|
131538
131682
|
"command-code": {
|
|
131539
131683
|
displayName: "Command Code",
|
|
131540
131684
|
projectDir: ".commandcode/skills",
|
|
131541
|
-
globalDir: (0,
|
|
131542
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131685
|
+
globalDir: (0, import_node_path5.join)(home, ".commandcode/skills"),
|
|
131686
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".commandcode"))
|
|
131543
131687
|
},
|
|
131544
131688
|
continue: {
|
|
131545
131689
|
displayName: "Continue",
|
|
131546
131690
|
projectDir: ".continue/skills",
|
|
131547
|
-
globalDir: (0,
|
|
131548
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131691
|
+
globalDir: (0, import_node_path5.join)(home, ".continue/skills"),
|
|
131692
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(process.cwd(), ".continue")) || (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".continue"))
|
|
131549
131693
|
},
|
|
131550
131694
|
cortex: {
|
|
131551
131695
|
displayName: "Cortex Code",
|
|
131552
131696
|
projectDir: ".cortex/skills",
|
|
131553
|
-
globalDir: (0,
|
|
131554
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131697
|
+
globalDir: (0, import_node_path5.join)(home, ".snowflake/cortex/skills"),
|
|
131698
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".snowflake/cortex"))
|
|
131555
131699
|
},
|
|
131556
131700
|
crush: {
|
|
131557
131701
|
displayName: "Crush",
|
|
131558
131702
|
projectDir: ".crush/skills",
|
|
131559
|
-
globalDir: (0,
|
|
131560
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131703
|
+
globalDir: (0, import_node_path5.join)(home, ".config/crush/skills"),
|
|
131704
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".config/crush"))
|
|
131561
131705
|
},
|
|
131562
131706
|
droid: {
|
|
131563
131707
|
displayName: "Droid",
|
|
131564
131708
|
projectDir: ".factory/skills",
|
|
131565
|
-
globalDir: (0,
|
|
131566
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131709
|
+
globalDir: (0, import_node_path5.join)(home, ".factory/skills"),
|
|
131710
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".factory"))
|
|
131567
131711
|
},
|
|
131568
131712
|
goose: {
|
|
131569
131713
|
displayName: "Goose",
|
|
131570
131714
|
projectDir: ".goose/skills",
|
|
131571
|
-
globalDir: (0,
|
|
131572
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131715
|
+
globalDir: (0, import_node_path5.join)(xdgConfig, "goose/skills"),
|
|
131716
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(xdgConfig, "goose"))
|
|
131573
131717
|
},
|
|
131574
131718
|
"iflow-cli": {
|
|
131575
131719
|
displayName: "iFlow CLI",
|
|
131576
131720
|
projectDir: ".iflow/skills",
|
|
131577
|
-
globalDir: (0,
|
|
131578
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131721
|
+
globalDir: (0, import_node_path5.join)(home, ".iflow/skills"),
|
|
131722
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".iflow"))
|
|
131579
131723
|
},
|
|
131580
131724
|
junie: {
|
|
131581
131725
|
displayName: "Junie",
|
|
131582
131726
|
projectDir: ".junie/skills",
|
|
131583
|
-
globalDir: (0,
|
|
131584
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131727
|
+
globalDir: (0, import_node_path5.join)(home, ".junie/skills"),
|
|
131728
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".junie"))
|
|
131585
131729
|
},
|
|
131586
131730
|
kilo: {
|
|
131587
131731
|
displayName: "Kilo Code",
|
|
131588
131732
|
projectDir: ".kilocode/skills",
|
|
131589
|
-
globalDir: (0,
|
|
131590
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131733
|
+
globalDir: (0, import_node_path5.join)(home, ".kilocode/skills"),
|
|
131734
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".kilocode"))
|
|
131591
131735
|
},
|
|
131592
131736
|
"kiro-cli": {
|
|
131593
131737
|
displayName: "Kiro CLI",
|
|
131594
131738
|
projectDir: ".kiro/skills",
|
|
131595
|
-
globalDir: (0,
|
|
131596
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131739
|
+
globalDir: (0, import_node_path5.join)(home, ".kiro/skills"),
|
|
131740
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".kiro"))
|
|
131597
131741
|
},
|
|
131598
131742
|
kode: {
|
|
131599
131743
|
displayName: "Kode",
|
|
131600
131744
|
projectDir: ".kode/skills",
|
|
131601
|
-
globalDir: (0,
|
|
131602
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131745
|
+
globalDir: (0, import_node_path5.join)(home, ".kode/skills"),
|
|
131746
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".kode"))
|
|
131603
131747
|
},
|
|
131604
131748
|
mcpjam: {
|
|
131605
131749
|
displayName: "MCPJam",
|
|
131606
131750
|
projectDir: ".mcpjam/skills",
|
|
131607
|
-
globalDir: (0,
|
|
131608
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131751
|
+
globalDir: (0, import_node_path5.join)(home, ".mcpjam/skills"),
|
|
131752
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".mcpjam"))
|
|
131609
131753
|
},
|
|
131610
131754
|
"mistral-vibe": {
|
|
131611
131755
|
displayName: "Mistral Vibe",
|
|
131612
131756
|
projectDir: ".vibe/skills",
|
|
131613
|
-
globalDir: (0,
|
|
131614
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131757
|
+
globalDir: (0, import_node_path5.join)(home, ".vibe/skills"),
|
|
131758
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".vibe"))
|
|
131615
131759
|
},
|
|
131616
131760
|
mux: {
|
|
131617
131761
|
displayName: "Mux",
|
|
131618
131762
|
projectDir: ".mux/skills",
|
|
131619
|
-
globalDir: (0,
|
|
131620
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131763
|
+
globalDir: (0, import_node_path5.join)(home, ".mux/skills"),
|
|
131764
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".mux"))
|
|
131621
131765
|
},
|
|
131622
131766
|
neovate: {
|
|
131623
131767
|
displayName: "Neovate",
|
|
131624
131768
|
projectDir: ".neovate/skills",
|
|
131625
|
-
globalDir: (0,
|
|
131626
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131769
|
+
globalDir: (0, import_node_path5.join)(home, ".neovate/skills"),
|
|
131770
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".neovate"))
|
|
131627
131771
|
},
|
|
131628
131772
|
openclaw: {
|
|
131629
131773
|
displayName: "OpenClaw",
|
|
131630
131774
|
projectDir: "skills",
|
|
131631
131775
|
globalDir: openClawGlobalDir(),
|
|
131632
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131776
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".openclaw")) || (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".clawdbot")) || (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".moltbot"))
|
|
131633
131777
|
},
|
|
131634
131778
|
openhands: {
|
|
131635
131779
|
displayName: "OpenHands",
|
|
131636
131780
|
projectDir: ".openhands/skills",
|
|
131637
|
-
globalDir: (0,
|
|
131638
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131781
|
+
globalDir: (0, import_node_path5.join)(home, ".openhands/skills"),
|
|
131782
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".openhands"))
|
|
131639
131783
|
},
|
|
131640
131784
|
pi: {
|
|
131641
131785
|
displayName: "Pi",
|
|
131642
131786
|
projectDir: ".pi/skills",
|
|
131643
|
-
globalDir: (0,
|
|
131644
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131787
|
+
globalDir: (0, import_node_path5.join)(home, ".pi/agent/skills"),
|
|
131788
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".pi/agent"))
|
|
131645
131789
|
},
|
|
131646
131790
|
pochi: {
|
|
131647
131791
|
displayName: "Pochi",
|
|
131648
131792
|
projectDir: ".pochi/skills",
|
|
131649
|
-
globalDir: (0,
|
|
131650
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131793
|
+
globalDir: (0, import_node_path5.join)(home, ".pochi/skills"),
|
|
131794
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".pochi"))
|
|
131651
131795
|
},
|
|
131652
131796
|
qoder: {
|
|
131653
131797
|
displayName: "Qoder",
|
|
131654
131798
|
projectDir: ".qoder/skills",
|
|
131655
|
-
globalDir: (0,
|
|
131656
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131799
|
+
globalDir: (0, import_node_path5.join)(home, ".qoder/skills"),
|
|
131800
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".qoder"))
|
|
131657
131801
|
},
|
|
131658
131802
|
"qwen-code": {
|
|
131659
131803
|
displayName: "Qwen Code",
|
|
131660
131804
|
projectDir: ".qwen/skills",
|
|
131661
|
-
globalDir: (0,
|
|
131662
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131805
|
+
globalDir: (0, import_node_path5.join)(home, ".qwen/skills"),
|
|
131806
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".qwen"))
|
|
131663
131807
|
},
|
|
131664
131808
|
roo: {
|
|
131665
131809
|
displayName: "Roo Code",
|
|
131666
131810
|
projectDir: ".roo/skills",
|
|
131667
|
-
globalDir: (0,
|
|
131668
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131811
|
+
globalDir: (0, import_node_path5.join)(home, ".roo/skills"),
|
|
131812
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".roo"))
|
|
131669
131813
|
},
|
|
131670
131814
|
trae: {
|
|
131671
131815
|
displayName: "Trae",
|
|
131672
131816
|
projectDir: ".trae/skills",
|
|
131673
|
-
globalDir: (0,
|
|
131674
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131817
|
+
globalDir: (0, import_node_path5.join)(home, ".trae/skills"),
|
|
131818
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".trae"))
|
|
131675
131819
|
},
|
|
131676
131820
|
"trae-cn": {
|
|
131677
131821
|
displayName: "Trae CN",
|
|
131678
131822
|
projectDir: ".trae/skills",
|
|
131679
|
-
globalDir: (0,
|
|
131680
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131823
|
+
globalDir: (0, import_node_path5.join)(home, ".trae-cn/skills"),
|
|
131824
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".trae-cn"))
|
|
131681
131825
|
},
|
|
131682
131826
|
windsurf: {
|
|
131683
131827
|
displayName: "Windsurf",
|
|
131684
131828
|
projectDir: ".windsurf/skills",
|
|
131685
|
-
globalDir: (0,
|
|
131686
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131829
|
+
globalDir: (0, import_node_path5.join)(home, ".codeium/windsurf/skills"),
|
|
131830
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".codeium/windsurf"))
|
|
131687
131831
|
},
|
|
131688
131832
|
zencoder: {
|
|
131689
131833
|
displayName: "Zencoder",
|
|
131690
131834
|
projectDir: ".zencoder/skills",
|
|
131691
|
-
globalDir: (0,
|
|
131692
|
-
detect: () => (0, import_node_fs2.existsSync)((0,
|
|
131835
|
+
globalDir: (0, import_node_path5.join)(home, ".zencoder/skills"),
|
|
131836
|
+
detect: () => (0, import_node_fs2.existsSync)((0, import_node_path5.join)(home, ".zencoder"))
|
|
131693
131837
|
}
|
|
131694
131838
|
};
|
|
131695
131839
|
function getLockPath(global2, cwd) {
|
|
131696
|
-
return global2 ? (0,
|
|
131840
|
+
return global2 ? (0, import_node_path5.join)(xdgConfig, "nara/skills-lock.json") : (0, import_node_path5.join)(cwd, ".nara/skills-lock.json");
|
|
131697
131841
|
}
|
|
131698
131842
|
async function readLock(global2, cwd) {
|
|
131699
131843
|
try {
|
|
@@ -131705,7 +131849,7 @@ async function readLock(global2, cwd) {
|
|
|
131705
131849
|
}
|
|
131706
131850
|
async function writeLock(lock, global2, cwd) {
|
|
131707
131851
|
const lockPath = getLockPath(global2, cwd);
|
|
131708
|
-
await (0, import_promises2.mkdir)((0,
|
|
131852
|
+
await (0, import_promises2.mkdir)((0, import_node_path5.dirname)(lockPath), { recursive: true });
|
|
131709
131853
|
await (0, import_promises2.writeFile)(lockPath, JSON.stringify(lock, null, 2) + "\n", "utf-8");
|
|
131710
131854
|
}
|
|
131711
131855
|
function detectAgents() {
|
|
@@ -131722,23 +131866,23 @@ function resolveInstallDirs(agentIds, global2, cwd) {
|
|
|
131722
131866
|
return {
|
|
131723
131867
|
agentId: id,
|
|
131724
131868
|
displayName: cfg.displayName,
|
|
131725
|
-
dir: global2 ? cfg.globalDir : (0,
|
|
131869
|
+
dir: global2 ? cfg.globalDir : (0, import_node_path5.join)(cwd, cfg.projectDir)
|
|
131726
131870
|
};
|
|
131727
131871
|
});
|
|
131728
131872
|
}
|
|
131729
131873
|
async function writeSkillFiles(name, content, targets) {
|
|
131730
131874
|
const written = [];
|
|
131731
131875
|
for (const { dir } of targets) {
|
|
131732
|
-
const skillDir = (0,
|
|
131876
|
+
const skillDir = (0, import_node_path5.join)(dir, name);
|
|
131733
131877
|
await (0, import_promises2.mkdir)(skillDir, { recursive: true });
|
|
131734
|
-
await (0, import_promises2.writeFile)((0,
|
|
131735
|
-
written.push((0,
|
|
131878
|
+
await (0, import_promises2.writeFile)((0, import_node_path5.join)(skillDir, "SKILL.md"), content);
|
|
131879
|
+
written.push((0, import_node_path5.join)(skillDir, "SKILL.md"));
|
|
131736
131880
|
}
|
|
131737
131881
|
return written;
|
|
131738
131882
|
}
|
|
131739
131883
|
async function removeSkillFiles(name, targets) {
|
|
131740
131884
|
for (const { dir } of targets) {
|
|
131741
|
-
await (0, import_promises2.rm)((0,
|
|
131885
|
+
await (0, import_promises2.rm)((0, import_node_path5.join)(dir, name), { recursive: true, force: true });
|
|
131742
131886
|
}
|
|
131743
131887
|
}
|
|
131744
131888
|
function shortenPath(fullPath, cwd) {
|
|
@@ -131848,7 +131992,7 @@ async function handleSkillsAdd(name, options) {
|
|
|
131848
131992
|
const additionalTargets = targets.filter((t) => !universalIds.includes(t.agentId));
|
|
131849
131993
|
const summaryLines = [];
|
|
131850
131994
|
if (universalTargets.length > 0) {
|
|
131851
|
-
const canonicalPath = (0,
|
|
131995
|
+
const canonicalPath = (0, import_node_path5.join)(universalTargets[0].dir, name);
|
|
131852
131996
|
summaryLines.push(`${import_picocolors3.default.cyan(shortenPath(canonicalPath, cwd))}`);
|
|
131853
131997
|
summaryLines.push(
|
|
131854
131998
|
` ${import_picocolors3.default.dim("\u2500\u2500")} ${import_picocolors3.default.bold("Universal (.agents/skills)")} ${import_picocolors3.default.dim("\u2500\u2500 always included \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}`
|
|
@@ -131859,7 +132003,7 @@ async function handleSkillsAdd(name, options) {
|
|
|
131859
132003
|
}
|
|
131860
132004
|
for (const t of additionalTargets) {
|
|
131861
132005
|
if (summaryLines.length > 0) summaryLines.push("");
|
|
131862
|
-
const filePath = (0,
|
|
132006
|
+
const filePath = (0, import_node_path5.join)(t.dir, name, "SKILL.md");
|
|
131863
132007
|
summaryLines.push(`${import_picocolors3.default.cyan(shortenPath(filePath, cwd))}`);
|
|
131864
132008
|
summaryLines.push(` ${import_picocolors3.default.green("\u2022")} ${t.displayName}`);
|
|
131865
132009
|
}
|
|
@@ -131939,9 +132083,9 @@ async function handleSkillsList(options) {
|
|
|
131939
132083
|
let canonicalPath = "";
|
|
131940
132084
|
for (const [, cfg] of Object.entries(AGENT_CONFIGS)) {
|
|
131941
132085
|
if (!cfg.detect()) continue;
|
|
131942
|
-
const dir = isGlobal ? cfg.globalDir : (0,
|
|
131943
|
-
if ((0, import_node_fs2.existsSync)((0,
|
|
131944
|
-
if (!canonicalPath) canonicalPath = shortenPath((0,
|
|
132086
|
+
const dir = isGlobal ? cfg.globalDir : (0, import_node_path5.join)(cwd, cfg.projectDir);
|
|
132087
|
+
if ((0, import_node_fs2.existsSync)((0, import_node_path5.join)(dir, name, "SKILL.md"))) {
|
|
132088
|
+
if (!canonicalPath) canonicalPath = shortenPath((0, import_node_path5.join)(dir, name), cwd);
|
|
131945
132089
|
installedAgents.push(cfg.displayName);
|
|
131946
132090
|
}
|
|
131947
132091
|
}
|
|
@@ -133229,7 +133373,7 @@ function registerCommands(program3) {
|
|
|
133229
133373
|
}
|
|
133230
133374
|
|
|
133231
133375
|
// bin/nara-cli.ts
|
|
133232
|
-
var version2 = true ? "1.0.
|
|
133376
|
+
var version2 = true ? "1.0.47" : "dev";
|
|
133233
133377
|
var program2 = new Command();
|
|
133234
133378
|
program2.name("naracli").description("CLI for the Nara chain (Solana-compatible)").version(version2);
|
|
133235
133379
|
program2.option("-r, --rpc-url <url>", "RPC endpoint URL").option("-w, --wallet <path>", "Path to wallet keypair JSON file").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.
|
|
3
|
+
"version": "1.0.47",
|
|
4
4
|
"description": "CLI for the Nara chain (Solana-compatible)",
|
|
5
5
|
"module": "index.ts",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test:skills": "node --require ./bin/env-loader.cjs --import tsx --test --experimental-test-isolation=none --test-reporter spec src/tests/skills.test.ts",
|
|
21
21
|
"test:zkid": "node --require ./bin/env-loader.cjs --import tsx --test --experimental-test-isolation=none --test-reporter spec src/tests/zkid.test.ts",
|
|
22
22
|
"test:agent": "node --require ./bin/env-loader.cjs --import tsx --test --experimental-test-isolation=none --test-reporter spec src/tests/agent-registry.test.ts",
|
|
23
|
+
"test:quest-relay": "node --require ./bin/env-loader.cjs --import tsx --test --experimental-test-isolation=none --test-reporter spec src/tests/quest-relay.test.ts",
|
|
23
24
|
"test:quest-referral": "node --require ./bin/env-loader.cjs --import tsx --test --experimental-test-isolation=none --test-reporter spec src/tests/quest-referral.test.ts",
|
|
24
25
|
"prepublishOnly": "npm run build"
|
|
25
26
|
},
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"bs58": "^6.0.0",
|
|
57
58
|
"commander": "^12.1.0",
|
|
58
59
|
"ed25519-hd-key": "^1.3.0",
|
|
59
|
-
"nara-sdk": "^1.0.
|
|
60
|
+
"nara-sdk": "^1.0.48",
|
|
60
61
|
"picocolors": "^1.1.1"
|
|
61
62
|
},
|
|
62
63
|
"packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { Connection, Keypair } from "@solana/web3.js";
|
|
7
|
+
import { join } from "node:path";
|
|
7
8
|
import { loadWallet, getRpcUrl } from "../utils/wallet";
|
|
8
9
|
import {
|
|
9
10
|
formatOutput,
|
|
@@ -25,9 +26,22 @@ import {
|
|
|
25
26
|
getStakeInfo,
|
|
26
27
|
type ActivityLog,
|
|
27
28
|
type StakeInfo,
|
|
29
|
+
type QuestOptions,
|
|
28
30
|
} from "nara-sdk";
|
|
29
31
|
import { loadNetworkConfig } from "../utils/agent-config";
|
|
30
32
|
|
|
33
|
+
// In CJS bundle (dist/naracli.cjs), import.meta.url is undefined and SDK
|
|
34
|
+
// cannot auto-resolve ZK circuit paths. Provide them explicitly via __dirname.
|
|
35
|
+
// Use indirect access to avoid esbuild empty-import-meta warning.
|
|
36
|
+
const _getMetaUrl = () => { try { return import.meta.url; } catch { return undefined; } };
|
|
37
|
+
function getZkOptions(): QuestOptions | undefined {
|
|
38
|
+
if (_getMetaUrl()) return undefined; // dev mode: SDK resolves paths itself
|
|
39
|
+
return {
|
|
40
|
+
circuitWasmPath: join(__dirname, "zk", "answer_proof.wasm"),
|
|
41
|
+
zkeyPath: join(__dirname, "zk", "answer_proof_final.zkey"),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
31
45
|
const DEFAULT_QUEST_RELAY_URL = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
|
|
32
46
|
|
|
33
47
|
// ─── Anchor error parsing ────────────────────────────────────────
|
|
@@ -103,8 +117,10 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
103
117
|
deadline: new Date(quest.deadline * 1000).toLocaleString(),
|
|
104
118
|
timeRemaining: formatTimeRemaining(quest.timeRemaining),
|
|
105
119
|
expired: quest.expired,
|
|
106
|
-
stakeRequirement: `${quest.
|
|
107
|
-
|
|
120
|
+
stakeRequirement: `${quest.effectiveStakeRequirement.toFixed(4)} NARA`,
|
|
121
|
+
stakeHigh: `${quest.stakeHigh} NARA`,
|
|
122
|
+
stakeLow: `${quest.stakeLow} NARA`,
|
|
123
|
+
avgParticipantStake: `${quest.avgParticipantStake} NARA`,
|
|
108
124
|
};
|
|
109
125
|
|
|
110
126
|
if (options.json) {
|
|
@@ -119,9 +135,8 @@ async function handleQuestGet(options: GlobalOptions) {
|
|
|
119
135
|
console.log(
|
|
120
136
|
` Reward slots: ${quest.winnerCount}/${quest.rewardCount} (${quest.remainingSlots} remaining)`
|
|
121
137
|
);
|
|
122
|
-
if (quest.
|
|
123
|
-
console.log(` Stake requirement: ${quest.
|
|
124
|
-
console.log(` Min winner stake: ${quest.minWinnerStake} NARA`);
|
|
138
|
+
if (quest.effectiveStakeRequirement > 0) {
|
|
139
|
+
console.log(` Stake requirement: ${quest.effectiveStakeRequirement.toFixed(4)} NARA (decays ${quest.stakeHigh} → ${quest.stakeLow})`);
|
|
125
140
|
}
|
|
126
141
|
console.log(` Deadline: ${new Date(quest.deadline * 1000).toLocaleString()}`);
|
|
127
142
|
if (quest.timeRemaining > 0) {
|
|
@@ -178,7 +193,7 @@ async function handleQuestAnswer(
|
|
|
178
193
|
|
|
179
194
|
let proof;
|
|
180
195
|
try {
|
|
181
|
-
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round);
|
|
196
|
+
proof = await generateProof(answer, quest.answerHash, wallet.publicKey, quest.round, getZkOptions());
|
|
182
197
|
} catch (err: any) {
|
|
183
198
|
if (err.message?.includes("Assert Failed")) {
|
|
184
199
|
printError("Wrong answer");
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for quest relay (gasless) submission
|
|
3
|
+
*
|
|
4
|
+
* Requires PRIVATE_KEY in .env and an active quest.
|
|
5
|
+
*
|
|
6
|
+
* Run: npm run test:quest-relay
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, it } from "node:test";
|
|
10
|
+
import assert from "node:assert/strict";
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
import { join, dirname } from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { Connection } from "@solana/web3.js";
|
|
15
|
+
import { runCli, hasWallet } from "./helpers.js";
|
|
16
|
+
import { getQuestInfo } from "nara-sdk";
|
|
17
|
+
|
|
18
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
|
|
20
|
+
interface TestQuestion {
|
|
21
|
+
text: string;
|
|
22
|
+
answer: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function loadTestQuestions(): TestQuestion[] {
|
|
26
|
+
const filePath = join(__dirname, "../../.assets/test-questions.json");
|
|
27
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// ─── Relay quest answer ──────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
describe("quest answer (relay)", { skip: !hasWallet ? "no wallet" : undefined }, () => {
|
|
33
|
+
it("submits answer via relay and outputs tx", async () => {
|
|
34
|
+
const rpcUrl = process.env.RPC_URL || "https://mainnet-api.nara.build/";
|
|
35
|
+
const relayUrl = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
|
|
36
|
+
console.log(` Relay: ${relayUrl}`);
|
|
37
|
+
const connection = new Connection(rpcUrl, "confirmed");
|
|
38
|
+
|
|
39
|
+
const quest = await getQuestInfo(connection);
|
|
40
|
+
if (!quest.active || quest.expired) {
|
|
41
|
+
console.log(" (skipped: no active quest)");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const questions = loadTestQuestions();
|
|
46
|
+
const match = questions.find((q) => q.text === quest.question);
|
|
47
|
+
if (!match) {
|
|
48
|
+
console.log(` (skipped: question not found in test-questions.json)`);
|
|
49
|
+
console.log(` Question: ${quest.question}`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log(` Question: ${quest.question}`);
|
|
54
|
+
console.log(` Answer: ${match.answer}`);
|
|
55
|
+
|
|
56
|
+
const { stdout, stderr, exitCode } = await runCli([
|
|
57
|
+
"quest", "answer", match.answer,
|
|
58
|
+
"--relay",
|
|
59
|
+
"--agent", "test",
|
|
60
|
+
"--model", "test",
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
const output = stdout + stderr;
|
|
64
|
+
|
|
65
|
+
if (output.includes("already answered") || output.includes("Already answered")) {
|
|
66
|
+
console.log(" Already answered this round");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (output.includes("expired")) {
|
|
70
|
+
console.log(" Quest expired during test");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
assert.equal(exitCode, 0, `CLI failed: ${stderr}`);
|
|
75
|
+
assert.ok(output.includes("Transaction:") || output.includes("submitted"), "should confirm submission");
|
|
76
|
+
|
|
77
|
+
// Extract and print tx signature
|
|
78
|
+
const txMatch = output.match(/Transaction:\s+(\S+)/);
|
|
79
|
+
if (txMatch) {
|
|
80
|
+
console.log(` TX: ${txMatch[1]}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Print reward info
|
|
84
|
+
if (output.includes("Reward received")) {
|
|
85
|
+
const rewardMatch = output.match(/Reward received:\s+(.+)/);
|
|
86
|
+
console.log(` Reward: ${rewardMatch ? rewardMatch[1] : "yes"}`);
|
|
87
|
+
} else if (output.includes("no reward") || output.includes("all reward slots")) {
|
|
88
|
+
console.log(" Reward: none (all slots claimed)");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
package/src/tests/quest.test.ts
CHANGED