@paydprotocol/mcp 0.3.0 → 0.3.1

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/server.js CHANGED
@@ -126,6 +126,7 @@ var GATEWAYS = [
126
126
  var LOG_SPAN = 9000n;
127
127
  var ROOT_WINDOWS = 6n;
128
128
  var GATEWAY_TIMEOUT_MS = 8e3;
129
+ var OLD_GATEWAY_TIMEOUT_MS = 3e3;
129
130
  var robinhoodChain = defineChain({
130
131
  id: CHAIN_ID,
131
132
  name: "Robinhood Chain",
@@ -219,7 +220,7 @@ function createPayd(opts) {
219
220
  for (const path of paths) {
220
221
  for (const gw of gateways) {
221
222
  try {
222
- const res = await fetch(gw.trim() + path, { signal: AbortSignal.timeout(GATEWAY_TIMEOUT_MS) });
223
+ const res = await fetch(gw.trim() + path, { signal: AbortSignal.timeout(publishedAt === void 0 ? GATEWAY_TIMEOUT_MS : OLD_GATEWAY_TIMEOUT_MS) });
223
224
  if (!res.ok) continue;
224
225
  const text = await res.text();
225
226
  if (sha256(toHex(text)) !== digest) continue;
@@ -370,12 +371,15 @@ function createPayd(opts) {
370
371
  *
371
372
  * An empty array if the address is not in the active root — a holder who
372
373
  * arrived after the last publication, or below the threshold. That is not an
373
- * error, it is the answer.
374
+ * error, it is the answer. An artifact no gateway serves IS an error: it
375
+ * used to read as the same empty array, and a holder was told they had
376
+ * nothing when the page simply could not see.
374
377
  */
375
378
  async shares(holder) {
376
379
  if (!isAddress(holder)) throw new Error(`payd: invalid holder address: ${holder}`);
377
- const { artifact, d } = await activeArtifact();
378
- if (!artifact) return [];
380
+ const { artifact, d, rootId } = await activeArtifact();
381
+ if (rootId === 0n) return [];
382
+ if (!artifact) throw new Error("payd: epoch data not found on any gateway");
379
383
  const mine = artifact.entries.filter((e) => e.holder.toLowerCase() === holder.toLowerCase());
380
384
  return Promise.all(mine.map(async (e) => {
381
385
  const stock = e.stock;
@@ -875,7 +879,7 @@ async function holderShares(c, vault, holder) {
875
879
  return {
876
880
  mode,
877
881
  shares: [],
878
- note: "Nothing in the current root for this address. Usually: bought after the last publication, or a share under the value floor \u2014 check again after the next epoch. It can also mean the epoch data could not be fetched from any gateway right now. Not an error either way."
882
+ note: "Nothing in the current root for this address. Usually: bought after the last publication, or a share under the value floor \u2014 check again after the next epoch. Not an error. (Epoch data that cannot be fetched comes back as an error, never as this.)"
879
883
  };
880
884
  }
881
885
  return {
@@ -887,10 +891,18 @@ async function holderShares(c, vault, holder) {
887
891
  async function holderPortfolio(c, holder) {
888
892
  const h = requireAddress("holder", holder);
889
893
  const { tokens } = await listTokens(c, { limit: Number.MAX_SAFE_INTEGER, offset: 0 });
890
- const rows = await Promise.all(tokens.map(async (t) => ({ ...t, ...await holderShares(c, t.vault, h) })));
894
+ const rows = await Promise.all(tokens.map(async (t) => {
895
+ try {
896
+ return { ...t, ...await holderShares(c, t.vault, h) };
897
+ } catch (e) {
898
+ return { ...t, shares: [], error: e.message };
899
+ }
900
+ }));
891
901
  const paying = rows.filter((r) => r.shares.length > 0);
902
+ const unreadable = rows.filter((r) => "error" in r).map((r) => ({ vault: r.vault, symbol: r.symbol, error: r.error }));
892
903
  return {
893
904
  launches: paying,
905
+ ...unreadable.length ? { unreadable } : {},
894
906
  scanned: rows.length,
895
907
  note: "Only launches where this address is in the current root are listed. Backing and lottery launches never list a share (see payd_token_info.howHoldersArePaid). " + UNTRUSTED_NOTE
896
908
  };
@@ -901,7 +913,9 @@ async function holderHistory(c, vault, holder, days) {
901
913
  if (payScreen(mode) !== "claim") return { mode, legs: [], note: PAID_HOW[mode] };
902
914
  const since = Math.floor(Date.now() / 1e3) - Math.round(days * 86400);
903
915
  const r = await createPayd({ vault: v, client: c }).earnedSince(requireAddress("holder", holder), since);
904
- if (!r) throw new Error("the older epoch data could not be fetched from any gateway right now; try again later");
916
+ if (!r) {
917
+ throw new Error(`no epoch data from ${days} days ago: the keeper keeps only its most recent epoch files pinned (a few days' worth), and older ones are dropped by design. Ask for a shorter period.`);
918
+ }
905
919
  return {
906
920
  mode,
907
921
  days,
@@ -957,7 +971,7 @@ async function launchOptions(c) {
957
971
  // src/register.ts
958
972
  import { readFileSync } from "node:fs";
959
973
  import { z } from "zod";
960
- var VERSION = "0.3.0";
974
+ var VERSION = "0.3.1";
961
975
  var run = async (f) => {
962
976
  try {
963
977
  return { content: [{ type: "text", text: toJson(await f()) }] };
package/docs/SDK.md CHANGED
@@ -262,6 +262,7 @@ that is the answer.
262
262
  | What you see | What it is |
263
263
  |---|---|
264
264
  | `shares()` returns nothing for a real holder | they are not in the *current* root — bought after the last publication, or below the threshold. Next epoch fixes it. |
265
+ | `shares()` throws `epoch data not found on any gateway` | the root exists but no gateway served its artifact (since 2026-10-07; it used to return `[]`, which told a holder they had nothing). Retry; it is not their share. |
265
266
  | `activeRoot() == 0` | no root published yet. A brand-new launch. Show "preparing the first payout". |
266
267
  | `economics()` returns zeros | a Pons getter moved. Hide the block; do not show 0 %. |
267
268
  | the artifact fetch fails on every gateway | the content is fine, the gateways are not. Retry, add gateways. Never fall back to unverified content. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paydprotocol/mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Keyless MCP server for Payd on Robinhood Chain: read launches, baskets and holder shares, and prepare unsigned transactions for your own wallet.",
5
5
  "type": "module",
6
6
  "license": "MIT",