@txtcel/mcp 0.2.0 → 0.4.0

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/index.js CHANGED
@@ -3111,9 +3111,9 @@ var require_data = __commonJS({
3111
3111
  }
3112
3112
  });
3113
3113
 
3114
- // node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js
3114
+ // node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/utils.js
3115
3115
  var require_utils = __commonJS({
3116
- "node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js"(exports, module) {
3116
+ "node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/utils.js"(exports, module) {
3117
3117
  "use strict";
3118
3118
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3119
3119
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
@@ -3424,9 +3424,9 @@ var require_utils = __commonJS({
3424
3424
  }
3425
3425
  });
3426
3426
 
3427
- // node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js
3427
+ // node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/schemes.js
3428
3428
  var require_schemes = __commonJS({
3429
- "node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3429
+ "node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3430
3430
  "use strict";
3431
3431
  var { isUUID } = require_utils();
3432
3432
  var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
@@ -3634,9 +3634,9 @@ var require_schemes = __commonJS({
3634
3634
  }
3635
3635
  });
3636
3636
 
3637
- // node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js
3637
+ // node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/index.js
3638
3638
  var require_fast_uri = __commonJS({
3639
- "node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js"(exports, module) {
3639
+ "node_modules/.pnpm/fast-uri@3.1.3/node_modules/fast-uri/index.js"(exports, module) {
3640
3640
  "use strict";
3641
3641
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3642
3642
  var { SCHEMES, getSchemeHandler } = require_schemes();
@@ -3849,7 +3849,7 @@ var require_fast_uri = __commonJS({
3849
3849
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3850
3850
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3851
3851
  try {
3852
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3852
+ parsed.host = new URL("http://" + parsed.host).hostname;
3853
3853
  } catch (e) {
3854
3854
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3855
3855
  }
@@ -6897,9 +6897,9 @@ var require_dist = __commonJS({
6897
6897
  }
6898
6898
  });
6899
6899
 
6900
- // node_modules/.pnpm/bn.js@5.2.3/node_modules/bn.js/lib/bn.js
6900
+ // node_modules/.pnpm/bn.js@5.2.4/node_modules/bn.js/lib/bn.js
6901
6901
  var require_bn = __commonJS({
6902
- "node_modules/.pnpm/bn.js@5.2.3/node_modules/bn.js/lib/bn.js"(exports, module) {
6902
+ "node_modules/.pnpm/bn.js@5.2.4/node_modules/bn.js/lib/bn.js"(exports, module) {
6903
6903
  "use strict";
6904
6904
  (function(module2, exports2) {
6905
6905
  "use strict";
@@ -7679,6 +7679,10 @@ var require_bn = __commonJS({
7679
7679
  }
7680
7680
  if (bitsLeft > 0) {
7681
7681
  this.words[i] = ~this.words[i] & 67108863 >> 26 - bitsLeft;
7682
+ i++;
7683
+ }
7684
+ for (; i < this.length; i++) {
7685
+ this.words[i] = 0;
7682
7686
  }
7683
7687
  return this._strip();
7684
7688
  };
@@ -12491,9 +12495,9 @@ var init_esm_node = __esm({
12491
12495
  }
12492
12496
  });
12493
12497
 
12494
- // node_modules/.pnpm/jayson@4.3.0/node_modules/jayson/lib/generateRequest.js
12498
+ // node_modules/.pnpm/jayson@4.3.0_bufferutil@4.1.0_utf-8-validate@6.0.6/node_modules/jayson/lib/generateRequest.js
12495
12499
  var require_generateRequest = __commonJS({
12496
- "node_modules/.pnpm/jayson@4.3.0/node_modules/jayson/lib/generateRequest.js"(exports, module) {
12500
+ "node_modules/.pnpm/jayson@4.3.0_bufferutil@4.1.0_utf-8-validate@6.0.6/node_modules/jayson/lib/generateRequest.js"(exports, module) {
12497
12501
  "use strict";
12498
12502
  var uuid2 = (init_esm_node(), __toCommonJS(esm_node_exports)).v4;
12499
12503
  var generateRequest = function(method, params, id, options) {
@@ -12535,9 +12539,9 @@ var require_generateRequest = __commonJS({
12535
12539
  }
12536
12540
  });
12537
12541
 
12538
- // node_modules/.pnpm/jayson@4.3.0/node_modules/jayson/lib/client/browser/index.js
12542
+ // node_modules/.pnpm/jayson@4.3.0_bufferutil@4.1.0_utf-8-validate@6.0.6/node_modules/jayson/lib/client/browser/index.js
12539
12543
  var require_browser = __commonJS({
12540
- "node_modules/.pnpm/jayson@4.3.0/node_modules/jayson/lib/client/browser/index.js"(exports, module) {
12544
+ "node_modules/.pnpm/jayson@4.3.0_bufferutil@4.1.0_utf-8-validate@6.0.6/node_modules/jayson/lib/client/browser/index.js"(exports, module) {
12541
12545
  "use strict";
12542
12546
  var uuid2 = (init_esm_node(), __toCommonJS(esm_node_exports)).v4;
12543
12547
  var generateRequest = require_generateRequest();
@@ -33498,7 +33502,7 @@ var StdioServerTransport = class {
33498
33502
  }
33499
33503
  };
33500
33504
 
33501
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
33505
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
33502
33506
  import { Buffer as Buffer2 } from "buffer";
33503
33507
 
33504
33508
  // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/cryptoNode.js
@@ -35735,14 +35739,14 @@ _RistrettoPoint.ZERO = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.
35735
35739
  _RistrettoPoint.Fp = /* @__PURE__ */ (() => Fp)();
35736
35740
  _RistrettoPoint.Fn = /* @__PURE__ */ (() => Fn)();
35737
35741
 
35738
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
35742
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
35739
35743
  var import_bn = __toESM(require_bn());
35740
35744
  var import_bs58 = __toESM(require_bs58());
35741
35745
 
35742
35746
  // node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js
35743
35747
  var sha2562 = sha256;
35744
35748
 
35745
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
35749
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
35746
35750
  var import_borsh = __toESM(require_lib());
35747
35751
  var BufferLayout = __toESM(require_Layout());
35748
35752
  var import_buffer_layout = __toESM(require_Layout());
@@ -36490,7 +36494,7 @@ var getU64Decoder = (config2 = {}) => numberDecoderFactory({
36490
36494
  });
36491
36495
  var getU64Codec = (config2 = {}) => combineCodec(getU64Encoder(config2), getU64Decoder(config2));
36492
36496
 
36493
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
36497
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
36494
36498
  import require$$0 from "util";
36495
36499
  import require$$0$1 from "http";
36496
36500
  import require$$0$2, { Agent } from "https";
@@ -36907,7 +36911,7 @@ function coerce2(struct2, condition, coercer) {
36907
36911
  });
36908
36912
  }
36909
36913
 
36910
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
36914
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
36911
36915
  var import_browser = __toESM(require_browser());
36912
36916
 
36913
36917
  // node_modules/.pnpm/node-fetch@2.7.0/node_modules/node-fetch/lib/index.mjs
@@ -39795,7 +39799,7 @@ function sqrtMod(y) {
39795
39799
  var Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod });
39796
39800
  var secp256k1 = createCurve({ ...secp256k1_CURVE, Fp: Fpk1, lowS: true, endo: secp256k1_ENDO }, sha256);
39797
39801
 
39798
- // node_modules/.pnpm/@solana+web3.js@1.98.4_typescript@5.9.3/node_modules/@solana/web3.js/lib/index.esm.js
39802
+ // node_modules/.pnpm/@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6/node_modules/@solana/web3.js/lib/index.esm.js
39799
39803
  var generatePrivateKey = ed25519.utils.randomPrivateKey;
39800
39804
  var generateKeypair = () => {
39801
39805
  const privateScalar = ed25519.utils.randomPrivateKey();
@@ -47863,7 +47867,7 @@ function loadWallet() {
47863
47867
  }
47864
47868
  }
47865
47869
 
47866
- // node_modules/.pnpm/file+..+txtcel-protocol_@solana+web3.js@1.98.4/node_modules/@txtcel/protocol/dist/index.js
47870
+ // node_modules/.pnpm/@txtcel+protocol@file+..+txtcel-protocol_@solana+web3.js@1.98.4_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@6.0.6_/node_modules/@txtcel/protocol/dist/index.js
47867
47871
  var import_zorsh = __toESM(require_src2(), 1);
47868
47872
  import { Buffer as Buffer3 } from "buffer";
47869
47873
  var TAG_CONTENT = 1;
@@ -47879,7 +47883,7 @@ var ACCESS_DENIED = 1;
47879
47883
  var ACCESS_FEE_EXEMPT = 2;
47880
47884
  var KIND_TEXT = 0;
47881
47885
  var CONTENT_SLOTS = 32;
47882
- var EXTEND_THRESHOLD = 16;
47886
+ var EXTEND_THRESHOLD = 24;
47883
47887
  var MAX_BODY_LEN = 8192;
47884
47888
  var MAX_TITLE_LEN = 64;
47885
47889
  var INDEX_NONE = 4294967295;
@@ -47961,6 +47965,7 @@ var ThreadNodeSchema = import_zorsh.b.struct({
47961
47965
  author: Pubkey,
47962
47966
  messageFee: import_zorsh.b.u64(),
47963
47967
  likeFee: import_zorsh.b.u64(),
47968
+ lastExtendSlot: import_zorsh.b.u64(),
47964
47969
  title: import_zorsh.b.bytes()
47965
47970
  });
47966
47971
  var ProgramSettingsSchema = import_zorsh.b.struct({
@@ -48033,7 +48038,8 @@ var FillSlotInstr = import_zorsh.b.struct({
48033
48038
  });
48034
48039
  var PrepareAllocInstr = import_zorsh.b.struct({
48035
48040
  tag: import_zorsh.b.u8(),
48036
- allocSeq: import_zorsh.b.u32()
48041
+ allocSeq: import_zorsh.b.u32(),
48042
+ witnessSlots: import_zorsh.b.vec(import_zorsh.b.u8())
48037
48043
  });
48038
48044
  var InitThreadAccessInstr = import_zorsh.b.struct({
48039
48045
  tag: import_zorsh.b.u8(),
@@ -48043,7 +48049,8 @@ var InitThreadAccessInstr = import_zorsh.b.struct({
48043
48049
  var RequestAccessInstr = import_zorsh.b.struct({
48044
48050
  tag: import_zorsh.b.u8(),
48045
48051
  treasuryShardIdx: import_zorsh.b.u16(),
48046
- authorFeeShardIdx: import_zorsh.b.u8()
48052
+ authorFeeShardIdx: import_zorsh.b.u8(),
48053
+ maxFee: import_zorsh.b.u64()
48047
48054
  });
48048
48055
  var LikeContentInstr = import_zorsh.b.struct({
48049
48056
  tag: import_zorsh.b.u8(),
@@ -48057,7 +48064,8 @@ var AppendContentInstr = import_zorsh.b.struct({
48057
48064
  tag: import_zorsh.b.u8(),
48058
48065
  chunk: import_zorsh.b.bytes(),
48059
48066
  treasuryShardIdx: import_zorsh.b.u16(),
48060
- authorFeeShardIdx: import_zorsh.b.u8()
48067
+ authorFeeShardIdx: import_zorsh.b.u8(),
48068
+ maxFee: import_zorsh.b.u64()
48061
48069
  });
48062
48070
  var textDecoder = new TextDecoder();
48063
48071
  function decodeContent(pubkey, data) {
@@ -48389,10 +48397,11 @@ function buildFillSlotInstruction(opts) {
48389
48397
  }))
48390
48398
  });
48391
48399
  }
48392
- function buildPrepareAllocInstruction(programId, payer, seed, allocSeq) {
48400
+ function buildPrepareAllocInstruction(programId, payer, seed, allocSeq, witnessSlots = []) {
48393
48401
  const currentAllocPda = deriveAllocPda(programId, seed, allocSeq);
48394
48402
  const newAllocPda = deriveAllocPda(programId, seed, allocSeq + 1);
48395
48403
  const threadAccount = deriveThreadPda(programId, seed);
48404
+ const witnessMetas = witnessSlots.map((slot) => readonlyMeta(deriveContentPda(programId, seed, allocSeq, slot)));
48396
48405
  return new TransactionInstruction({
48397
48406
  programId,
48398
48407
  keys: [
@@ -48400,15 +48409,17 @@ function buildPrepareAllocInstruction(programId, payer, seed, allocSeq) {
48400
48409
  writableMeta(currentAllocPda),
48401
48410
  writableMeta(newAllocPda),
48402
48411
  writableMeta(threadAccount),
48403
- readonlyMeta(SystemProgram.programId)
48412
+ readonlyMeta(SystemProgram.programId),
48413
+ ...witnessMetas
48404
48414
  ],
48405
48415
  data: Buffer3.from(PrepareAllocInstr.serialize({
48406
48416
  tag: Instruction.PrepareAlloc,
48407
- allocSeq
48417
+ allocSeq,
48418
+ witnessSlots: new Uint8Array(witnessSlots)
48408
48419
  }))
48409
48420
  });
48410
48421
  }
48411
- function buildAppendContentInstruction(programId, payer, contentAccount, threadAccount, settingsAccount, treasuryShard, authorFeeShard, chunk, treasuryShardIdx, authorFeeShardIdx) {
48422
+ function buildAppendContentInstruction(programId, payer, contentAccount, threadAccount, settingsAccount, treasuryShard, authorFeeShard, chunk, treasuryShardIdx, authorFeeShardIdx, maxFee) {
48412
48423
  return new TransactionInstruction({
48413
48424
  programId,
48414
48425
  keys: [
@@ -48424,7 +48435,8 @@ function buildAppendContentInstruction(programId, payer, contentAccount, threadA
48424
48435
  tag: Instruction.AppendContent,
48425
48436
  chunk,
48426
48437
  treasuryShardIdx,
48427
- authorFeeShardIdx
48438
+ authorFeeShardIdx,
48439
+ maxFee
48428
48440
  }))
48429
48441
  });
48430
48442
  }
@@ -48435,7 +48447,6 @@ var CANDIDATE_SIZE = 4 + 1;
48435
48447
  var ACCOUNT_KEY_SIZE = 32;
48436
48448
  var FILL_SLOT_BASE_ACCOUNTS = 6;
48437
48449
  var FILL_SLOT_ACCESS_ACCOUNTS = 2;
48438
- var PREPARE_ALLOC_MARGINAL_SIZE = 2 * ACCOUNT_KEY_SIZE + 1 + 1 + 5 + 1 + (1 + 4);
48439
48450
  var CONTENT_NODE_FIXED_SIZE = 89;
48440
48451
  var MAX_FEE_SLIPPAGE_NUM = 2n;
48441
48452
  var APPEND_INSTR_ACCOUNTS = 7;
@@ -48479,6 +48490,10 @@ function pageCandidates(programId, seed, allocSeq) {
48479
48490
  slot
48480
48491
  }));
48481
48492
  }
48493
+ function pickWitnessSlots(occupiedSlots) {
48494
+ if (occupiedSlots.length < EXTEND_THRESHOLD) return null;
48495
+ return shuffle(occupiedSlots).slice(0, EXTEND_THRESHOLD).sort((a, b2) => a - b2);
48496
+ }
48482
48497
  async function buildSendMessageTransactions(connection, programId, payerKey, seed, text, replyTo) {
48483
48498
  const textBytes = ensureTextBytes(text);
48484
48499
  const threadPda = deriveThreadPda(programId, seed);
@@ -48489,10 +48504,9 @@ async function buildSendMessageTransactions(connection, programId, payerKey, see
48489
48504
  const freeInWindow = windowCandidates.filter((_, i) => windowInfos[i] === null);
48490
48505
  const treasuryShardIdx = randomTreasuryShard();
48491
48506
  const authorFeeShardIdx = randomAuthorFeeShard();
48492
- const extendInline = freeInWindow.length === 0;
48493
- const selected = extendInline ? pageCandidates(programId, seed, lastAllocSeq + 1).slice(0, DESIRED_CANDIDATES) : shuffle(freeInWindow).slice(0, DESIRED_CANDIDATES);
48494
- const reserve = extendInline ? PREPARE_ALLOC_MARGINAL_SIZE : 0;
48495
- const maxFirst = maxFillSlotTextLen(selected.length, reserve);
48507
+ const extendFirst = freeInWindow.length === 0;
48508
+ const selected = extendFirst ? pageCandidates(programId, seed, lastAllocSeq + 1).slice(0, DESIRED_CANDIDATES) : shuffle(freeInWindow).slice(0, DESIRED_CANDIDATES);
48509
+ const maxFirst = maxFillSlotTextLen(selected.length);
48496
48510
  const firstChunkLen = Math.min(textBytes.length, maxFirst);
48497
48511
  const firstChunk = textBytes.subarray(0, firstChunkLen);
48498
48512
  const settings = await loadProgramSettings(connection, programId);
@@ -48515,12 +48529,21 @@ async function buildSendMessageTransactions(connection, programId, payerKey, see
48515
48529
  replyAllocSeq: replyTo?.allocSeq ?? null,
48516
48530
  replySlot: replyTo?.slot ?? null
48517
48531
  });
48518
- const firstTx = new Transaction();
48519
- if (extendInline) {
48520
- firstTx.add(buildPrepareAllocInstruction(programId, payerKey, seed, lastAllocSeq));
48532
+ const transactions = [];
48533
+ if (extendFirst) {
48534
+ const isAuthor = payerKey.toBase58() === thread.author;
48535
+ const occupiedTailSlots = windowCandidates.reduce((acc, candidate, index) => {
48536
+ if (candidate.allocSeq === lastAllocSeq && windowInfos[index] !== null) {
48537
+ acc.push(candidate.slot);
48538
+ }
48539
+ return acc;
48540
+ }, []);
48541
+ const witnessSlots = isAuthor ? [] : pickWitnessSlots(occupiedTailSlots) ?? [];
48542
+ transactions.push(
48543
+ new Transaction().add(buildPrepareAllocInstruction(programId, payerKey, seed, lastAllocSeq, witnessSlots))
48544
+ );
48521
48545
  }
48522
- firstTx.add(fillSlotIx);
48523
- const transactions = [firstTx];
48546
+ transactions.push(new Transaction().add(fillSlotIx));
48524
48547
  if (firstChunkLen < textBytes.length) {
48525
48548
  const remaining = textBytes.subarray(firstChunkLen);
48526
48549
  const appendMax = maxAppendChunkLen();
@@ -48528,8 +48551,13 @@ async function buildSendMessageTransactions(connection, programId, payerKey, see
48528
48551
  const settingsPda = deriveSettingsPda(programId);
48529
48552
  const treasuryShardPda = deriveTreasuryShardPda(programId, treasuryShardIdx);
48530
48553
  const authorFeeShardPda = deriveAuthorFeePda(programId, seed, authorFeeShardIdx);
48554
+ const emptyRent = BigInt(await connection.getMinimumBalanceForRentExemption(0, "confirmed"));
48555
+ const oneByteRent = BigInt(await connection.getMinimumBalanceForRentExemption(1, "confirmed"));
48556
+ const rentPerByte = oneByteRent - emptyRent;
48531
48557
  for (let offset2 = 0; offset2 < remaining.length; offset2 += appendMax) {
48532
48558
  const chunk = remaining.subarray(offset2, offset2 + appendMax);
48559
+ const appendBaseFee = BigInt(chunk.length) * rentPerByte * baseFeeBps / 10000n;
48560
+ const appendMaxFee = appendBaseFee * MAX_FEE_SLIPPAGE_NUM + 1n;
48533
48561
  const appendIx = buildAppendContentInstruction(
48534
48562
  programId,
48535
48563
  payerKey,
@@ -48540,7 +48568,8 @@ async function buildSendMessageTransactions(connection, programId, payerKey, see
48540
48568
  authorFeeShardPda,
48541
48569
  chunk,
48542
48570
  treasuryShardIdx,
48543
- authorFeeShardIdx
48571
+ authorFeeShardIdx,
48572
+ appendMaxFee
48544
48573
  );
48545
48574
  transactions.push(new Transaction().add(appendIx));
48546
48575
  }
@@ -48553,10 +48582,18 @@ async function buildExtendAllocTransaction(connection, programId, payerKey, seed
48553
48582
  const lastAllocSeq = thread.lastAllocSeq;
48554
48583
  const tailCandidates = pageCandidates(programId, seed, lastAllocSeq);
48555
48584
  const tailInfos = await connection.getMultipleAccountsInfo(tailCandidates.map((c) => c.pda));
48556
- const freeOnPageN = tailInfos.filter((info) => info === null).length;
48557
- const filled = CONTENT_SLOTS - freeOnPageN;
48558
- if (filled < EXTEND_THRESHOLD) return null;
48559
- return new Transaction().add(buildPrepareAllocInstruction(programId, payerKey, seed, lastAllocSeq));
48585
+ const occupiedTailSlots = tailCandidates.reduce((acc, candidate, index) => {
48586
+ if (tailInfos[index] !== null) {
48587
+ acc.push(candidate.slot);
48588
+ }
48589
+ return acc;
48590
+ }, []);
48591
+ const witnessSlots = pickWitnessSlots(occupiedTailSlots);
48592
+ if (witnessSlots === null) return null;
48593
+ const isAuthor = payerKey.toBase58() === thread.author;
48594
+ return new Transaction().add(
48595
+ buildPrepareAllocInstruction(programId, payerKey, seed, lastAllocSeq, isAuthor ? [] : witnessSlots)
48596
+ );
48560
48597
  }
48561
48598
  function buildCreateRootAllocInstruction(programId, payer, seed, messageFee = 0n, title = "") {
48562
48599
  const titleBytes = new TextEncoder().encode(title);
@@ -48605,16 +48642,13 @@ async function createRootAlloc(connection, programId, payer, messageFee = 0n, ti
48605
48642
  };
48606
48643
  }
48607
48644
  function buildCloseAccountInstruction(programId, payer, targetAccount, likesAccount) {
48608
- const keys = [
48609
- signerMeta(payer),
48610
- writableMeta(targetAccount)
48611
- ];
48612
- if (likesAccount) {
48613
- keys.push(writableMeta(likesAccount));
48614
- }
48615
48645
  return new TransactionInstruction({
48616
48646
  programId,
48617
- keys,
48647
+ keys: [
48648
+ signerMeta(payer),
48649
+ writableMeta(targetAccount),
48650
+ writableMeta(likesAccount)
48651
+ ],
48618
48652
  data: Buffer3.from(TagOnlyInstr.serialize({ tag: Instruction.CloseAccount }))
48619
48653
  });
48620
48654
  }
@@ -48683,7 +48717,7 @@ function buildSetThreadAccessInstruction(programId, authority, accessAccount, en
48683
48717
  }))
48684
48718
  });
48685
48719
  }
48686
- function buildRequestAccessInstruction(programId, payer, seed) {
48720
+ function buildRequestAccessInstruction(programId, payer, seed, maxFee) {
48687
48721
  const accessAccount = deriveAccessPda(programId, seed);
48688
48722
  const entryAccount = deriveAccessEntryPda(programId, seed, payer);
48689
48723
  const threadAccount = deriveThreadPda(programId, seed);
@@ -48707,7 +48741,8 @@ function buildRequestAccessInstruction(programId, payer, seed) {
48707
48741
  data: Buffer3.from(RequestAccessInstr.serialize({
48708
48742
  tag: Instruction.RequestAccess,
48709
48743
  treasuryShardIdx,
48710
- authorFeeShardIdx
48744
+ authorFeeShardIdx,
48745
+ maxFee
48711
48746
  }))
48712
48747
  });
48713
48748
  }
@@ -49076,15 +49111,17 @@ function registerMessagingTools(server) {
49076
49111
  channel: channelArg,
49077
49112
  allocSeq: external_exports.number().int().describe("allocSeq of the target message."),
49078
49113
  slot: external_exports.number().int().describe("slot of the target message."),
49079
- text: external_exports.string().min(1).describe("Text chunk to append.")
49114
+ text: external_exports.string().min(1).describe("Text chunk to append."),
49115
+ maxFee: external_exports.union([external_exports.number(), external_exports.string()]).optional().describe("Max base fee in lamports willing to pay for the append (slippage cap). Default 100000000 (0.1 SOL).")
49080
49116
  }
49081
49117
  },
49082
- handler(async ({ channel, allocSeq, slot, text }) => {
49118
+ handler(async ({ channel, allocSeq, slot, text, maxFee }) => {
49083
49119
  const { programId } = loadConfig();
49084
49120
  const payer = loadWallet();
49085
49121
  const seed = resolveSeed(channel);
49086
49122
  const treasuryShardIdx = randomTreasuryShard();
49087
49123
  const authorFeeShardIdx = randomAuthorFeeShard();
49124
+ const cap = maxFee === void 0 ? 100000000n : toLamports(maxFee);
49088
49125
  const ix = buildAppendContentInstruction(
49089
49126
  programId,
49090
49127
  payer.publicKey,
@@ -49095,7 +49132,8 @@ function registerMessagingTools(server) {
49095
49132
  deriveAuthorFeePda(programId, seed, authorFeeShardIdx),
49096
49133
  new TextEncoder().encode(text),
49097
49134
  treasuryShardIdx,
49098
- authorFeeShardIdx
49135
+ authorFeeShardIdx,
49136
+ cap
49099
49137
  );
49100
49138
  const signature = await sendInstructions(payer, [ix]);
49101
49139
  return jsonResult({ signature, explorer: explorerTx(signature) });
@@ -49105,17 +49143,37 @@ function registerMessagingTools(server) {
49105
49143
  "prepare_alloc",
49106
49144
  {
49107
49145
  title: "Prepare alloc",
49108
- description: "Manually pre-create the next alloc page (allocSeq + 1) in a channel so there are free slots ahead of demand. send_message already does this best-effort; use this to force-extend a high-traffic channel. Racy by design: it fails with InvalidAllocSeq if the chain tail moved on.",
49146
+ description: "Manually pre-create the next alloc page (allocSeq + 1) in a channel. Extension is occupancy-gated on-chain: unless the agent wallet is the channel author (or the last extension is older than the time hatch), the tail page must hold at least EXTEND_THRESHOLD messages \u2014 this tool gathers the witness proof automatically and fails with an explanation when occupancy is too low. Racy by design: it fails with InvalidAllocSeq if the chain tail moved on.",
49109
49147
  inputSchema: {
49110
49148
  channel: channelArg,
49111
49149
  allocSeq: external_exports.number().int().describe("Current alloc seq to extend from.")
49112
49150
  }
49113
49151
  },
49114
49152
  handler(async ({ channel, allocSeq }) => {
49115
- const { programId } = loadConfig();
49153
+ const { connection, programId } = loadConfig();
49116
49154
  const payer = loadWallet();
49117
49155
  const seed = resolveSeed(channel);
49118
- const ix = buildPrepareAllocInstruction(programId, payer.publicKey, seed, allocSeq);
49156
+ const thread = await loadThreadNode(connection, programId, deriveThreadPda(programId, seed));
49157
+ const isAuthor = payer.publicKey.toBase58() === thread.author;
49158
+ let witnessSlots = [];
49159
+ if (!isAuthor) {
49160
+ const pdas = Array.from({ length: CONTENT_SLOTS }, (_, slot) => deriveContentPda(programId, seed, allocSeq, slot));
49161
+ const infos = await connection.getMultipleAccountsInfo(pdas);
49162
+ const occupied = infos.reduce((acc, info, slot) => {
49163
+ if (info !== null) acc.push(slot);
49164
+ return acc;
49165
+ }, []);
49166
+ if (occupied.length < EXTEND_THRESHOLD) {
49167
+ return jsonResult({
49168
+ error: "occupancy below extend threshold",
49169
+ occupied: occupied.length,
49170
+ required: EXTEND_THRESHOLD,
49171
+ hint: "Only the channel author (or the daily time hatch) can extend a page this empty."
49172
+ });
49173
+ }
49174
+ witnessSlots = occupied.slice(0, EXTEND_THRESHOLD);
49175
+ }
49176
+ const ix = buildPrepareAllocInstruction(programId, payer.publicKey, seed, allocSeq, witnessSlots);
49119
49177
  const signature = await sendInstructions(payer, [ix]);
49120
49178
  return jsonResult({ signature, explorer: explorerTx(signature) });
49121
49179
  })
@@ -49171,14 +49229,18 @@ function registerMessagingTools(server) {
49171
49229
  "request_access",
49172
49230
  {
49173
49231
  title: "Request channel access",
49174
- description: "Pay the entry fee to join a gated channel so the agent wallet can post in it.",
49175
- inputSchema: { channel: channelArg }
49232
+ description: "Pay the entry fee to join a gated channel so the agent wallet can post in it. The current on-chain entry fee is used as the slippage cap unless maxFee is given.",
49233
+ inputSchema: {
49234
+ channel: channelArg,
49235
+ maxFee: external_exports.union([external_exports.number(), external_exports.string()]).optional().describe("Max entry fee in lamports willing to pay (slippage cap). Defaults to the current on-chain entry fee.")
49236
+ }
49176
49237
  },
49177
- handler(async ({ channel }) => {
49178
- const { programId } = loadConfig();
49238
+ handler(async ({ channel, maxFee }) => {
49239
+ const { connection, programId } = loadConfig();
49179
49240
  const payer = loadWallet();
49180
49241
  const seed = resolveSeed(channel);
49181
- const ix = buildRequestAccessInstruction(programId, payer.publicKey, seed);
49242
+ const cap = maxFee === void 0 ? (await loadThreadAccess(connection, programId, deriveAccessPda(programId, seed))).entryFee : toLamports(maxFee);
49243
+ const ix = buildRequestAccessInstruction(programId, payer.publicKey, seed, cap);
49182
49244
  const signature = await sendInstructions(payer, [ix]);
49183
49245
  return jsonResult({ signature, explorer: explorerTx(signature) });
49184
49246
  })