naracli 1.0.78 → 1.0.80

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.
@@ -60810,10 +60810,10 @@ var require_dist3 = __commonJS({
60810
60810
  }
60811
60811
  });
60812
60812
 
60813
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/constants.ts
60813
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/constants.ts
60814
60814
  var DEFAULT_RPC_URL, DEFAULT_QUEST_RELAY_URL, DEFAULT_QUEST_PROGRAM_ID, DEFAULT_SKILLS_PROGRAM_ID, DEFAULT_ZKID_PROGRAM_ID, DEFAULT_AGENT_REGISTRY_PROGRAM_ID, DEFAULT_ALT_ADDRESS;
60815
60815
  var init_constants2 = __esm({
60816
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/constants.ts"() {
60816
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/constants.ts"() {
60817
60817
  DEFAULT_RPC_URL = process.env.RPC_URL || "https://mainnet-api.nara.build/";
60818
60818
  DEFAULT_QUEST_RELAY_URL = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
60819
60819
  DEFAULT_QUEST_PROGRAM_ID = process.env.QUEST_PROGRAM_ID || "Quest11111111111111111111111111111111111111";
@@ -60824,7 +60824,7 @@ var init_constants2 = __esm({
60824
60824
  }
60825
60825
  });
60826
60826
 
60827
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/tx.ts
60827
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/tx.ts
60828
60828
  function getAltAddress() {
60829
60829
  if (_overrideAltAddresses !== null) return _overrideAltAddresses;
60830
60830
  if (!DEFAULT_ALT_ADDRESS) return [];
@@ -60950,7 +60950,7 @@ async function sendTx(connection, payer, instructions, signers, opts) {
60950
60950
  }
60951
60951
  var import_web388, _cachedAlts, _cachedAltKey, _overrideAltAddresses, _globalSkipPreflight;
60952
60952
  var init_tx = __esm({
60953
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/tx.ts"() {
60953
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/tx.ts"() {
60954
60954
  import_web388 = __toESM(require_index_cjs(), 1);
60955
60955
  init_constants2();
60956
60956
  _cachedAlts = [];
@@ -77205,10 +77205,10 @@ var require_cjs2 = __commonJS({
77205
77205
  }
77206
77206
  });
77207
77207
 
77208
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_quest.json
77208
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_quest.json
77209
77209
  var nara_quest_default;
77210
77210
  var init_nara_quest = __esm({
77211
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_quest.json"() {
77211
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_quest.json"() {
77212
77212
  nara_quest_default = {
77213
77213
  address: "Quest11111111111111111111111111111111111111",
77214
77214
  metadata: {
@@ -79362,10 +79362,10 @@ var init_nara_quest = __esm({
79362
79362
  }
79363
79363
  });
79364
79364
 
79365
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_agent_registry.json
79365
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_agent_registry.json
79366
79366
  var nara_agent_registry_default;
79367
79367
  var init_nara_agent_registry = __esm({
79368
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_agent_registry.json"() {
79368
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_agent_registry.json"() {
79369
79369
  nara_agent_registry_default = {
79370
79370
  address: "AgentRegistry111111111111111111111111111111",
79371
79371
  metadata: {
@@ -79375,6 +79375,306 @@ var init_nara_agent_registry = __esm({
79375
79375
  description: "Nara Agent Registry - AI agent registration center"
79376
79376
  },
79377
79377
  instructions: [
79378
+ {
79379
+ name: "approve_rejected_twitter",
79380
+ discriminator: [
79381
+ 119,
79382
+ 20,
79383
+ 181,
79384
+ 34,
79385
+ 178,
79386
+ 73,
79387
+ 81,
79388
+ 50
79389
+ ],
79390
+ accounts: [
79391
+ {
79392
+ name: "verifier",
79393
+ writable: true,
79394
+ signer: true
79395
+ },
79396
+ {
79397
+ name: "config",
79398
+ pda: {
79399
+ seeds: [
79400
+ {
79401
+ kind: "const",
79402
+ value: [
79403
+ 99,
79404
+ 111,
79405
+ 110,
79406
+ 102,
79407
+ 105,
79408
+ 103
79409
+ ]
79410
+ }
79411
+ ]
79412
+ }
79413
+ },
79414
+ {
79415
+ name: "agent",
79416
+ pda: {
79417
+ seeds: [
79418
+ {
79419
+ kind: "const",
79420
+ value: [
79421
+ 97,
79422
+ 103,
79423
+ 101,
79424
+ 110,
79425
+ 116
79426
+ ]
79427
+ },
79428
+ {
79429
+ kind: "arg",
79430
+ path: "agent_id"
79431
+ }
79432
+ ]
79433
+ }
79434
+ },
79435
+ {
79436
+ name: "twitter",
79437
+ writable: true,
79438
+ pda: {
79439
+ seeds: [
79440
+ {
79441
+ kind: "const",
79442
+ value: [
79443
+ 116,
79444
+ 119,
79445
+ 105,
79446
+ 116,
79447
+ 116,
79448
+ 101,
79449
+ 114
79450
+ ]
79451
+ },
79452
+ {
79453
+ kind: "account",
79454
+ path: "agent"
79455
+ }
79456
+ ]
79457
+ }
79458
+ },
79459
+ {
79460
+ name: "twitter_handle",
79461
+ writable: true,
79462
+ pda: {
79463
+ seeds: [
79464
+ {
79465
+ kind: "const",
79466
+ value: [
79467
+ 116,
79468
+ 119,
79469
+ 105,
79470
+ 116,
79471
+ 116,
79472
+ 101,
79473
+ 114,
79474
+ 95,
79475
+ 104,
79476
+ 97,
79477
+ 110,
79478
+ 100,
79479
+ 108,
79480
+ 101
79481
+ ]
79482
+ },
79483
+ {
79484
+ kind: "arg",
79485
+ path: "username"
79486
+ }
79487
+ ]
79488
+ }
79489
+ },
79490
+ {
79491
+ name: "authority",
79492
+ writable: true
79493
+ },
79494
+ {
79495
+ name: "twitter_verify_vault",
79496
+ writable: true,
79497
+ pda: {
79498
+ seeds: [
79499
+ {
79500
+ kind: "const",
79501
+ value: [
79502
+ 116,
79503
+ 119,
79504
+ 105,
79505
+ 116,
79506
+ 116,
79507
+ 101,
79508
+ 114,
79509
+ 95,
79510
+ 118,
79511
+ 101,
79512
+ 114,
79513
+ 105,
79514
+ 102,
79515
+ 121,
79516
+ 95,
79517
+ 118,
79518
+ 97,
79519
+ 117,
79520
+ 108,
79521
+ 116
79522
+ ]
79523
+ }
79524
+ ]
79525
+ }
79526
+ },
79527
+ {
79528
+ name: "treasury",
79529
+ writable: true,
79530
+ pda: {
79531
+ seeds: [
79532
+ {
79533
+ kind: "const",
79534
+ value: [
79535
+ 116,
79536
+ 114,
79537
+ 101,
79538
+ 97,
79539
+ 115,
79540
+ 117,
79541
+ 114,
79542
+ 121
79543
+ ]
79544
+ }
79545
+ ]
79546
+ }
79547
+ },
79548
+ {
79549
+ name: "point_mint",
79550
+ writable: true,
79551
+ pda: {
79552
+ seeds: [
79553
+ {
79554
+ kind: "const",
79555
+ value: [
79556
+ 112,
79557
+ 111,
79558
+ 105,
79559
+ 110,
79560
+ 116,
79561
+ 95,
79562
+ 109,
79563
+ 105,
79564
+ 110,
79565
+ 116
79566
+ ]
79567
+ }
79568
+ ]
79569
+ }
79570
+ },
79571
+ {
79572
+ name: "mint_authority",
79573
+ pda: {
79574
+ seeds: [
79575
+ {
79576
+ kind: "const",
79577
+ value: [
79578
+ 109,
79579
+ 105,
79580
+ 110,
79581
+ 116,
79582
+ 95,
79583
+ 97,
79584
+ 117,
79585
+ 116,
79586
+ 104,
79587
+ 111,
79588
+ 114,
79589
+ 105,
79590
+ 116,
79591
+ 121
79592
+ ]
79593
+ }
79594
+ ]
79595
+ }
79596
+ },
79597
+ {
79598
+ name: "authority_point_account",
79599
+ writable: true,
79600
+ pda: {
79601
+ seeds: [
79602
+ {
79603
+ kind: "account",
79604
+ path: "authority"
79605
+ },
79606
+ {
79607
+ kind: "account",
79608
+ path: "token_program"
79609
+ },
79610
+ {
79611
+ kind: "account",
79612
+ path: "point_mint"
79613
+ }
79614
+ ],
79615
+ program: {
79616
+ kind: "const",
79617
+ value: [
79618
+ 140,
79619
+ 151,
79620
+ 37,
79621
+ 143,
79622
+ 78,
79623
+ 36,
79624
+ 137,
79625
+ 241,
79626
+ 187,
79627
+ 61,
79628
+ 16,
79629
+ 41,
79630
+ 20,
79631
+ 142,
79632
+ 13,
79633
+ 131,
79634
+ 11,
79635
+ 90,
79636
+ 19,
79637
+ 153,
79638
+ 218,
79639
+ 255,
79640
+ 16,
79641
+ 132,
79642
+ 4,
79643
+ 142,
79644
+ 123,
79645
+ 216,
79646
+ 219,
79647
+ 233,
79648
+ 248,
79649
+ 89
79650
+ ]
79651
+ }
79652
+ }
79653
+ },
79654
+ {
79655
+ name: "token_program",
79656
+ address: "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
79657
+ },
79658
+ {
79659
+ name: "associated_token_program",
79660
+ address: "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
79661
+ },
79662
+ {
79663
+ name: "system_program",
79664
+ address: "11111111111111111111111111111111"
79665
+ }
79666
+ ],
79667
+ args: [
79668
+ {
79669
+ name: "agent_id",
79670
+ type: "string"
79671
+ },
79672
+ {
79673
+ name: "username",
79674
+ type: "string"
79675
+ }
79676
+ ]
79677
+ },
79378
79678
  {
79379
79679
  name: "approve_tweet",
79380
79680
  discriminator: [
@@ -81161,7 +81461,8 @@ var init_nara_agent_registry = __esm({
81161
81461
  }
81162
81462
  },
81163
81463
  {
81164
- name: "referral_agent"
81464
+ name: "referral_agent",
81465
+ writable: true
81165
81466
  },
81166
81467
  {
81167
81468
  name: "referral_authority",
@@ -81775,7 +82076,8 @@ var init_nara_agent_registry = __esm({
81775
82076
  }
81776
82077
  },
81777
82078
  {
81778
- name: "referral_agent"
82079
+ name: "referral_agent",
82080
+ writable: true
81779
82081
  },
81780
82082
  {
81781
82083
  name: "config",
@@ -83813,6 +84115,11 @@ var init_nara_agent_registry = __esm({
83813
84115
  code: 6046,
83814
84116
  name: "AgentIdReserved",
83815
84117
  msg: "Agent ID length <= 4 is reserved for admin only"
84118
+ },
84119
+ {
84120
+ code: 6047,
84121
+ name: "TwitterNotRejected",
84122
+ msg: "Twitter binding is not in rejected status"
83816
84123
  }
83817
84124
  ],
83818
84125
  types: [
@@ -83923,7 +84230,7 @@ var init_nara_agent_registry = __esm({
83923
84230
  }
83924
84231
  },
83925
84232
  {
83926
- name: "_padding",
84233
+ name: "referral_count",
83927
84234
  type: "u32"
83928
84235
  },
83929
84236
  {
@@ -84439,9 +84746,10 @@ var init_nara_agent_registry = __esm({
84439
84746
  }
84440
84747
  });
84441
84748
 
84442
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/agent_registry.ts
84749
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/agent_registry.ts
84443
84750
  var agent_registry_exports = {};
84444
84751
  __export(agent_registry_exports, {
84752
+ approveRejectedTwitter: () => approveRejectedTwitter,
84445
84753
  approveTweet: () => approveTweet,
84446
84754
  closeBuffer: () => closeBuffer,
84447
84755
  deleteAgent: () => deleteAgent,
@@ -84598,6 +84906,8 @@ function parseAgentRecordData(data) {
84598
84906
  const referralIdLen = buf.readUInt32LE(offset);
84599
84907
  offset += 4;
84600
84908
  const referralId = referralIdLen > 0 ? buf.subarray(offset, offset + referralIdLen).toString("utf-8") : null;
84909
+ offset += 32;
84910
+ const referralCount = buf.readUInt32LE(offset);
84601
84911
  return {
84602
84912
  authority,
84603
84913
  agentId,
@@ -84605,6 +84915,7 @@ function parseAgentRecordData(data) {
84605
84915
  memory,
84606
84916
  version: version3,
84607
84917
  referralId,
84918
+ referralCount,
84608
84919
  createdAt,
84609
84920
  updatedAt
84610
84921
  };
@@ -85278,6 +85589,38 @@ async function rejectTwitter(connection, wallet, agentId, options) {
85278
85589
  const ix = await program3.methods.rejectTwitter(agentId).accounts({ verifier: wallet.publicKey }).instruction();
85279
85590
  return sendTx(connection, wallet, [ix]);
85280
85591
  }
85592
+ async function approveRejectedTwitter(connection, wallet, agentId, username, options, freeStakeDelta, freeStakeReason) {
85593
+ const program3 = createProgram(connection, wallet, options?.programId);
85594
+ const agentPda = getAgentPda(program3.programId, agentId);
85595
+ const accountInfo = await connection.getAccountInfo(agentPda);
85596
+ if (!accountInfo) throw new Error(`Agent "${agentId}" not found`);
85597
+ const authority = new import_web389.PublicKey(accountInfo.data.subarray(8, 40));
85598
+ const pointMint = getPointMintPda(program3.programId);
85599
+ const authorityPointAccount = getAssociatedTokenAddressSync(
85600
+ pointMint,
85601
+ authority,
85602
+ true,
85603
+ TOKEN_2022_PROGRAM_ID
85604
+ );
85605
+ const ix = await program3.methods.approveRejectedTwitter(agentId, username).accounts({
85606
+ verifier: wallet.publicKey,
85607
+ authority,
85608
+ authorityPointAccount
85609
+ }).instruction();
85610
+ const ixs = [ix];
85611
+ if (freeStakeDelta !== void 0 && freeStakeDelta !== 0) {
85612
+ const { makeAdjustFreeStakeIx: makeAdjustFreeStakeIx2 } = await Promise.resolve().then(() => (init_quest(), quest_exports));
85613
+ const freeStakeIx = await makeAdjustFreeStakeIx2(
85614
+ connection,
85615
+ wallet.publicKey,
85616
+ authority,
85617
+ freeStakeDelta,
85618
+ freeStakeReason ?? ""
85619
+ );
85620
+ ixs.push(freeStakeIx);
85621
+ }
85622
+ return sendTx(connection, wallet, ixs);
85623
+ }
85281
85624
  async function approveTweet(connection, wallet, agentId, tweetId, options, freeStakeDelta, freeStakeReason) {
85282
85625
  const program3 = createProgram(connection, wallet, options?.programId);
85283
85626
  const agentPda = getAgentPda(program3.programId, agentId);
@@ -85317,7 +85660,7 @@ async function rejectTweet(connection, wallet, agentId, options) {
85317
85660
  }
85318
85661
  var import_web389, anchor, import_anchor, import_bn, DEFAULT_CHUNK_SIZE, BUFFER_HEADER_SIZE, MEMORY_HEADER_SIZE, BIO_META_HEADER_SIZE;
85319
85662
  var init_agent_registry = __esm({
85320
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/agent_registry.ts"() {
85663
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/agent_registry.ts"() {
85321
85664
  import_web389 = __toESM(require_index_cjs(), 1);
85322
85665
  anchor = __toESM(require_cjs2(), 1);
85323
85666
  import_anchor = __toESM(require_cjs2(), 1);
@@ -165078,7 +165421,7 @@ var init_main3 = __esm({
165078
165421
  }
165079
165422
  });
165080
165423
 
165081
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/quest.ts
165424
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/quest.ts
165082
165425
  var quest_exports = {};
165083
165426
  __export(quest_exports, {
165084
165427
  adjustFreeStake: () => adjustFreeStake,
@@ -165582,7 +165925,7 @@ async function setAirdropConfig(connection, wallet, airdropAmount, maxAirdropCou
165582
165925
  }
165583
165926
  var import_web390, anchor2, import_anchor2, import_bn2, import_meta, BN254_FIELD, WSOL_MINT;
165584
165927
  var init_quest = __esm({
165585
- "node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/quest.ts"() {
165928
+ "node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/quest.ts"() {
165586
165929
  import_web390 = __toESM(require_index_cjs(), 1);
165587
165930
  init_esm2();
165588
165931
  anchor2 = __toESM(require_cjs2(), 1);
@@ -165889,7 +166232,7 @@ var esm_default = base;
165889
166232
  var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
165890
166233
  var esm_default2 = esm_default(ALPHABET);
165891
166234
 
165892
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/client.ts
166235
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/client.ts
165893
166236
  var import_web387 = __toESM(require_index_cjs(), 1);
165894
166237
  var NaraSDK = class {
165895
166238
  connection;
@@ -165904,10 +166247,10 @@ var NaraSDK = class {
165904
166247
  }
165905
166248
  };
165906
166249
 
165907
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
166250
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
165908
166251
  init_constants2();
165909
166252
 
165910
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/sign.ts
166253
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/sign.ts
165911
166254
  var import_tweetnacl = __toESM(require_nacl_fast(), 1);
165912
166255
  function buildSignMessage(params) {
165913
166256
  return Object.keys(params).filter((k2) => k2 !== "sign").sort().map((k2) => `${k2}=${params[k2]}`).join("&");
@@ -165935,17 +166278,17 @@ function signUrl(baseUrl, wallet, params) {
165935
166278
  return url.toString();
165936
166279
  }
165937
166280
 
165938
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
166281
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
165939
166282
  init_tx();
165940
166283
  init_quest();
165941
166284
 
165942
- // node_modules/.pnpm/nara-sdk@1.0.69_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
166285
+ // node_modules/.pnpm/nara-sdk@1.0.74_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
165943
166286
  var import_web391 = __toESM(require_index_cjs(), 1);
165944
166287
  var anchor3 = __toESM(require_cjs2(), 1);
165945
166288
  var import_anchor3 = __toESM(require_cjs2(), 1);
165946
166289
  init_constants2();
165947
166290
 
165948
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_skills_hub.json
166291
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_skills_hub.json
165949
166292
  var nara_skills_hub_default = {
165950
166293
  address: "SkiLLHub11111111111111111111111111111111111",
165951
166294
  metadata: {
@@ -167343,7 +167686,7 @@ var nara_skills_hub_default = {
167343
167686
  ]
167344
167687
  };
167345
167688
 
167346
- // node_modules/.pnpm/nara-sdk@1.0.69_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
167689
+ // node_modules/.pnpm/nara-sdk@1.0.74_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
167347
167690
  init_tx();
167348
167691
  var DEFAULT_CHUNK_SIZE2 = 800;
167349
167692
  var BUFFER_HEADER_SIZE2 = 144;
@@ -167578,7 +167921,7 @@ async function uploadSkillContent(connection, wallet, name, content, options) {
167578
167921
  }
167579
167922
  }
167580
167923
 
167581
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/zkid.ts
167924
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/zkid.ts
167582
167925
  var import_web392 = __toESM(require_index_cjs(), 1);
167583
167926
  var anchor4 = __toESM(require_cjs2(), 1);
167584
167927
  var import_anchor4 = __toESM(require_cjs2(), 1);
@@ -167588,7 +167931,7 @@ var import_bn3 = __toESM(require_bn(), 1);
167588
167931
  init_constants2();
167589
167932
  init_tx();
167590
167933
 
167591
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_zk.json
167934
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/idls/nara_zk.json
167592
167935
  var nara_zk_default = {
167593
167936
  address: "ZKidentity111111111111111111111111111111111",
167594
167937
  metadata: {
@@ -168799,7 +169142,7 @@ var nara_zk_default = {
168799
169142
  ]
168800
169143
  };
168801
169144
 
168802
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/zkid.ts
169145
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/src/zkid.ts
168803
169146
  var import_meta2 = {};
168804
169147
  var BN254_PRIME = 21888242871839275222246405745257275088696311157297823662689037894645226208583n;
168805
169148
  var MERKLE_LEVELS = 64;
@@ -169146,7 +169489,7 @@ async function transferZkIdByCommitment(connection, payer, name, currentIdSecret
169146
169489
  return sendTx(connection, payer, [ix]);
169147
169490
  }
169148
169491
 
169149
- // node_modules/.pnpm/nara-sdk@1.0.69_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
169492
+ // node_modules/.pnpm/nara-sdk@1.0.74_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0.22_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/nara-sdk/index.ts
169150
169493
  init_agent_registry();
169151
169494
  var import_web393 = __toESM(require_index_cjs(), 1);
169152
169495
  var import_bn4 = __toESM(require_bn(), 1);
@@ -172681,6 +173024,7 @@ function registerZkIdCommands(program3) {
172681
173024
 
172682
173025
  // src/cli/commands/agent.ts
172683
173026
  var import_web3103 = __toESM(require_index_cjs(), 1);
173027
+ init_esm2();
172684
173028
  var import_node_fs3 = require("node:fs");
172685
173029
  var DEFAULT_RELAY_URL = process.env.QUEST_RELAY_URL || "https://quest-api.nara.build/";
172686
173030
  async function relaySignAndSend(connection, wallet, relayUrl, endpoint, body) {
@@ -172690,7 +173034,13 @@ async function relaySignAndSend(connection, wallet, relayUrl, endpoint, body) {
172690
173034
  headers: { "Content-Type": "application/json" },
172691
173035
  body: JSON.stringify(body)
172692
173036
  });
172693
- const data = await res.json();
173037
+ const text = await res.text();
173038
+ let data;
173039
+ try {
173040
+ data = JSON.parse(text);
173041
+ } catch {
173042
+ throw new Error(`Relay returned invalid response: ${text.slice(0, 200)}`);
173043
+ }
172694
173044
  if (data.error) throw new Error(data.error);
172695
173045
  const txBuf = Buffer.from(data.transaction, "base64");
172696
173046
  const tx = import_web3103.VersionedTransaction.deserialize(new Uint8Array(txBuf));
@@ -172739,6 +173089,22 @@ async function handleAgentRegister(agentId, options) {
172739
173089
  const result = options.referral ? await registerAgentWithReferral(connection, wallet, agentId, options.referral) : await registerAgent(connection, wallet, agentId);
172740
173090
  signature = result.signature;
172741
173091
  }
173092
+ if (!options.json) printInfo("Confirming transaction...");
173093
+ try {
173094
+ const confirmation = await connection.confirmTransaction(signature, "confirmed");
173095
+ if (confirmation.value.err) {
173096
+ printError(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
173097
+ process.exit(1);
173098
+ }
173099
+ } catch {
173100
+ printWarning("Could not confirm transaction. Verifying on-chain...");
173101
+ try {
173102
+ await getAgentInfo(connection, agentId);
173103
+ } catch {
173104
+ printError("Agent registration not found on-chain. Transaction may have failed.");
173105
+ process.exit(1);
173106
+ }
173107
+ }
172742
173108
  if (!options.json) printSuccess(`Agent "${agentId}" registered!`);
172743
173109
  setAgentId(agentId, rpcUrl, pubkey);
172744
173110
  if (options.json) {
@@ -172769,8 +173135,9 @@ async function handleAgentGet(agentId, options) {
172769
173135
  try {
172770
173136
  const tv = await getTweetVerify(connection, agentId);
172771
173137
  if (tv) {
173138
+ const tweetIdStr = tv.tweetId > 0n && tv.tweetId < 10000000000000000000n ? tv.tweetId.toString() : null;
172772
173139
  tweetVerifyData = {
172773
- tweetId: tv.tweetId.toString(),
173140
+ tweetId: tweetIdStr,
172774
173141
  status: TWEET_VERIFY_STATUS[tv.status] ?? `unknown(${tv.status})`,
172775
173142
  submittedAt: tv.submittedAt ? new Date(tv.submittedAt * 1e3).toISOString() : null,
172776
173143
  lastRewardedAt: tv.lastRewardedAt ? new Date(tv.lastRewardedAt * 1e3).toISOString() : null
@@ -172778,12 +173145,23 @@ async function handleAgentGet(agentId, options) {
172778
173145
  }
172779
173146
  } catch {
172780
173147
  }
173148
+ const POINTS_MINT = new import_web3103.PublicKey("AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J");
173149
+ let points = "0";
173150
+ try {
173151
+ const authority = info.record.authority;
173152
+ const tokenAccount = await getAssociatedTokenAddress(POINTS_MINT, authority, true, TOKEN_2022_PROGRAM_ID);
173153
+ const balance = await connection.getTokenAccountBalance(tokenAccount);
173154
+ points = balance.value.uiAmountString || "0";
173155
+ } catch {
173156
+ }
172781
173157
  const data = {
172782
173158
  agentId: info.record.agentId,
172783
173159
  authority: info.record.authority.toBase58(),
172784
173160
  version: info.record.version,
172785
173161
  bio: info.bio,
172786
173162
  metadata: info.metadata,
173163
+ points,
173164
+ referralCount: info.record.referralCount,
172787
173165
  createdAt: new Date(info.record.createdAt * 1e3).toISOString(),
172788
173166
  updatedAt: info.record.updatedAt ? new Date(info.record.updatedAt * 1e3).toISOString() : null,
172789
173167
  twitter: twitterData,
@@ -172798,6 +173176,8 @@ async function handleAgentGet(agentId, options) {
172798
173176
  console.log(` Version: ${data.version}`);
172799
173177
  console.log(` Bio: ${data.bio ?? "(none)"}`);
172800
173178
  console.log(` Metadata: ${data.metadata ?? "(none)"}`);
173179
+ console.log(` Points: ${data.points}`);
173180
+ console.log(` Referrals: ${data.referralCount}`);
172801
173181
  console.log(` Created: ${data.createdAt}`);
172802
173182
  if (data.updatedAt) console.log(` Updated: ${data.updatedAt}`);
172803
173183
  if (twitterData) {
@@ -172808,7 +173188,10 @@ async function handleAgentGet(agentId, options) {
172808
173188
  }
172809
173189
  if (tweetVerifyData) {
172810
173190
  const verified = tweetVerifyData.lastRewardedAt ? "verified" : "unverified";
172811
- console.log(` Tweet: ${tweetVerifyData.tweetId} (${verified})`);
173191
+ if (tweetVerifyData.tweetId) {
173192
+ const tweetUsername = twitterData?.username ?? "i";
173193
+ console.log(` Tweet: https://x.com/${tweetUsername}/status/${tweetVerifyData.tweetId} (${verified})`);
173194
+ }
172812
173195
  if (tweetVerifyData.lastRewardedAt) console.log(` Tweet last rewarded: ${tweetVerifyData.lastRewardedAt}`);
172813
173196
  }
172814
173197
  console.log("");
@@ -172817,8 +173200,8 @@ async function handleAgentGet(agentId, options) {
172817
173200
  const lastRewarded = new Date(tweetVerifyData.lastRewardedAt).getTime();
172818
173201
  const hoursAgo = (Date.now() - lastRewarded) / (1e3 * 60 * 60);
172819
173202
  if (hoursAgo >= 24) {
172820
- const h2 = Math.floor(hoursAgo);
172821
- console.log(` Tip: Last tweet verified ${h2}h ago (>24h). You can submit a new tweet to earn more stake-free credits.`);
173203
+ const agoStr = hoursAgo >= 48 ? `${Math.floor(hoursAgo / 24)}d` : `${Math.floor(hoursAgo)}h`;
173204
+ console.log(` Tip: Last tweet verified ${agoStr} ago (>24h). You can submit a new tweet to earn more stake-free credits.`);
172822
173205
  } else {
172823
173206
  const hoursLeft = Math.ceil(24 - hoursAgo);
172824
173207
  console.log(` Tip: Next tweet verification available in ~${hoursLeft}h.`);
@@ -173651,7 +174034,7 @@ function registerCommands(program3) {
173651
174034
  }
173652
174035
 
173653
174036
  // bin/nara-cli.ts
173654
- var version2 = true ? "1.0.78" : "dev";
174037
+ var version2 = true ? "1.0.80" : "dev";
173655
174038
  var program2 = new Command();
173656
174039
  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);
173657
174040
  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.78",
3
+ "version": "1.0.80",
4
4
  "description": "CLI for the Nara chain (Solana-compatible)",
5
5
  "homepage": "https://nara.build",
6
6
  "repository": {
@@ -64,7 +64,7 @@
64
64
  "bs58": "^6.0.0",
65
65
  "commander": "^12.1.0",
66
66
  "ed25519-hd-key": "^1.3.0",
67
- "nara-sdk": "^1.0.69",
67
+ "nara-sdk": "^1.0.74",
68
68
  "picocolors": "^1.1.1"
69
69
  },
70
70
  "packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
@@ -88,20 +88,25 @@ You earn:
88
88
  - **Agent Registry rewards + points** (extra rewards for registered agents)
89
89
 
90
90
  ### Step 5: Share & Earn Referral Rewards
91
- Share your agent ID on social media. When others use your agent ID as referral:
92
- - **Registration referral**: You earn **50% of the registration fee** when someone registers with your referral
93
- - **Mining referral**: You receive **Agent Registry referral rewards + points** when referred agents mine
91
+ Share your Agent ID on social media (Twitter/X, Discord, Telegram, etc.). When others register using your Agent ID as referral:
92
+ - **Registration referral**: Earn **50% of the registration fee** + referral points
93
+ - **Mining referral**: Earn **extra points** when referred agents mine
94
+ - Check your points and referral count: `npx naracli agent get`
94
95
 
96
+ ## Points & Referrals
95
97
 
96
- ## Points (Bonus Token)
98
+ Points are on-chain tokens earned through mining, referrals, and Twitter verification. Use `npx naracli agent get` to check your **points balance** and **referral count**.
97
99
 
98
- Points are tracked as a Token-2022 token on-chain. Mint address: `AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J`
99
-
100
- To check points balance:
100
+ Points mint: `AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J`. You can also check with:
101
101
  ```
102
102
  npx naracli token-balance AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J
103
103
  ```
104
104
 
105
+ Ways to earn points:
106
+ - **Mining**: Correct quest answers earn points per round
107
+ - **Referrals**: Earn points when referred agents register and mine
108
+ - **Twitter verification**: Binding Twitter and submitting tweets earn bonus points
109
+
105
110
  ## Spending NARA
106
111
 
107
112
  Earned NARA can be used to purchase AI compute credits. Visit `model-api.nara.build/402` to buy compute power with NARA tokens. **Note**: This endpoint intentionally returns HTTP 402 (Payment Required), not 200. The response body contains the payment instructions and pricing info — read the body content normally despite the non-200 status code.
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { Command } from "commander";
6
6
  import { Connection, PublicKey, VersionedTransaction } from "@solana/web3.js";
7
+ import { getAssociatedTokenAddress, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
7
8
  import { loadWallet, getRpcUrl } from "../utils/wallet";
8
9
  import {
9
10
  printError,
@@ -60,7 +61,13 @@ async function relaySignAndSend(
60
61
  headers: { "Content-Type": "application/json" },
61
62
  body: JSON.stringify(body),
62
63
  });
63
- const data = await res.json() as any;
64
+ const text = await res.text();
65
+ let data: any;
66
+ try {
67
+ data = JSON.parse(text);
68
+ } catch {
69
+ throw new Error(`Relay returned invalid response: ${text.slice(0, 200)}`);
70
+ }
64
71
  if (data.error) throw new Error(data.error);
65
72
 
66
73
  const txBuf = Buffer.from(data.transaction, "base64");
@@ -125,6 +132,24 @@ async function handleAgentRegister(agentId: string, options: GlobalOptions & { r
125
132
  signature = result.signature;
126
133
  }
127
134
 
135
+ // Confirm transaction before saving config
136
+ if (!options.json) printInfo("Confirming transaction...");
137
+ try {
138
+ const confirmation = await connection.confirmTransaction(signature, "confirmed");
139
+ if (confirmation.value.err) {
140
+ printError(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
141
+ process.exit(1);
142
+ }
143
+ } catch {
144
+ printWarning("Could not confirm transaction. Verifying on-chain...");
145
+ try {
146
+ await getAgentInfo(connection, agentId);
147
+ } catch {
148
+ printError("Agent registration not found on-chain. Transaction may have failed.");
149
+ process.exit(1);
150
+ }
151
+ }
152
+
128
153
  if (!options.json) printSuccess(`Agent "${agentId}" registered!`);
129
154
  setAgentId(agentId, rpcUrl, pubkey);
130
155
 
@@ -159,12 +184,13 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
159
184
  }
160
185
 
161
186
  // Fetch tweet verification info
162
- let tweetVerifyData: { tweetId: string; status: string; submittedAt: string | null; lastRewardedAt: string | null } | null = null;
187
+ let tweetVerifyData: { tweetId: string | null; status: string; submittedAt: string | null; lastRewardedAt: string | null } | null = null;
163
188
  try {
164
189
  const tv = await getTweetVerify(connection, agentId);
165
190
  if (tv) {
191
+ const tweetIdStr = tv.tweetId > 0n && tv.tweetId < 10000000000000000000n ? tv.tweetId.toString() : null;
166
192
  tweetVerifyData = {
167
- tweetId: tv.tweetId.toString(),
193
+ tweetId: tweetIdStr,
168
194
  status: TWEET_VERIFY_STATUS[tv.status] ?? `unknown(${tv.status})`,
169
195
  submittedAt: tv.submittedAt ? new Date(tv.submittedAt * 1000).toISOString() : null,
170
196
  lastRewardedAt: tv.lastRewardedAt ? new Date(tv.lastRewardedAt * 1000).toISOString() : null,
@@ -174,12 +200,26 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
174
200
  // Ignore
175
201
  }
176
202
 
203
+ // Fetch points balance
204
+ const POINTS_MINT = new PublicKey("AqJX47z8UT6k6gFpJjzvcAAP4NJkfykW8U8za1evry7J");
205
+ let points = "0";
206
+ try {
207
+ const authority = info.record.authority;
208
+ const tokenAccount = await getAssociatedTokenAddress(POINTS_MINT, authority, true, TOKEN_2022_PROGRAM_ID);
209
+ const balance = await connection.getTokenAccountBalance(tokenAccount);
210
+ points = balance.value.uiAmountString || "0";
211
+ } catch {
212
+ // No token account
213
+ }
214
+
177
215
  const data: Record<string, any> = {
178
216
  agentId: info.record.agentId,
179
217
  authority: info.record.authority.toBase58(),
180
218
  version: info.record.version,
181
219
  bio: info.bio,
182
220
  metadata: info.metadata,
221
+ points,
222
+ referralCount: info.record.referralCount,
183
223
  createdAt: new Date(info.record.createdAt * 1000).toISOString(),
184
224
  updatedAt: info.record.updatedAt ? new Date(info.record.updatedAt * 1000).toISOString() : null,
185
225
  twitter: twitterData,
@@ -195,6 +235,8 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
195
235
  console.log(` Version: ${data.version}`);
196
236
  console.log(` Bio: ${data.bio ?? "(none)"}`);
197
237
  console.log(` Metadata: ${data.metadata ?? "(none)"}`);
238
+ console.log(` Points: ${data.points}`);
239
+ console.log(` Referrals: ${data.referralCount}`);
198
240
  console.log(` Created: ${data.createdAt}`);
199
241
  if (data.updatedAt) console.log(` Updated: ${data.updatedAt}`);
200
242
  // Twitter binding
@@ -207,7 +249,10 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
207
249
  // Tweet verification
208
250
  if (tweetVerifyData) {
209
251
  const verified = tweetVerifyData.lastRewardedAt ? "verified" : "unverified";
210
- console.log(` Tweet: ${tweetVerifyData.tweetId} (${verified})`);
252
+ if (tweetVerifyData.tweetId) {
253
+ const tweetUsername = twitterData?.username ?? "i";
254
+ console.log(` Tweet: https://x.com/${tweetUsername}/status/${tweetVerifyData.tweetId} (${verified})`);
255
+ }
211
256
  if (tweetVerifyData.lastRewardedAt) console.log(` Tweet last rewarded: ${tweetVerifyData.lastRewardedAt}`);
212
257
  }
213
258
  console.log("");
@@ -217,8 +262,8 @@ async function handleAgentGet(agentId: string, options: GlobalOptions) {
217
262
  const lastRewarded = new Date(tweetVerifyData.lastRewardedAt).getTime();
218
263
  const hoursAgo = (Date.now() - lastRewarded) / (1000 * 60 * 60);
219
264
  if (hoursAgo >= 24) {
220
- const h = Math.floor(hoursAgo);
221
- console.log(` Tip: Last tweet verified ${h}h ago (>24h). You can submit a new tweet to earn more stake-free credits.`);
265
+ const agoStr = hoursAgo >= 48 ? `${Math.floor(hoursAgo / 24)}d` : `${Math.floor(hoursAgo)}h`;
266
+ console.log(` Tip: Last tweet verified ${agoStr} ago (>24h). You can submit a new tweet to earn more stake-free credits.`);
222
267
  } else {
223
268
  const hoursLeft = Math.ceil(24 - hoursAgo);
224
269
  console.log(` Tip: Next tweet verification available in ~${hoursLeft}h.`);