agentcash 0.9.1 → 0.9.2

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.
Files changed (51) hide show
  1. package/dist/cjs/run-server.cjs +25 -9
  2. package/dist/esm/{add-skill-CPSJHRFF.js → add-skill-U34U44YC.js} +5 -4
  3. package/dist/esm/{add-skill-CPSJHRFF.js.map → add-skill-U34U44YC.js.map} +1 -1
  4. package/dist/esm/{check-YVZ3KR2P.js → check-DXJXBWT2.js} +5 -4
  5. package/dist/esm/{check-YVZ3KR2P.js.map → check-DXJXBWT2.js.map} +1 -1
  6. package/dist/esm/{chunk-VBQYLC7F.js → chunk-6ZASEAWN.js} +2 -2
  7. package/dist/esm/{chunk-WROGRZ4L.js → chunk-CGFED7FU.js} +2 -2
  8. package/dist/esm/{chunk-4Q7QFS3O.js → chunk-G5IKWSIV.js} +2 -2
  9. package/dist/esm/chunk-GQTOWVH6.js +7 -0
  10. package/dist/esm/{chunk-IB75YFBW.js → chunk-IMJKJGRG.js} +2 -2
  11. package/dist/esm/{chunk-NEJKY3UL.js → chunk-KFJDRCNE.js} +7 -2
  12. package/dist/esm/{chunk-NEJKY3UL.js.map → chunk-KFJDRCNE.js.map} +1 -1
  13. package/dist/esm/{chunk-7QBTMZ6P.js → chunk-OJ7TLSTP.js} +2 -2
  14. package/dist/esm/{chunk-UVO3ZZGC.js → chunk-PGMMXO5J.js} +14 -2
  15. package/dist/esm/{chunk-UVO3ZZGC.js.map → chunk-PGMMXO5J.js.map} +1 -1
  16. package/dist/esm/chunk-TTAO2EJK.js +10 -0
  17. package/dist/esm/chunk-TTAO2EJK.js.map +1 -0
  18. package/dist/esm/{chunk-P7WFI336.js → chunk-UJO2BWV6.js} +2 -2
  19. package/dist/esm/{fetch-IQ6WDIU7.js → fetch-4X4N7TSG.js} +8 -7
  20. package/dist/esm/{fetch-IQ6WDIU7.js.map → fetch-4X4N7TSG.js.map} +1 -1
  21. package/dist/esm/{fetch-auth-KEO66U6Q.js → fetch-auth-R54NXQBZ.js} +5 -4
  22. package/dist/esm/{fetch-auth-KEO66U6Q.js.map → fetch-auth-R54NXQBZ.js.map} +1 -1
  23. package/dist/esm/index.js +21 -20
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/{install-ZGLLK225.js → install-GB7Z3Y7Y.js} +3 -3
  26. package/dist/esm/{onboard-KORBDJEE.js → onboard-IOSC3DTG.js} +5 -5
  27. package/dist/esm/{origins-EYBTV3GF.js → origins-GFGI6TY3.js} +5 -4
  28. package/dist/esm/{origins-EYBTV3GF.js.map → origins-GFGI6TY3.js.map} +1 -1
  29. package/dist/esm/{report-error-352HDKYW.js → report-error-CSI2EPQJ.js} +7 -6
  30. package/dist/esm/{report-error-352HDKYW.js.map → report-error-CSI2EPQJ.js.map} +1 -1
  31. package/dist/esm/{server-UAIAMGJS.js → server-EM2KLQJY.js} +2 -2
  32. package/dist/esm/{server-45ZQGODV.js → server-QT37RZYD.js} +10 -9
  33. package/dist/esm/{server-45ZQGODV.js.map → server-QT37RZYD.js.map} +1 -1
  34. package/dist/esm/{settings-NIG3JCWL.js → settings-I7MPPOB7.js} +4 -3
  35. package/dist/esm/{settings-NIG3JCWL.js.map → settings-I7MPPOB7.js.map} +1 -1
  36. package/dist/esm/{try-IH77VUTC.js → try-2XWGGAAP.js} +7 -6
  37. package/dist/esm/{try-IH77VUTC.js.map → try-2XWGGAAP.js.map} +1 -1
  38. package/dist/esm/{wallet-RXHBDJED.js → wallet-3ZWXDQNE.js} +7 -6
  39. package/dist/esm/{wallet-RXHBDJED.js.map → wallet-3ZWXDQNE.js.map} +1 -1
  40. package/package.json +4 -4
  41. package/dist/esm/chunk-SF3JWCTJ.js +0 -7
  42. /package/dist/esm/{chunk-VBQYLC7F.js.map → chunk-6ZASEAWN.js.map} +0 -0
  43. /package/dist/esm/{chunk-WROGRZ4L.js.map → chunk-CGFED7FU.js.map} +0 -0
  44. /package/dist/esm/{chunk-4Q7QFS3O.js.map → chunk-G5IKWSIV.js.map} +0 -0
  45. /package/dist/esm/{chunk-SF3JWCTJ.js.map → chunk-GQTOWVH6.js.map} +0 -0
  46. /package/dist/esm/{chunk-IB75YFBW.js.map → chunk-IMJKJGRG.js.map} +0 -0
  47. /package/dist/esm/{chunk-7QBTMZ6P.js.map → chunk-OJ7TLSTP.js.map} +0 -0
  48. /package/dist/esm/{chunk-P7WFI336.js.map → chunk-UJO2BWV6.js.map} +0 -0
  49. /package/dist/esm/{install-ZGLLK225.js.map → install-GB7Z3Y7Y.js.map} +0 -0
  50. /package/dist/esm/{onboard-KORBDJEE.js.map → onboard-IOSC3DTG.js.map} +0 -0
  51. /package/dist/esm/{server-UAIAMGJS.js.map → server-EM2KLQJY.js.map} +0 -0
@@ -95225,7 +95225,7 @@ var import_path2 = require("path");
95225
95225
  var import_url = require("url");
95226
95226
  function getVersion() {
95227
95227
  if (true) {
95228
- return "0.9.1";
95228
+ return "0.9.2";
95229
95229
  }
95230
95230
  const __dirname3 = (0, import_path2.dirname)((0, import_url.fileURLToPath)(importMetaUrl));
95231
95231
  const pkg2 = JSON.parse(
@@ -95378,7 +95378,7 @@ var isFetchError = (error48) => {
95378
95378
 
95379
95379
  // src/shared/mpp-enabled.ts
95380
95380
  init_cjs_shims();
95381
- var isMppEnabled = () => "0.9.1".includes("-mpp");
95381
+ var isMppEnabled = () => "0.9.2".includes("-mpp");
95382
95382
 
95383
95383
  // src/operations/fetch-with-payment.ts
95384
95384
  init_cjs_shims();
@@ -120713,12 +120713,28 @@ var setSettings = (settings) => {
120713
120713
  import_fs4.default.writeFileSync(SETTINGS_FILE, JSON.stringify(newSettings, null, 2));
120714
120714
  };
120715
120715
 
120716
+ // src/shared/origins.ts
120717
+ init_cjs_shims();
120718
+ var BLACKLISTED_ORIGINS = [
120719
+ "https://twit.sh",
120720
+ "https://x402.twit.sh"
120721
+ ];
120722
+
120716
120723
  // src/operations/fetch-with-payment.ts
120717
120724
  var DEFAULT_MAX_AMOUNT = 5;
120718
120725
  function createFetchWithPayment(options) {
120719
120726
  const { surface, paymentMethod, timeout, maxAmount } = options;
120720
120727
  const effectiveMaxAmount = maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;
120721
120728
  return async (request) => {
120729
+ const blocked = BLACKLISTED_ORIGINS.find(
120730
+ (origin) => request.url.startsWith(origin)
120731
+ );
120732
+ if (blocked) {
120733
+ return fetchErr(surface, {
120734
+ cause: "network",
120735
+ message: `${blocked} is no longer available. This origin has been deprecated.`
120736
+ });
120737
+ }
120722
120738
  const clonedRequest = request.clone();
120723
120739
  const fallbackRequest = request.clone();
120724
120740
  const probeResult = await safeFetch(surface, request, timeout);
@@ -120944,11 +120960,6 @@ init_cjs_shims();
120944
120960
 
120945
120961
  // src/shared/descriptions.ts
120946
120962
  init_cjs_shims();
120947
-
120948
- // src/shared/origins.ts
120949
- init_cjs_shims();
120950
-
120951
- // src/shared/descriptions.ts
120952
120963
  var ORIGIN_METADATA = {
120953
120964
  ["https://stableenrich.dev" /* StableEnrich */]: {
120954
120965
  title: "StableEnrich",
@@ -120985,6 +120996,10 @@ var ORIGIN_METADATA = {
120985
120996
  ["https://x402facilitator.com" /* X402Facilitator */]: {
120986
120997
  title: "X402 Facilitator",
120987
120998
  description: "Payment facilitation"
120999
+ },
121000
+ ["https://stablemerch.dev" /* StableMerch */]: {
121001
+ title: "StableMerch",
121002
+ description: "Create shirts and mugs with custom images and have them shipped to your address."
120988
121003
  }
120989
121004
  };
120990
121005
  var PRIMARY_ORIGINS = [
@@ -120992,7 +121007,8 @@ var PRIMARY_ORIGINS = [
120992
121007
  "https://stablesocial.dev" /* StableSocial */,
120993
121008
  "https://stablestudio.dev" /* StableStudio */,
120994
121009
  "https://stableupload.dev" /* StableUpload */,
120995
- "https://stableemail.dev" /* StableEmail */
121010
+ "https://stableemail.dev" /* StableEmail */,
121011
+ "https://stablemerch.dev" /* StableMerch */
120996
121012
  ];
120997
121013
  var DESCRIPTIONS = {
120998
121014
  fetch: {
@@ -123030,7 +123046,7 @@ var import_path3 = require("path");
123030
123046
  var import_url2 = require("url");
123031
123047
  function getVersion3() {
123032
123048
  if (true) {
123033
- return "0.9.1";
123049
+ return "0.9.2";
123034
123050
  }
123035
123051
  const __dirname3 = (0, import_path3.dirname)((0, import_url2.fileURLToPath)(importMetaUrl));
123036
123052
  const pkg2 = JSON.parse(
@@ -4,14 +4,15 @@ import {
4
4
  import {
5
5
  addOriginSkill,
6
6
  resolveOrigin
7
- } from "./chunk-7QBTMZ6P.js";
7
+ } from "./chunk-OJ7TLSTP.js";
8
8
  import "./chunk-FRPTMW3B.js";
9
- import "./chunk-IB75YFBW.js";
9
+ import "./chunk-IMJKJGRG.js";
10
10
  import "./chunk-4AS5OYMF.js";
11
- import "./chunk-NEJKY3UL.js";
11
+ import "./chunk-KFJDRCNE.js";
12
12
  import {
13
13
  toJsonObject
14
14
  } from "./chunk-7HVLEKUI.js";
15
+ import "./chunk-TTAO2EJK.js";
15
16
  import "./chunk-P3Z6XR5A.js";
16
17
  import "./chunk-M6OXSG34.js";
17
18
  import "./chunk-VDBUUHJF.js";
@@ -56,4 +57,4 @@ async function addSkillCommand(args, flags) {
56
57
  export {
57
58
  addSkillCommand
58
59
  };
59
- //# sourceMappingURL=add-skill-CPSJHRFF.js.map
60
+ //# sourceMappingURL=add-skill-U34U44YC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/add-skill.ts"],"sourcesContent":["import { successResponse, outputAndExit, type OutputFlags } from '@/cli/output';\nimport { toJsonObject } from '@/shared/neverthrow/json';\nimport type { GlobalFlags } from '@/types';\nimport { addUserOrigin } from '@/shared/user-origins';\nimport { resolveOrigin, addOriginSkill } from '../lib';\n\nconst SURFACE = 'cli:add-skill';\n\ninterface AddSkillArgs {\n url: string;\n}\n\nexport async function addSkillCommand(\n args: AddSkillArgs,\n flags: GlobalFlags<OutputFlags>\n): Promise<void> {\n const resolved = await resolveOrigin(args.url, SURFACE);\n if (!resolved.ok) return outputAndExit(resolved.error, flags);\n\n const { origin } = resolved;\n addUserOrigin(origin);\n\n const skillResult = await addOriginSkill(origin, SURFACE, {\n cwd: process.cwd(),\n });\n\n if (!skillResult.isOk()) {\n origin.warnings.push(\n 'Failed to install skill: ' +\n skillResult.error.cause +\n ' ' +\n skillResult.error.message\n );\n }\n const installedPaths = skillResult.isOk() ? skillResult.value.paths : [];\n\n return outputAndExit(\n successResponse(\n toJsonObject({\n url: origin.url,\n title: origin.title,\n description: origin.description,\n installed: installedPaths,\n note: 'Restart your MCP server for this origin to appear in the model context.',\n ...(origin.warnings.length > 0 && { warnings: origin.warnings }),\n })\n ),\n flags\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAM,UAAU;AAMhB,eAAsB,gBACpB,MACA,OACe;AACf,QAAM,WAAW,MAAM,cAAc,KAAK,KAAK,OAAO;AACtD,MAAI,CAAC,SAAS,GAAI,QAAO,cAAc,SAAS,OAAO,KAAK;AAE5D,QAAM,EAAE,OAAO,IAAI;AACnB,gBAAc,MAAM;AAEpB,QAAM,cAAc,MAAM,eAAe,QAAQ,SAAS;AAAA,IACxD,KAAK,QAAQ,IAAI;AAAA,EACnB,CAAC;AAED,MAAI,CAAC,YAAY,KAAK,GAAG;AACvB,WAAO,SAAS;AAAA,MACd,8BACE,YAAY,MAAM,QAClB,MACA,YAAY,MAAM;AAAA,IACtB;AAAA,EACF;AACA,QAAM,iBAAiB,YAAY,KAAK,IAAI,YAAY,MAAM,QAAQ,CAAC;AAEvE,SAAO;AAAA,IACL;AAAA,MACE,aAAa;AAAA,QACX,KAAK,OAAO;AAAA,QACZ,OAAO,OAAO;AAAA,QACd,aAAa,OAAO;AAAA,QACpB,WAAW;AAAA,QACX,MAAM;AAAA,QACN,GAAI,OAAO,SAAS,SAAS,KAAK,EAAE,UAAU,OAAO,SAAS;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/add-skill.ts"],"sourcesContent":["import { successResponse, outputAndExit, type OutputFlags } from '@/cli/output';\nimport { toJsonObject } from '@/shared/neverthrow/json';\nimport type { GlobalFlags } from '@/types';\nimport { addUserOrigin } from '@/shared/user-origins';\nimport { resolveOrigin, addOriginSkill } from '../lib';\n\nconst SURFACE = 'cli:add-skill';\n\ninterface AddSkillArgs {\n url: string;\n}\n\nexport async function addSkillCommand(\n args: AddSkillArgs,\n flags: GlobalFlags<OutputFlags>\n): Promise<void> {\n const resolved = await resolveOrigin(args.url, SURFACE);\n if (!resolved.ok) return outputAndExit(resolved.error, flags);\n\n const { origin } = resolved;\n addUserOrigin(origin);\n\n const skillResult = await addOriginSkill(origin, SURFACE, {\n cwd: process.cwd(),\n });\n\n if (!skillResult.isOk()) {\n origin.warnings.push(\n 'Failed to install skill: ' +\n skillResult.error.cause +\n ' ' +\n skillResult.error.message\n );\n }\n const installedPaths = skillResult.isOk() ? skillResult.value.paths : [];\n\n return outputAndExit(\n successResponse(\n toJsonObject({\n url: origin.url,\n title: origin.title,\n description: origin.description,\n installed: installedPaths,\n note: 'Restart your MCP server for this origin to appear in the model context.',\n ...(origin.warnings.length > 0 && { warnings: origin.warnings }),\n })\n ),\n flags\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAM,UAAU;AAMhB,eAAsB,gBACpB,MACA,OACe;AACf,QAAM,WAAW,MAAM,cAAc,KAAK,KAAK,OAAO;AACtD,MAAI,CAAC,SAAS,GAAI,QAAO,cAAc,SAAS,OAAO,KAAK;AAE5D,QAAM,EAAE,OAAO,IAAI;AACnB,gBAAc,MAAM;AAEpB,QAAM,cAAc,MAAM,eAAe,QAAQ,SAAS;AAAA,IACxD,KAAK,QAAQ,IAAI;AAAA,EACnB,CAAC;AAED,MAAI,CAAC,YAAY,KAAK,GAAG;AACvB,WAAO,SAAS;AAAA,MACd,8BACE,YAAY,MAAM,QAClB,MACA,YAAY,MAAM;AAAA,IACtB;AAAA,EACF;AACA,QAAM,iBAAiB,YAAY,KAAK,IAAI,YAAY,MAAM,QAAQ,CAAC;AAEvE,SAAO;AAAA,IACL;AAAA,MACE,aAAa;AAAA,QACX,KAAK,OAAO;AAAA,QACZ,OAAO,OAAO;AAAA,QACd,aAAa,OAAO;AAAA,QACpB,WAAW;AAAA,QACX,MAAM;AAAA,QACN,GAAI,OAAO,SAAS,SAAS,KAAK,EAAE,UAAU,OAAO,SAAS;AAAA,MAChE,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
@@ -3,14 +3,15 @@ import {
3
3
  } from "./chunk-2OX7YBGR.js";
4
4
  import {
5
5
  getWalletOrExit
6
- } from "./chunk-7QBTMZ6P.js";
6
+ } from "./chunk-OJ7TLSTP.js";
7
7
  import "./chunk-FRPTMW3B.js";
8
- import "./chunk-IB75YFBW.js";
8
+ import "./chunk-IMJKJGRG.js";
9
9
  import "./chunk-4AS5OYMF.js";
10
- import "./chunk-NEJKY3UL.js";
10
+ import "./chunk-KFJDRCNE.js";
11
11
  import {
12
12
  toJsonObject
13
13
  } from "./chunk-7HVLEKUI.js";
14
+ import "./chunk-TTAO2EJK.js";
14
15
  import "./chunk-P3Z6XR5A.js";
15
16
  import "./chunk-M6OXSG34.js";
16
17
  import "./chunk-VDBUUHJF.js";
@@ -70,4 +71,4 @@ async function checkCommand(args, flags) {
70
71
  export {
71
72
  checkCommand
72
73
  };
73
- //# sourceMappingURL=check-YVZ3KR2P.js.map
74
+ //# sourceMappingURL=check-DXJXBWT2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/check.ts"],"sourcesContent":["import { randomBytes } from 'crypto';\n\nimport { successResponse, outputAndExit, type OutputFlags } from '@/cli/output';\n\nimport {\n checkEndpoint,\n type SupportedMethod,\n} from '@/operations/check-endpoint';\nimport { toJsonObject } from '@/shared/neverthrow/json';\nimport { getWalletOrExit } from '../lib';\n\nimport type { GlobalFlags } from '@/types';\n\nconst SURFACE = 'cli:check';\n\ninterface CheckArgs {\n url: string;\n method?: string;\n body?: string;\n headers?: string;\n}\n\nexport async function checkCommand(\n args: CheckArgs,\n flags: GlobalFlags<OutputFlags>\n): Promise<void> {\n const {\n evmAccount: {\n account: { address },\n },\n } = await getWalletOrExit(flags);\n const sessionId = randomBytes(16).toString('hex');\n\n const parsedBody = args.body\n ? (JSON.parse(args.body) as Record<string, unknown>)\n : undefined;\n const parsedHeaders = args.headers\n ? (JSON.parse(args.headers) as Record<string, string>)\n : undefined;\n\n const result = await checkEndpoint(\n SURFACE,\n args.url,\n args.method ? [args.method as SupportedMethod] : undefined,\n parsedBody,\n {\n ...parsedHeaders,\n 'X-Wallet-Address': address,\n 'X-Session-ID': sessionId,\n }\n );\n\n if (!result.found) {\n return outputAndExit(\n successResponse(\n toJsonObject({\n url: args.url,\n results: [],\n error: result.cause,\n message: result.message,\n })\n ),\n flags\n );\n }\n\n const results = result.advisories.map(a => ({\n ...a,\n requiresPayment: a.authMode === 'paid' || a.authMode === 'apiKey+paid',\n }));\n\n return outputAndExit(\n successResponse(toJsonObject({ url: args.url, results })),\n flags\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,mBAAmB;AAa5B,IAAM,UAAU;AAShB,eAAsB,aACpB,MACA,OACe;AACf,QAAM;AAAA,IACJ,YAAY;AAAA,MACV,SAAS,EAAE,QAAQ;AAAA,IACrB;AAAA,EACF,IAAI,MAAM,gBAAgB,KAAK;AAC/B,QAAM,YAAY,YAAY,EAAE,EAAE,SAAS,KAAK;AAEhD,QAAM,aAAa,KAAK,OACnB,KAAK,MAAM,KAAK,IAAI,IACrB;AACJ,QAAM,gBAAgB,KAAK,UACtB,KAAK,MAAM,KAAK,OAAO,IACxB;AAEJ,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,KAAK;AAAA,IACL,KAAK,SAAS,CAAC,KAAK,MAAyB,IAAI;AAAA,IACjD;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,OAAO;AACjB,WAAO;AAAA,MACL;AAAA,QACE,aAAa;AAAA,UACX,KAAK,KAAK;AAAA,UACV,SAAS,CAAC;AAAA,UACV,OAAO,OAAO;AAAA,UACd,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,WAAW,IAAI,QAAM;AAAA,IAC1C,GAAG;AAAA,IACH,iBAAiB,EAAE,aAAa,UAAU,EAAE,aAAa;AAAA,EAC3D,EAAE;AAEF,SAAO;AAAA,IACL,gBAAgB,aAAa,EAAE,KAAK,KAAK,KAAK,QAAQ,CAAC,CAAC;AAAA,IACxD;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/check.ts"],"sourcesContent":["import { randomBytes } from 'crypto';\n\nimport { successResponse, outputAndExit, type OutputFlags } from '@/cli/output';\n\nimport {\n checkEndpoint,\n type SupportedMethod,\n} from '@/operations/check-endpoint';\nimport { toJsonObject } from '@/shared/neverthrow/json';\nimport { getWalletOrExit } from '../lib';\n\nimport type { GlobalFlags } from '@/types';\n\nconst SURFACE = 'cli:check';\n\ninterface CheckArgs {\n url: string;\n method?: string;\n body?: string;\n headers?: string;\n}\n\nexport async function checkCommand(\n args: CheckArgs,\n flags: GlobalFlags<OutputFlags>\n): Promise<void> {\n const {\n evmAccount: {\n account: { address },\n },\n } = await getWalletOrExit(flags);\n const sessionId = randomBytes(16).toString('hex');\n\n const parsedBody = args.body\n ? (JSON.parse(args.body) as Record<string, unknown>)\n : undefined;\n const parsedHeaders = args.headers\n ? (JSON.parse(args.headers) as Record<string, string>)\n : undefined;\n\n const result = await checkEndpoint(\n SURFACE,\n args.url,\n args.method ? [args.method as SupportedMethod] : undefined,\n parsedBody,\n {\n ...parsedHeaders,\n 'X-Wallet-Address': address,\n 'X-Session-ID': sessionId,\n }\n );\n\n if (!result.found) {\n return outputAndExit(\n successResponse(\n toJsonObject({\n url: args.url,\n results: [],\n error: result.cause,\n message: result.message,\n })\n ),\n flags\n );\n }\n\n const results = result.advisories.map(a => ({\n ...a,\n requiresPayment: a.authMode === 'paid' || a.authMode === 'apiKey+paid',\n }));\n\n return outputAndExit(\n successResponse(toJsonObject({ url: args.url, results })),\n flags\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,mBAAmB;AAa5B,IAAM,UAAU;AAShB,eAAsB,aACpB,MACA,OACe;AACf,QAAM;AAAA,IACJ,YAAY;AAAA,MACV,SAAS,EAAE,QAAQ;AAAA,IACrB;AAAA,EACF,IAAI,MAAM,gBAAgB,KAAK;AAC/B,QAAM,YAAY,YAAY,EAAE,EAAE,SAAS,KAAK;AAEhD,QAAM,aAAa,KAAK,OACnB,KAAK,MAAM,KAAK,IAAI,IACrB;AACJ,QAAM,gBAAgB,KAAK,UACtB,KAAK,MAAM,KAAK,OAAO,IACxB;AAEJ,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,KAAK;AAAA,IACL,KAAK,SAAS,CAAC,KAAK,MAAyB,IAAI;AAAA,IACjD;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,oBAAoB;AAAA,MACpB,gBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,OAAO;AACjB,WAAO;AAAA,MACL;AAAA,QACE,aAAa;AAAA,UACX,KAAK,KAAK;AAAA,UACV,SAAS,CAAC;AAAA,UACV,OAAO,OAAO;AAAA,UACd,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,WAAW,IAAI,QAAM;AAAA,IAC1C,GAAG;AAAA,IACH,iBAAiB,EAAE,aAAa,UAAU,EAAE,aAAa;AAAA,EAC3D,EAAE;AAEF,SAAO;AAAA,IACL,gBAAgB,aAAa,EAAE,KAAK,KAAK,KAAK,QAAQ,CAAC,CAAC;AAAA,IACxD;AAAA,EACF;AACF;","names":[]}
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-RBEVKU3U.js";
7
7
  import {
8
8
  DIST_TAG
9
- } from "./chunk-WROGRZ4L.js";
9
+ } from "./chunk-CGFED7FU.js";
10
10
  import {
11
11
  log,
12
12
  safeReadFile,
@@ -596,4 +596,4 @@ export {
596
596
  tryAddServer,
597
597
  addServer
598
598
  };
599
- //# sourceMappingURL=chunk-VBQYLC7F.js.map
599
+ //# sourceMappingURL=chunk-6ZASEAWN.js.map
@@ -4,7 +4,7 @@ import { dirname, join } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  function getVersion() {
6
6
  if (true) {
7
- return "0.9.1";
7
+ return "0.9.2";
8
8
  }
9
9
  const __dirname2 = dirname(fileURLToPath(import.meta.url));
10
10
  const pkg = JSON.parse(
@@ -19,4 +19,4 @@ export {
19
19
  MCP_VERSION,
20
20
  DIST_TAG
21
21
  };
22
- //# sourceMappingURL=chunk-WROGRZ4L.js.map
22
+ //# sourceMappingURL=chunk-CGFED7FU.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  MCP_VERSION
3
- } from "./chunk-WROGRZ4L.js";
3
+ } from "./chunk-CGFED7FU.js";
4
4
  import {
5
5
  getBaseUrl
6
6
  } from "./chunk-OKHBFFZP.js";
@@ -51,4 +51,4 @@ async function submitErrorReport(surface, input, address, dev) {
51
51
  export {
52
52
  submitErrorReport
53
53
  };
54
- //# sourceMappingURL=chunk-4Q7QFS3O.js.map
54
+ //# sourceMappingURL=chunk-G5IKWSIV.js.map
@@ -0,0 +1,7 @@
1
+ // src/shared/mpp-enabled.ts
2
+ var isMppEnabled = () => "0.9.2".includes("-mpp");
3
+
4
+ export {
5
+ isMppEnabled
6
+ };
7
+ //# sourceMappingURL=chunk-GQTOWVH6.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  REQUEST_PARAMS
3
- } from "./chunk-NEJKY3UL.js";
3
+ } from "./chunk-KFJDRCNE.js";
4
4
 
5
5
  // src/server/tools/lib/request.ts
6
6
  import z from "zod";
@@ -37,4 +37,4 @@ export {
37
37
  requestSchema,
38
38
  buildRequest
39
39
  };
40
- //# sourceMappingURL=chunk-IB75YFBW.js.map
40
+ //# sourceMappingURL=chunk-IMJKJGRG.js.map
@@ -35,6 +35,10 @@ var ORIGIN_METADATA = {
35
35
  ["https://x402facilitator.com" /* X402Facilitator */]: {
36
36
  title: "X402 Facilitator",
37
37
  description: "Payment facilitation"
38
+ },
39
+ ["https://stablemerch.dev" /* StableMerch */]: {
40
+ title: "StableMerch",
41
+ description: "Create shirts and mugs with custom images and have them shipped to your address."
38
42
  }
39
43
  };
40
44
  var PRIMARY_ORIGINS = [
@@ -42,7 +46,8 @@ var PRIMARY_ORIGINS = [
42
46
  "https://stablesocial.dev" /* StableSocial */,
43
47
  "https://stablestudio.dev" /* StableStudio */,
44
48
  "https://stableupload.dev" /* StableUpload */,
45
- "https://stableemail.dev" /* StableEmail */
49
+ "https://stableemail.dev" /* StableEmail */,
50
+ "https://stablemerch.dev" /* StableMerch */
46
51
  ];
47
52
  var DESCRIPTIONS = {
48
53
  fetch: {
@@ -196,4 +201,4 @@ export {
196
201
  REQUEST_PARAMS,
197
202
  TOOL_PARAMS
198
203
  };
199
- //# sourceMappingURL=chunk-NEJKY3UL.js.map
204
+ //# sourceMappingURL=chunk-KFJDRCNE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/shared/descriptions.ts"],"sourcesContent":["/**\n * Single source of truth for all LLM-facing text in the MCP package.\n *\n * `DESCRIPTIONS` covers every tool with both an `mcp` variant (detailed,\n * AI-audience) and a `cli` variant (concise, human-readable for --help).\n * `serverInstructions` is shared across both surfaces.\n *\n * Additional exports cover parameter/output schema descriptions, origin\n * metadata, and prompt content — all LLM-facing text in one place.\n */\n\nimport { Origin } from './origins';\nimport type { UserOrigin } from './user-origins';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Origin metadata (used for MCP resource registration descriptions)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const ORIGIN_METADATA: Record<\n string,\n { title: string; description: string }\n> = {\n [Origin.StableEnrich]: {\n title: 'StableEnrich',\n description:\n 'People/org search, Google Maps, Exa web search, LinkedIn data, Firecrawl scrape, WhitePages, email enrichment',\n },\n [Origin.StableSocial]: {\n title: 'StableSocial',\n description:\n 'Social media data for Twitter, Instagram, TikTok, YouTube, Facebook, Reddit',\n },\n [Origin.StableStudio]: {\n title: 'StableStudio',\n description: 'Generate and edit images and videos',\n },\n [Origin.StableUpload]: {\n title: 'StableUpload',\n description: 'Pay to upload files, get a permanent download URL.',\n },\n [Origin.StableEmail]: {\n title: 'StableEmail',\n description: 'Send emails',\n },\n [Origin.X402Scan]: {\n title: 'X402 Scan',\n description: 'x402 protocol explorer',\n },\n [Origin.Shirt]: {\n title: 'Shirt',\n description: 'Shirt.sh',\n },\n [Origin.X402Puppet]: {\n title: 'X402 Puppet',\n description: 'Browser automation',\n },\n [Origin.X402Facilitator]: {\n title: 'X402 Facilitator',\n description: 'Payment facilitation',\n },\n};\n\nexport const PRIMARY_ORIGINS = [\n Origin.StableEnrich,\n Origin.StableSocial,\n Origin.StableStudio,\n Origin.StableUpload,\n Origin.StableEmail,\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tool descriptions — { mcp, cli } per tool + shared serverInstructions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const DESCRIPTIONS = {\n fetch: {\n mcp: `HTTP fetch with automatic x402 payment handling. Makes the request and, if the endpoint returns 402, signs payment and retries with payment headers. Returns response data along with payment details (price, tx hash) if a payment was made.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic x402 payment handling. If the endpoint returns 402, signs payment and retries — no manual payment steps needed. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch-auth' instead if the endpoint requires identity (SIWX) rather than payment.`,\n },\n\n fetchWithAuth: {\n mcp: `HTTP fetch with automatic SIWX (Sign-In With X) authentication. Sends an authenticated request to a SIWX-protected endpoint. Returns response data gated by the endpoint's authentication requirements.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic SIWX (Sign-In With X) authentication for identity-gated endpoints. No payment required — the wallet is used as an identity proof only. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch-auth <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch' instead if the endpoint requires payment (x402) rather than identity.`,\n },\n\n getWalletInfo: {\n mcp: `Get wallet address and USDC balance. Auto-creates wallet on first use (~/.agentcash/wallet.json). Returns a deposit link if funding is needed. If onboardingCta is present, show its message to the user — it means they haven't onboarded yet and need to either visit the onboard link or deposit directly.`,\n cli: `Get wallet address, USDC balance, and deposit link. Creates the wallet on first use (~/.agentcash/wallet.json). Check this before making paid API calls — if balance is zero, deposit USDC using the returned link.`,\n },\n\n checkEndpointSchema: {\n mcp: [\n `Get the input/output schema and auth mode (paid or SIWX) for a single endpoint.`,\n `Call this to see exactly what fields the request body expects and what the response contains.`,\n `Returns the schema from the origin's OpenAPI spec. Optionally pass sample_input_body to probe the endpoint live (without payment) for an exact price quote — do this when pricing is range-based or quote-based, or when you're unsure about the input schema.`,\n ].join('\\n\\n'),\n cli: `Get the input/output schema and auth mode (paid or SIWX) for an endpoint. Returns exact field names from the OpenAPI spec — call this before 'fetch' or 'fetch-auth' to avoid 400 errors. Pass --body to probe the endpoint live for an exact price quote when pricing is range-based or unclear.`,\n epilogue: `Auth mode tells you which command to use:\\n paid → agentcash fetch <url>\\n SIWX → agentcash fetch-auth <url>`,\n },\n\n discoverApiEndpoints: {\n mcp: [\n `List available endpoints at an API origin. Returns endpoint URLs with descriptions of what each does and the auth mode for each (paid or SIWX). Works with any origin, not just the registered ones.`,\n `Call this when you need to see what routes are available at an origin — whether it's one of the registered origins or any other origin you've identified as useful.`,\n `The response always indicates whether guidance is available. Guidance is documentation published by the API provider explaining how endpoints work together, edge cases, and usage tips. compact guidance is included automatically; set include_guidance=true to force-include full usage documentation when you need to compose two or more endpoints or need clarification on how the origin works.`,\n ].join('\\n\\n'),\n cli: `List available endpoints at an API origin with descriptions and auth modes (paid or SIWX). Works with any origin, not just registered ones. Add --include-guidance for full provider docs when composing multiple endpoints or when usage is unclear.`,\n epilogue: `Registered origins:\\n${PRIMARY_ORIGINS.flatMap(o => (ORIGIN_METADATA[o] ? [` ${o} — ${ORIGIN_METADATA[o].description}`] : [])).join('\\n')}`,\n },\n\n redeemInvite: {\n mcp: `Redeem an invite code for free USDC on Base. One-time use per code. Returns amount received and transaction hash. Use get_wallet_info after to verify balance.`,\n cli: `Redeem an invite code for free USDC on Base. One-time use per code. Run 'wallet info' after to verify the balance landed.`,\n },\n\n try: {\n cli: `Fetch a new origin for its resources and return a prompt guiding the user through the process of calling the first endpoint.`,\n },\n\n reportError: {\n mcp: `EMERGENCY ONLY. Report critical MCP tool bugs. Do NOT use for normal errors (balance, network, 4xx) — those are recoverable.`,\n cli: `Report a critical bug to the agentcash team (emergency only). Do NOT use for normal errors like low balance, network timeouts, or 4xx responses — those are recoverable without filing a report.`,\n },\n\n updateSettings: {\n mcp: `Update user settings (persisted to ~/.agentcash/settings.json). Currently supports maxAmount — the maximum USD amount allowed per fetch request. If a fetch response requests more than this, the payment is rejected. Returns the current settings after applying changes.`,\n },\n\n getSettings: {\n mcp: `Get current user settings. Returns persisted values from ~/.agentcash/settings.json with defaults applied.`,\n },\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dynamic server instructions (includes user-added origins at runtime)\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst WORKFLOW = [\n `Workflow:`,\n `1. If you don't already know your balance, call get_wallet_info. You need a balance for paid endpoints — if it's zero, share the deposit link with the user. SIWX endpoints don't require a balance. You don't need to call this every turn, just before your first paid call or whenever you're unsure.`,\n `2. Call discover_api_endpoints() to get the endpoint index — a list of available routes with descriptions and auth modes. The auth mode for each endpoint tells you whether to use fetch (paid) or fetch_with_auth (SIWX).`,\n `3. Call check_endpoint_schema() to get the exact input/output schema and auth mode for the endpoint you want to call, so you know what fields to pass and what the response contains. Both discover_api_endpoints and check_endpoint_schema return the auth mode.`,\n `4. Call fetch (paid) or fetch_with_auth (SIWX) based on the auth mode, and with the correct input schema.`,\n].join('\\n');\n\nexport function buildServerInstructions(\n userOrigins: UserOrigin[] = []\n): string {\n const allOrigins = [\n ...userOrigins.map(o => ` - ${o.url} — ${o.description}`),\n ...PRIMARY_ORIGINS.flatMap(o =>\n ORIGIN_METADATA[o] ? [` - ${o} — ${ORIGIN_METADATA[o].description}`] : []\n ),\n ].join('\\n');\n\n return [\n `AgentCash lets you call protected APIs — handling both x402 micropayments and SIWX authentication seamlessly. It manages a USDC wallet for paid endpoints (fetch) and signs wallet proofs for identity-gated endpoints (fetch_with_auth).`,\n `The user has installed agentcash because they want to use paid and SIWX-protected APIs as their preferred way to accomplish related tasks.`,\n `Paid endpoints require a wallet balance. SIWX endpoints are free — they only require a wallet identity.`,\n `If a task could be accomplished by one of these registered origins, run the workflow below:\\n${allOrigins}`,\n `discover_api_endpoints also works with any origin beyond this list. If you identify another origin that would be useful for a task, you can use it.`,\n WORKFLOW,\n `If you need to compose multiple endpoints in sequence, or anything about the origin's capabilities is unclear, call discover_api_endpoints with include_guidance=true to retrieve the origin's full usage documentation.`,\n ].join('\\n\\n');\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared request schema parameter descriptions\n// (used by fetch, fetch_with_auth tools)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const REQUEST_PARAMS = {\n url: 'The endpoint URL',\n method: 'HTTP method. Defaults to GET for fetch operations.',\n body: 'Request body for POST/PUT/PATCH methods',\n headers: 'Additional headers to include',\n timeout: 'Request timeout in milliseconds',\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Per-tool parameter and output schema descriptions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const TOOL_PARAMS = {\n fetch: {\n paymentMethod: 'Payment protocol to use. Defaults to auto-detect.',\n maxAmount:\n 'Maximum amount (in USD) to pay per request. Aborts if the endpoint requests more. Defaults to $5. Pass a higher value for known-expensive endpoints.',\n },\n\n checkEndpointSchema: {\n url: 'Full URL of the endpoint to inspect',\n method:\n 'HTTP method to check. If omitted, all methods declared in the spec are returned.',\n sampleInputBody:\n 'Optional. A sample request body to probe the endpoint live (without payment) for exact pricing. Use when pricing is range-based or quote-based, or when you need to verify the input schema. Omit to get the static schema and advisory pricing from the spec.',\n headers: 'Additional headers to include in the probe request',\n },\n\n getWalletInfo: {\n output: {\n address: 'Wallet address (0x...)',\n balance: 'Total USDC balance across all chains',\n chains: 'Balance breakdown by chain',\n isNewWallet: 'Whether the wallet is new and needs to be funded',\n depositLink: 'Link to deposit USDC directly into the wallet',\n onboardingCta:\n 'Present when the user has not yet redeemed an invite code. Show the message to the user — it directs them to onboard or deposit.',\n onboardingCtaOnboardLink: 'Link to the onboarding page',\n onboardingCtaDepositLink: 'Link to deposit USDC directly',\n onboardingCtaMessage: 'Human-readable CTA to show the user',\n message: 'Warning if balance is low',\n chain: 'Chain name',\n chainBalance: 'USDC balance on this chain',\n },\n },\n\n redeemInvite: {\n code: 'The invite code',\n output: {\n amount: 'Amount with unit (e.g., \"5 USDC\")',\n txHash: 'Transaction hash on Base',\n },\n },\n\n discoverApiEndpoints: {\n url: 'The origin URL to discover endpoints on (e.g. https://stableenrich.dev)',\n includeGuidance:\n \"Request the origin's usage guidance. true=always include, false=never include, omit=auto (included when compact). Guidance explains how to compose multiple endpoints and covers edge cases.\",\n },\n\n reportError: {\n tool: 'MCP tool name',\n resource: 'Resource URL',\n summary: '1-2 sentence summary',\n errorMessage: 'Error message',\n stack: 'Stack trace',\n fullReport: 'Detailed report with context, logs, repro steps',\n output: {\n reportId: 'Unique report ID for tracking',\n message: 'Confirmation message',\n },\n },\n} as const;\n"],"mappings":";AAkBO,IAAM,kBAGT;AAAA,EACF,8CAAoB,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,aACE;AAAA,EACJ;AAAA,EACA,8CAAoB,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,aACE;AAAA,EACJ;AAAA,EACA,8CAAoB,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,8CAAoB,GAAG;AAAA,IACrB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,4CAAmB,GAAG;AAAA,IACpB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,sCAAgB,GAAG;AAAA,IACjB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,+BAAa,GAAG;AAAA,IACd,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,0CAAkB,GAAG;AAAA,IACnB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AAAA,EACA,oDAAuB,GAAG;AAAA,IACxB,OAAO;AAAA,IACP,aAAa;AAAA,EACf;AACF;AAEO,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAM/B;AAMO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,IACL,KAAK;AAAA;AAAA;AAAA,IACL,KAAK;AAAA,IACL,UAAU;AAAA;AAAA,EACZ;AAAA,EAEA,eAAe;AAAA,IACb,KAAK;AAAA;AAAA;AAAA,IACL,KAAK;AAAA,IACL,UAAU;AAAA;AAAA,EACZ;AAAA,EAEA,eAAe;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAAA,EAEA,qBAAqB;AAAA,IACnB,KAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,MAAM;AAAA,IACb,KAAK;AAAA,IACL,UAAU;AAAA;AAAA;AAAA,EACZ;AAAA,EAEA,sBAAsB;AAAA,IACpB,KAAK;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,MAAM;AAAA,IACb,KAAK;AAAA,IACL,UAAU;AAAA,EAAwB,gBAAgB,QAAQ,OAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,WAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,CAAE,EAAE,KAAK,IAAI,CAAC;AAAA,EACvJ;AAAA,EAEA,cAAc;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAAA,EAEA,KAAK;AAAA,IACH,KAAK;AAAA,EACP;AAAA,EAEA,aAAa;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAAA,EAEA,gBAAgB;AAAA,IACd,KAAK;AAAA,EACP;AAAA,EAEA,aAAa;AAAA,IACX,KAAK;AAAA,EACP;AACF;AAMA,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEJ,SAAS,wBACd,cAA4B,CAAC,GACrB;AACR,QAAM,aAAa;AAAA,IACjB,GAAG,YAAY,IAAI,OAAK,OAAO,EAAE,GAAG,WAAM,EAAE,WAAW,EAAE;AAAA,IACzD,GAAG,gBAAgB;AAAA,MAAQ,OACzB,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,WAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC;AAAA,IAC3E;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAgG,UAAU;AAAA,IAC1G;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,MAAM;AACf;AAOO,IAAM,iBAAiB;AAAA,EAC5B,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACX;AAMO,IAAM,cAAc;AAAA,EACzB,OAAO;AAAA,IACL,eAAe;AAAA,IACf,WACE;AAAA,EACJ;AAAA,EAEA,qBAAqB;AAAA,IACnB,KAAK;AAAA,IACL,QACE;AAAA,IACF,iBACE;AAAA,IACF,SAAS;AAAA,EACX;AAAA,EAEA,eAAe;AAAA,IACb,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,aAAa;AAAA,MACb,eACE;AAAA,MACF,0BAA0B;AAAA,MAC1B,0BAA0B;AAAA,MAC1B,sBAAsB;AAAA,MACtB,SAAS;AAAA,MACT,OAAO;AAAA,MACP,cAAc;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,cAAc;AAAA,IACZ,MAAM;AAAA,IACN,QAAQ;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,sBAAsB;AAAA,IACpB,KAAK;AAAA,IACL,iBACE;AAAA,EACJ;AAAA,EAEA,aAAa;AAAA,IACX,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,cAAc;AAAA,IACd,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/shared/descriptions.ts"],"sourcesContent":["/**\n * Single source of truth for all LLM-facing text in the MCP package.\n *\n * `DESCRIPTIONS` covers every tool with both an `mcp` variant (detailed,\n * AI-audience) and a `cli` variant (concise, human-readable for --help).\n * `serverInstructions` is shared across both surfaces.\n *\n * Additional exports cover parameter/output schema descriptions, origin\n * metadata, and prompt content — all LLM-facing text in one place.\n */\n\nimport { Origin } from './origins';\nimport type { UserOrigin } from './user-origins';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Origin metadata (used for MCP resource registration descriptions)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const ORIGIN_METADATA: Record<\n string,\n { title: string; description: string }\n> = {\n [Origin.StableEnrich]: {\n title: 'StableEnrich',\n description:\n 'People/org search, Google Maps, Exa web search, LinkedIn data, Firecrawl scrape, WhitePages, email enrichment',\n },\n [Origin.StableSocial]: {\n title: 'StableSocial',\n description:\n 'Social media data for Twitter, Instagram, TikTok, YouTube, Facebook, Reddit',\n },\n [Origin.StableStudio]: {\n title: 'StableStudio',\n description: 'Generate and edit images and videos',\n },\n [Origin.StableUpload]: {\n title: 'StableUpload',\n description: 'Pay to upload files, get a permanent download URL.',\n },\n [Origin.StableEmail]: {\n title: 'StableEmail',\n description: 'Send emails',\n },\n [Origin.X402Scan]: {\n title: 'X402 Scan',\n description: 'x402 protocol explorer',\n },\n [Origin.Shirt]: {\n title: 'Shirt',\n description: 'Shirt.sh',\n },\n [Origin.X402Puppet]: {\n title: 'X402 Puppet',\n description: 'Browser automation',\n },\n [Origin.X402Facilitator]: {\n title: 'X402 Facilitator',\n description: 'Payment facilitation',\n },\n [Origin.StableMerch]: {\n title: 'StableMerch',\n description:\n 'Create shirts and mugs with custom images and have them shipped to your address.',\n },\n};\n\nexport const PRIMARY_ORIGINS = [\n Origin.StableEnrich,\n Origin.StableSocial,\n Origin.StableStudio,\n Origin.StableUpload,\n Origin.StableEmail,\n Origin.StableMerch,\n] as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tool descriptions — { mcp, cli } per tool + shared serverInstructions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const DESCRIPTIONS = {\n fetch: {\n mcp: `HTTP fetch with automatic x402 payment handling. Makes the request and, if the endpoint returns 402, signs payment and retries with payment headers. Returns response data along with payment details (price, tx hash) if a payment was made.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic x402 payment handling. If the endpoint returns 402, signs payment and retries — no manual payment steps needed. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch-auth' instead if the endpoint requires identity (SIWX) rather than payment.`,\n },\n\n fetchWithAuth: {\n mcp: `HTTP fetch with automatic SIWX (Sign-In With X) authentication. Sends an authenticated request to a SIWX-protected endpoint. Returns response data gated by the endpoint's authentication requirements.\\n\\nFor endpoints you haven't called before in this session, you MUST call check_endpoint_schema first to confirm the request body schema. Skipping this causes 400 errors from wrong field names.`,\n cli: `HTTP fetch with automatic SIWX (Sign-In With X) authentication for identity-gated endpoints. No payment required — the wallet is used as an identity proof only. Run 'check <url>' first to confirm the request body schema; skipping this causes 400 errors from wrong field names.`,\n epilogue: `Workflow: check <url> → fetch-auth <url> -m POST -b '{\"field\":\"value\"}'\\nUse 'fetch' instead if the endpoint requires payment (x402) rather than identity.`,\n },\n\n getWalletInfo: {\n mcp: `Get wallet address and USDC balance. Auto-creates wallet on first use (~/.agentcash/wallet.json). Returns a deposit link if funding is needed. If onboardingCta is present, show its message to the user — it means they haven't onboarded yet and need to either visit the onboard link or deposit directly.`,\n cli: `Get wallet address, USDC balance, and deposit link. Creates the wallet on first use (~/.agentcash/wallet.json). Check this before making paid API calls — if balance is zero, deposit USDC using the returned link.`,\n },\n\n checkEndpointSchema: {\n mcp: [\n `Get the input/output schema and auth mode (paid or SIWX) for a single endpoint.`,\n `Call this to see exactly what fields the request body expects and what the response contains.`,\n `Returns the schema from the origin's OpenAPI spec. Optionally pass sample_input_body to probe the endpoint live (without payment) for an exact price quote — do this when pricing is range-based or quote-based, or when you're unsure about the input schema.`,\n ].join('\\n\\n'),\n cli: `Get the input/output schema and auth mode (paid or SIWX) for an endpoint. Returns exact field names from the OpenAPI spec — call this before 'fetch' or 'fetch-auth' to avoid 400 errors. Pass --body to probe the endpoint live for an exact price quote when pricing is range-based or unclear.`,\n epilogue: `Auth mode tells you which command to use:\\n paid → agentcash fetch <url>\\n SIWX → agentcash fetch-auth <url>`,\n },\n\n discoverApiEndpoints: {\n mcp: [\n `List available endpoints at an API origin. Returns endpoint URLs with descriptions of what each does and the auth mode for each (paid or SIWX). Works with any origin, not just the registered ones.`,\n `Call this when you need to see what routes are available at an origin — whether it's one of the registered origins or any other origin you've identified as useful.`,\n `The response always indicates whether guidance is available. Guidance is documentation published by the API provider explaining how endpoints work together, edge cases, and usage tips. compact guidance is included automatically; set include_guidance=true to force-include full usage documentation when you need to compose two or more endpoints or need clarification on how the origin works.`,\n ].join('\\n\\n'),\n cli: `List available endpoints at an API origin with descriptions and auth modes (paid or SIWX). Works with any origin, not just registered ones. Add --include-guidance for full provider docs when composing multiple endpoints or when usage is unclear.`,\n epilogue: `Registered origins:\\n${PRIMARY_ORIGINS.flatMap(o => (ORIGIN_METADATA[o] ? [` ${o} — ${ORIGIN_METADATA[o].description}`] : [])).join('\\n')}`,\n },\n\n redeemInvite: {\n mcp: `Redeem an invite code for free USDC on Base. One-time use per code. Returns amount received and transaction hash. Use get_wallet_info after to verify balance.`,\n cli: `Redeem an invite code for free USDC on Base. One-time use per code. Run 'wallet info' after to verify the balance landed.`,\n },\n\n try: {\n cli: `Fetch a new origin for its resources and return a prompt guiding the user through the process of calling the first endpoint.`,\n },\n\n reportError: {\n mcp: `EMERGENCY ONLY. Report critical MCP tool bugs. Do NOT use for normal errors (balance, network, 4xx) — those are recoverable.`,\n cli: `Report a critical bug to the agentcash team (emergency only). Do NOT use for normal errors like low balance, network timeouts, or 4xx responses — those are recoverable without filing a report.`,\n },\n\n updateSettings: {\n mcp: `Update user settings (persisted to ~/.agentcash/settings.json). Currently supports maxAmount — the maximum USD amount allowed per fetch request. If a fetch response requests more than this, the payment is rejected. Returns the current settings after applying changes.`,\n },\n\n getSettings: {\n mcp: `Get current user settings. Returns persisted values from ~/.agentcash/settings.json with defaults applied.`,\n },\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Dynamic server instructions (includes user-added origins at runtime)\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst WORKFLOW = [\n `Workflow:`,\n `1. If you don't already know your balance, call get_wallet_info. You need a balance for paid endpoints — if it's zero, share the deposit link with the user. SIWX endpoints don't require a balance. You don't need to call this every turn, just before your first paid call or whenever you're unsure.`,\n `2. Call discover_api_endpoints() to get the endpoint index — a list of available routes with descriptions and auth modes. The auth mode for each endpoint tells you whether to use fetch (paid) or fetch_with_auth (SIWX).`,\n `3. Call check_endpoint_schema() to get the exact input/output schema and auth mode for the endpoint you want to call, so you know what fields to pass and what the response contains. Both discover_api_endpoints and check_endpoint_schema return the auth mode.`,\n `4. Call fetch (paid) or fetch_with_auth (SIWX) based on the auth mode, and with the correct input schema.`,\n].join('\\n');\n\nexport function buildServerInstructions(\n userOrigins: UserOrigin[] = []\n): string {\n const allOrigins = [\n ...userOrigins.map(o => ` - ${o.url} — ${o.description}`),\n ...PRIMARY_ORIGINS.flatMap(o =>\n ORIGIN_METADATA[o] ? [` - ${o} — ${ORIGIN_METADATA[o].description}`] : []\n ),\n ].join('\\n');\n\n return [\n `AgentCash lets you call protected APIs — handling both x402 micropayments and SIWX authentication seamlessly. It manages a USDC wallet for paid endpoints (fetch) and signs wallet proofs for identity-gated endpoints (fetch_with_auth).`,\n `The user has installed agentcash because they want to use paid and SIWX-protected APIs as their preferred way to accomplish related tasks.`,\n `Paid endpoints require a wallet balance. SIWX endpoints are free — they only require a wallet identity.`,\n `If a task could be accomplished by one of these registered origins, run the workflow below:\\n${allOrigins}`,\n `discover_api_endpoints also works with any origin beyond this list. If you identify another origin that would be useful for a task, you can use it.`,\n WORKFLOW,\n `If you need to compose multiple endpoints in sequence, or anything about the origin's capabilities is unclear, call discover_api_endpoints with include_guidance=true to retrieve the origin's full usage documentation.`,\n ].join('\\n\\n');\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared request schema parameter descriptions\n// (used by fetch, fetch_with_auth tools)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const REQUEST_PARAMS = {\n url: 'The endpoint URL',\n method: 'HTTP method. Defaults to GET for fetch operations.',\n body: 'Request body for POST/PUT/PATCH methods',\n headers: 'Additional headers to include',\n timeout: 'Request timeout in milliseconds',\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Per-tool parameter and output schema descriptions\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const TOOL_PARAMS = {\n fetch: {\n paymentMethod: 'Payment protocol to use. Defaults to auto-detect.',\n maxAmount:\n 'Maximum amount (in USD) to pay per request. Aborts if the endpoint requests more. Defaults to $5. Pass a higher value for known-expensive endpoints.',\n },\n\n checkEndpointSchema: {\n url: 'Full URL of the endpoint to inspect',\n method:\n 'HTTP method to check. If omitted, all methods declared in the spec are returned.',\n sampleInputBody:\n 'Optional. A sample request body to probe the endpoint live (without payment) for exact pricing. Use when pricing is range-based or quote-based, or when you need to verify the input schema. Omit to get the static schema and advisory pricing from the spec.',\n headers: 'Additional headers to include in the probe request',\n },\n\n getWalletInfo: {\n output: {\n address: 'Wallet address (0x...)',\n balance: 'Total USDC balance across all chains',\n chains: 'Balance breakdown by chain',\n isNewWallet: 'Whether the wallet is new and needs to be funded',\n depositLink: 'Link to deposit USDC directly into the wallet',\n onboardingCta:\n 'Present when the user has not yet redeemed an invite code. Show the message to the user — it directs them to onboard or deposit.',\n onboardingCtaOnboardLink: 'Link to the onboarding page',\n onboardingCtaDepositLink: 'Link to deposit USDC directly',\n onboardingCtaMessage: 'Human-readable CTA to show the user',\n message: 'Warning if balance is low',\n chain: 'Chain name',\n chainBalance: 'USDC balance on this chain',\n },\n },\n\n redeemInvite: {\n code: 'The invite code',\n output: {\n amount: 'Amount with unit (e.g., \"5 USDC\")',\n txHash: 'Transaction hash on Base',\n },\n },\n\n discoverApiEndpoints: {\n url: 'The origin URL to discover endpoints on (e.g. https://stableenrich.dev)',\n includeGuidance:\n \"Request the origin's usage guidance. true=always include, false=never include, omit=auto (included when compact). Guidance explains how to compose multiple endpoints and covers edge cases.\",\n },\n\n reportError: {\n tool: 'MCP tool name',\n resource: 'Resource URL',\n summary: '1-2 sentence summary',\n errorMessage: 'Error message',\n stack: 'Stack trace',\n fullReport: 'Detailed report with context, logs, repro steps',\n output: {\n reportId: 'Unique report ID for tracking',\n message: 'Confirmation message',\n },\n },\n} as const;\n"],"mappings":"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","names":[]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-FRPTMW3B.js";
4
4
  import {
5
5
  requestSchema
6
- } from "./chunk-IB75YFBW.js";
6
+ } from "./chunk-IMJKJGRG.js";
7
7
  import {
8
8
  getWallet
9
9
  } from "./chunk-4AS5OYMF.js";
@@ -207,4 +207,4 @@ export {
207
207
  resolveOrigin,
208
208
  addOriginSkill
209
209
  };
210
- //# sourceMappingURL=chunk-7QBTMZ6P.js.map
210
+ //# sourceMappingURL=chunk-OJ7TLSTP.js.map
@@ -14,10 +14,13 @@ import {
14
14
  } from "./chunk-OKHBFFZP.js";
15
15
  import {
16
16
  isMppEnabled
17
- } from "./chunk-SF3JWCTJ.js";
17
+ } from "./chunk-GQTOWVH6.js";
18
18
  import {
19
19
  networkSchema
20
20
  } from "./chunk-G3AVBW3H.js";
21
+ import {
22
+ BLACKLISTED_ORIGINS
23
+ } from "./chunk-TTAO2EJK.js";
21
24
  import {
22
25
  log
23
26
  } from "./chunk-M6OXSG34.js";
@@ -428,6 +431,15 @@ function createFetchWithPayment(options) {
428
431
  const { surface, paymentMethod, timeout, maxAmount } = options;
429
432
  const effectiveMaxAmount = maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;
430
433
  return async (request) => {
434
+ const blocked = BLACKLISTED_ORIGINS.find(
435
+ (origin) => request.url.startsWith(origin)
436
+ );
437
+ if (blocked) {
438
+ return fetchErr(surface, {
439
+ cause: "network",
440
+ message: `${blocked} is no longer available. This origin has been deprecated.`
441
+ });
442
+ }
431
443
  const clonedRequest = request.clone();
432
444
  const fallbackRequest = request.clone();
433
445
  const probeResult = await safeFetch(surface, request, timeout);
@@ -488,4 +500,4 @@ export {
488
500
  DEFAULT_MAX_AMOUNT,
489
501
  createFetchWithPayment
490
502
  };
491
- //# sourceMappingURL=chunk-UVO3ZZGC.js.map
503
+ //# sourceMappingURL=chunk-PGMMXO5J.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/shared/settings.ts","../../src/shared/protocols/detect.ts","../../src/shared/protocols/mpp/index.ts","../../src/shared/protocols/pick.ts","../../src/shared/protocols/mpp/handle-payment.ts","../../src/shared/protocols/x402/choose-payment-requirement.ts","../../src/shared/protocols/x402/handle-payment.ts","../../src/operations/fetch-with-payment.ts"],"sourcesContent":["import z from 'zod';\nimport fs from 'fs';\n\nimport { configFile } from './fs';\n\nconst SETTINGS_FILE = configFile('settings.json');\n\nconst settingsSchema = z\n .looseObject({\n maxAmount: z.number().positive(),\n })\n .partial();\n\nexport type Settings = z.infer<typeof settingsSchema>;\n\nexport const getSettings = (): Settings => {\n if (!fs.existsSync(SETTINGS_FILE)) {\n return {};\n }\n\n const content = fs.readFileSync(SETTINGS_FILE, 'utf-8');\n const result = settingsSchema.safeParse(JSON.parse(content));\n if (!result.success) {\n return {};\n }\n return result.data;\n};\n\nexport const setSettings = (settings: Settings) => {\n const existing = getSettings();\n const newSettings = settingsSchema.parse({ ...existing, ...settings });\n fs.writeFileSync(SETTINGS_FILE, JSON.stringify(newSettings, null, 2));\n};\n","import { isMppEnabled } from '@/shared/mpp-enabled';\nimport type { PaymentProtocol } from './types';\n\n/**\n * Detects all payment protocols present in a 402 response.\n * MPP responses include a `WWW-Authenticate` header starting with \"Payment\".\n * x402 responses include a `payment-required` header.\n * If neither is explicitly detected, defaults to x402.\n *\n * MPP detection is gated behind {@link isMppEnabled} so it never surfaces\n * in agent context on the `latest` dist-tag.\n */\nexport function detectPaymentProtocols(response: Response): PaymentProtocol[] {\n const protocols: PaymentProtocol[] = [];\n if (isMppEnabled()) {\n const wwwAuth = response.headers.get('WWW-Authenticate');\n if (wwwAuth?.startsWith('Payment')) {\n protocols.push('mpp');\n }\n }\n const paymentRequired = response.headers.get('payment-required');\n if (paymentRequired) {\n protocols.push('x402');\n }\n // If we couldn't detect either explicitly, default to x402\n if (protocols.length === 0) {\n protocols.push('x402');\n }\n return protocols;\n}\n","import { Challenge, Receipt } from 'mppx';\nimport { Methods } from 'mppx/tempo';\nimport {\n err,\n ok,\n resultFromPromise,\n resultFromThrowable,\n} from '@agentcash/neverthrow';\n\nimport { Mppx, tempo as tempoMethod } from 'mppx/client';\n\nimport { createClient, http } from 'viem';\nimport { tempo } from 'viem/chains';\n\nimport { isMppEnabled } from '@/shared/mpp-enabled';\n\nimport type { BaseMppError } from './types';\nimport type { Wallets } from '@/wallet';\n\nconst errorType = 'mpp';\n\nexport const mppOk = <T>(value: T) => ok(value);\nexport const mppErr = (surface: string, error: BaseMppError) =>\n err(errorType, surface, error);\n\nconst mppResultFromPromise = <T>(\n surface: string,\n promise: Promise<T>,\n error: (e: unknown) => BaseMppError\n) => resultFromPromise(errorType, surface, promise, error);\n\nconst mppResultFromThrowable = <T>(\n surface: string,\n fn: () => T,\n error: (e: unknown) => BaseMppError\n) => resultFromThrowable(errorType, surface, fn, error);\n\nexport const safeGetMppChallenge = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () => Challenge.fromResponse(response, { methods: [Methods.charge] }),\n error => ({\n cause: 'parse_mpp_challenge',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP challenge from response',\n })\n );\n};\n\nexport const safeCreateMppCredential = (\n surface: string,\n wallets: Wallets,\n response: Response\n) => {\n if (!isMppEnabled()) {\n return mppErr(surface, {\n cause: 'mpp_disabled',\n message: 'MPP is not enabled',\n });\n }\n\n const TEMPO_RPC_URL =\n 'https://eng:acard-melody-fashion-finish@rpc.mainnet.tempo.xyz';\n\n const client = Mppx.create({\n polyfill: false,\n methods: [\n tempoMethod({\n account: wallets.evmAccount.account,\n getClient: () =>\n createClient({\n chain: tempo,\n transport: http(TEMPO_RPC_URL),\n }),\n }),\n ],\n });\n\n return mppResultFromPromise(\n surface,\n client.createCredential(response),\n error => ({\n cause: 'create_mpp_credential',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to create MPP credential',\n })\n );\n};\n\nexport const safeGetMppReceipt = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () => Receipt.fromResponse(response),\n error => ({\n cause: 'parse_mpp_receipt',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP receipt from response',\n })\n );\n};\n","import { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { safeGetMppChallenge } from '@/shared/protocols/mpp';\n\nimport { log } from '@/shared/log';\nimport { getBalance } from '@/shared/balance';\nimport { Network } from '@agentcash/networks';\n\nimport type { FetchWithPaymentOptions } from '@/operations/fetch-with-payment';\n\n/**\n * Pick the preferred protocol by comparing wallet balances.\n * Falls back to 'mpp' if both balances fail to fetch.\n */\nexport async function pickByBalance(\n response: Response,\n options: FetchWithPaymentOptions\n): Promise<'x402' | 'mpp'> {\n const { surface, wallets, flags } = options;\n\n // Get x402 (USDC on Base) balance\n const x402BalanceResult = await resultFromPromise(\n 'balance',\n surface,\n getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: Network.BASE,\n },\n flags\n ).then(r => (r.isOk() ? r.value.balance : 0)),\n () => ({\n cause: 'x402_balance' as const,\n message: 'Failed to get x402 balance',\n })\n );\n\n if (x402BalanceResult.isErr()) {\n log.debug('Balance comparison failed, defaulting to mpp');\n return 'mpp';\n }\n\n const x402Balance = x402BalanceResult.value;\n\n // Get MPP (Tempo) balance — need token address from the challenge\n let mppBalance = 0;\n const challengeResult = safeGetMppChallenge(surface, response);\n if (challengeResult.isOk()) {\n const currency = challengeResult.value.request.currency as\n | string\n | undefined;\n const decimals = 6;\n if (currency) {\n const tempoResult = await getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: Network.TEMPO,\n },\n flags\n );\n if (tempoResult.isOk()) {\n mppBalance = Number(tempoResult.value.balance ?? (0).toFixed(decimals));\n }\n }\n }\n\n log.info(`Protocol selection — x402: $${x402Balance}, mpp: $${mppBalance}`);\n return x402Balance >= mppBalance ? 'x402' : 'mpp';\n}\n","import { formatUnits } from 'viem';\n\nimport { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeGetMppChallenge,\n safeCreateMppCredential,\n safeGetMppReceipt,\n mppErr,\n mppOk,\n} from '@/shared/protocols/mpp';\n\nimport type { FetchWithPaymentResult } from '@/operations/fetch-with-payment';\nimport type { HandlePaymentParams } from '../types';\nimport { Network } from '@agentcash/networks';\n\nexport async function handleMppPayment({\n response,\n clonedRequest,\n options,\n maxAmount,\n}: HandlePaymentParams) {\n const { surface, wallets, beforePayment, timeout } = options;\n\n // Prevent retry loops\n if (clonedRequest.headers.has('Authorization')) {\n return mppErr(surface, {\n cause: 'mpp_payment_already_attempted',\n message: 'MPP payment already attempted',\n });\n }\n\n // Parse the challenge from the WWW-Authenticate header\n const challengeResult = safeGetMppChallenge(surface, response);\n\n if (challengeResult.isErr()) {\n return challengeResult;\n }\n\n const challenge = challengeResult.value;\n\n // Extract payment info from challenge request\n const amount = Number(formatUnits(BigInt(challenge.request.amount), 6));\n const currency = challenge.request.currency;\n\n if (amount > maxAmount) {\n return mppErr(surface, {\n cause: 'mpp_payment_amount_exceeds_max_amount' as const,\n message: `Endpoint requested $${amount} which exceeds the maximum allowed amount of $${maxAmount}. Pass a higher maxAmount on this call, or use update_settings to raise the default permanently.`,\n });\n }\n\n if (beforePayment) {\n const hookResult = await resultFromPromise(\n 'mpp',\n surface,\n beforePayment({\n protocol: 'mpp',\n amount,\n currency,\n network: Network.TEMPO,\n }),\n e => ({\n cause: 'before_payment_hook_failed' as const,\n message: e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return mppErr(surface, hookResult.error);\n }\n }\n\n const credentialResult = await safeCreateMppCredential(\n surface,\n wallets,\n response\n );\n\n if (credentialResult.isErr()) {\n return credentialResult;\n }\n\n const credential = credentialResult.value;\n\n // Set Authorization header on cloned request\n clonedRequest.headers.set('Authorization', credential);\n\n // Retry the fetch with the credential\n return await safeFetch(surface, clonedRequest, timeout).andThen(\n paidResponse => {\n // Parse the receipt for transaction hash\n const receiptResult = safeGetMppReceipt(surface, paidResponse);\n\n return mppOk<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'mpp',\n price: amount.toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n }),\n payment: receiptResult.isOk()\n ? {\n success: true,\n transactionHash: receiptResult.value.reference,\n }\n : null,\n },\n });\n }\n );\n}\n","import { getBalance } from '@/shared/balance';\nimport { Network, networkSchema } from '@agentcash/networks';\n\nimport type { PaymentRequirements } from '@x402/core/types';\nimport type { FetchWithPaymentOptions } from '@/operations/fetch-with-payment';\n\ninterface ChoosePaymentRequirementParams {\n paymentRequirements: PaymentRequirements[];\n options: FetchWithPaymentOptions;\n}\n\nexport const choosePaymentRequirement = async ({\n paymentRequirements,\n options,\n}: ChoosePaymentRequirementParams) => {\n const { surface, paymentNetwork, wallets, flags } = options;\n if (paymentNetwork) {\n return paymentRequirements.find(\n pr => pr.network === (paymentNetwork as string)\n );\n }\n\n const requirementsWithBalance = await Promise.all(\n paymentRequirements.map(async pr => {\n const parsedNetwork = networkSchema.safeParse(pr.network);\n if (!parsedNetwork.success) {\n return {\n balance: 0,\n requirement: pr,\n };\n }\n if (parsedNetwork.data === Network.SOLANA) {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.svmAccount.account.address,\n network: parsedNetwork.data,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n } else {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: parsedNetwork.data,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n }\n })\n );\n return requirementsWithBalance.sort((a, b) => b.balance - a.balance)[0]!\n .requirement;\n};\n","import { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { choosePaymentRequirement } from './choose-payment-requirement';\n\nimport { safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeCreatePaymentPayload,\n safeGetPaymentRequired,\n safeGetPaymentSettlement,\n x402Err,\n x402Ok,\n x402ProbeClient,\n} from '@/shared/protocols/x402';\nimport { tokenStringToNumber } from '@/shared/utils';\n\nimport type { FetchWithPaymentResult } from '@/operations/fetch-with-payment';\nimport type { HandlePaymentParams } from '../types';\nimport type { Network } from '@agentcash/networks';\n\nexport async function handleX402Payment({\n response,\n clonedRequest,\n options,\n maxAmount,\n}: HandlePaymentParams) {\n const { surface, wallets, beforePayment, timeout } = options;\n\n const paymentRequiredResult = await safeGetPaymentRequired(surface, response);\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const paymentRequired = paymentRequiredResult.value;\n\n if (paymentRequired.x402Version === 1) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint uses the x402 v1 format, which is not supported by agentcash. Only x402 v2 servers (with an `accepts` array in the Payment-Required header) are supported.',\n });\n }\n\n if (!paymentRequired.accepts || !Array.isArray(paymentRequired.accepts)) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint has a missing or malformed accepts array in the Payment-Required header.',\n });\n }\n\n // Check amount against maxAmount before any payment logic\n const accept = await choosePaymentRequirement({\n options,\n paymentRequirements: paymentRequired.accepts,\n });\n\n if (accept) {\n const amount = tokenStringToNumber(accept.amount);\n if (amount > maxAmount) {\n return x402Err(surface, {\n cause: 'payment_amount_exceeds_max_amount' as const,\n message: `Endpoint requested $${amount} which exceeds the maximum allowed amount of $${maxAmount}. Pass a higher maxAmount on this call, or use update_settings to raise the default permanently.`,\n });\n }\n\n if (beforePayment) {\n const amount = tokenStringToNumber(accept.amount);\n const hookResult = await resultFromPromise(\n 'x402',\n surface,\n beforePayment({\n protocol: 'x402',\n amount,\n currency: 'USDC',\n network: accept.network as Network,\n }),\n e => ({\n cause: 'payment_already_attempted' as const,\n message:\n e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return x402Err(surface, hookResult.error);\n }\n }\n }\n\n const paymentPayloadResult = await safeCreatePaymentPayload(\n surface,\n wallets,\n paymentRequired,\n accept ? () => accept : undefined\n );\n\n if (paymentPayloadResult.isErr()) {\n return paymentPayloadResult;\n }\n\n const paymentPayload = paymentPayloadResult.value;\n\n // Encode payment header\n const paymentHeaders =\n x402ProbeClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Check if this is already a retry to prevent infinite loops\n if (\n clonedRequest.headers.has('PAYMENT-SIGNATURE') ||\n clonedRequest.headers.has('X-PAYMENT')\n ) {\n return x402Err(surface, {\n cause: 'payment_already_attempted',\n message: 'Payment already attempted',\n });\n }\n\n // Add payment headers to cloned request\n for (const [key, value] of Object.entries(paymentHeaders)) {\n clonedRequest.headers.set(key, value);\n }\n clonedRequest.headers.set(\n 'Access-Control-Expose-Headers',\n 'PAYMENT-RESPONSE,X-PAYMENT-RESPONSE'\n );\n\n // Retry the request with payment\n return await safeFetch(surface, clonedRequest, timeout).andThen(\n paidResponse => {\n const settlementResult = safeGetPaymentSettlement(surface, paidResponse);\n\n return x402Ok<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'x402',\n price: tokenStringToNumber(\n paymentPayload.accepted.amount\n ).toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n }),\n payment: settlementResult.isOk()\n ? {\n success: settlementResult.value.success,\n transactionHash: settlementResult.value.transaction,\n }\n : null,\n },\n });\n }\n );\n}\n","import type { GlobalFlags } from '@/types';\n\nimport { fetchErr, fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\n\nimport { detectPaymentProtocols } from '@/shared/protocols/detect';\nimport { pickByBalance } from '@/shared/protocols/pick';\n\nimport { handleMppPayment } from '@/shared/protocols/mpp/handle-payment';\nimport { handleX402Payment } from '@/shared/protocols/x402/handle-payment';\n\nimport { getSettings } from '@/shared/settings';\n\nimport type { Wallets } from '@/wallet';\nimport type { PaymentProtocol } from '@/shared/protocols/types';\nimport type { Network } from '@agentcash/networks';\n\n/**\n * Hook called before a payment is executed.\n * Throw to abort. Return to proceed.\n * Matches existing checkBalance/checkTempoBalance throw-to-abort behavior.\n */\nexport type BeforePaymentHook = (ctx: {\n protocol: PaymentProtocol;\n amount: number;\n currency: string;\n network: Network;\n}) => Promise<void>;\n\nexport interface FetchWithPaymentResult {\n response: Response;\n paymentInfo: null | {\n protocol: PaymentProtocol;\n price: string;\n payment: {\n success: boolean;\n transactionHash: string;\n } | null;\n };\n}\n\n/** Default max amount (in USD/USDC) allowed without explicit opt-in. */\nexport const DEFAULT_MAX_AMOUNT = 5;\n\nexport interface FetchWithPaymentOptions {\n surface: string;\n wallets: Wallets;\n flags: GlobalFlags;\n paymentMethod?: PaymentProtocol;\n paymentNetwork?: Network;\n beforePayment?: BeforePaymentHook;\n timeout?: number;\n maxAmount?: number;\n}\n\n/**\n * Create a fetch function with automatic dual-protocol payment handling.\n *\n * 1. Makes initial request\n * 2. If 402 response, detects protocol(s)\n * 3. Calls beforePayment hook (for balance checks)\n * 4. Creates payment credential/payload\n * 5. Retries request with payment headers\n */\nexport function createFetchWithPayment(options: FetchWithPaymentOptions) {\n const { surface, paymentMethod, timeout, maxAmount } = options;\n const effectiveMaxAmount =\n maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;\n\n return async (request: Request) => {\n const clonedRequest = request.clone();\n const fallbackRequest = request.clone();\n\n const probeResult = await safeFetch(surface, request, timeout);\n\n if (probeResult.isErr()) {\n return fetchErr(surface, probeResult.error);\n }\n\n // Not a 402 response — return as-is\n if (probeResult.value.status !== 402) {\n return probeResult.andThen(response =>\n fetchOk<FetchWithPaymentResult>({ response, paymentInfo: null })\n );\n }\n\n const response = probeResult.value;\n\n // User explicitly chose a protocol — use that, no fallback\n if (paymentMethod) {\n const handler = getHandler(paymentMethod);\n return handler({\n response,\n clonedRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n }\n\n // Auto: detect available protocols, pick by higher balance\n const available = detectPaymentProtocols(response);\n\n const preferred =\n available.length === 1\n ? available[0]!\n : await pickByBalance(response, options);\n\n const fallback =\n available.length > 1 ? (preferred === 'mpp' ? 'x402' : 'mpp') : null;\n\n const preferredHandler = getHandler(preferred);\n\n const result = await preferredHandler({\n response,\n clonedRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n\n if (result.isErr() && fallback) {\n const fallbackHandler = getHandler(fallback);\n return fallbackHandler({\n response,\n clonedRequest: fallbackRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n }\n\n return result;\n };\n}\n\nconst getHandler = (protocol: PaymentProtocol) => {\n switch (protocol) {\n case 'mpp':\n return handleMppPayment;\n case 'x402':\n return handleX402Payment;\n default:\n throw new Error(`Unknown protocol: ${protocol as string}`);\n }\n};\n"],"mappings":"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","names":["amount","response"]}
1
+ {"version":3,"sources":["../../src/shared/settings.ts","../../src/shared/protocols/detect.ts","../../src/shared/protocols/mpp/index.ts","../../src/shared/protocols/pick.ts","../../src/shared/protocols/mpp/handle-payment.ts","../../src/shared/protocols/x402/choose-payment-requirement.ts","../../src/shared/protocols/x402/handle-payment.ts","../../src/operations/fetch-with-payment.ts"],"sourcesContent":["import z from 'zod';\nimport fs from 'fs';\n\nimport { configFile } from './fs';\n\nconst SETTINGS_FILE = configFile('settings.json');\n\nconst settingsSchema = z\n .looseObject({\n maxAmount: z.number().positive(),\n })\n .partial();\n\nexport type Settings = z.infer<typeof settingsSchema>;\n\nexport const getSettings = (): Settings => {\n if (!fs.existsSync(SETTINGS_FILE)) {\n return {};\n }\n\n const content = fs.readFileSync(SETTINGS_FILE, 'utf-8');\n const result = settingsSchema.safeParse(JSON.parse(content));\n if (!result.success) {\n return {};\n }\n return result.data;\n};\n\nexport const setSettings = (settings: Settings) => {\n const existing = getSettings();\n const newSettings = settingsSchema.parse({ ...existing, ...settings });\n fs.writeFileSync(SETTINGS_FILE, JSON.stringify(newSettings, null, 2));\n};\n","import { isMppEnabled } from '@/shared/mpp-enabled';\nimport type { PaymentProtocol } from './types';\n\n/**\n * Detects all payment protocols present in a 402 response.\n * MPP responses include a `WWW-Authenticate` header starting with \"Payment\".\n * x402 responses include a `payment-required` header.\n * If neither is explicitly detected, defaults to x402.\n *\n * MPP detection is gated behind {@link isMppEnabled} so it never surfaces\n * in agent context on the `latest` dist-tag.\n */\nexport function detectPaymentProtocols(response: Response): PaymentProtocol[] {\n const protocols: PaymentProtocol[] = [];\n if (isMppEnabled()) {\n const wwwAuth = response.headers.get('WWW-Authenticate');\n if (wwwAuth?.startsWith('Payment')) {\n protocols.push('mpp');\n }\n }\n const paymentRequired = response.headers.get('payment-required');\n if (paymentRequired) {\n protocols.push('x402');\n }\n // If we couldn't detect either explicitly, default to x402\n if (protocols.length === 0) {\n protocols.push('x402');\n }\n return protocols;\n}\n","import { Challenge, Receipt } from 'mppx';\nimport { Methods } from 'mppx/tempo';\nimport {\n err,\n ok,\n resultFromPromise,\n resultFromThrowable,\n} from '@agentcash/neverthrow';\n\nimport { Mppx, tempo as tempoMethod } from 'mppx/client';\n\nimport { createClient, http } from 'viem';\nimport { tempo } from 'viem/chains';\n\nimport { isMppEnabled } from '@/shared/mpp-enabled';\n\nimport type { BaseMppError } from './types';\nimport type { Wallets } from '@/wallet';\n\nconst errorType = 'mpp';\n\nexport const mppOk = <T>(value: T) => ok(value);\nexport const mppErr = (surface: string, error: BaseMppError) =>\n err(errorType, surface, error);\n\nconst mppResultFromPromise = <T>(\n surface: string,\n promise: Promise<T>,\n error: (e: unknown) => BaseMppError\n) => resultFromPromise(errorType, surface, promise, error);\n\nconst mppResultFromThrowable = <T>(\n surface: string,\n fn: () => T,\n error: (e: unknown) => BaseMppError\n) => resultFromThrowable(errorType, surface, fn, error);\n\nexport const safeGetMppChallenge = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () => Challenge.fromResponse(response, { methods: [Methods.charge] }),\n error => ({\n cause: 'parse_mpp_challenge',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP challenge from response',\n })\n );\n};\n\nexport const safeCreateMppCredential = (\n surface: string,\n wallets: Wallets,\n response: Response\n) => {\n if (!isMppEnabled()) {\n return mppErr(surface, {\n cause: 'mpp_disabled',\n message: 'MPP is not enabled',\n });\n }\n\n const TEMPO_RPC_URL =\n 'https://eng:acard-melody-fashion-finish@rpc.mainnet.tempo.xyz';\n\n const client = Mppx.create({\n polyfill: false,\n methods: [\n tempoMethod({\n account: wallets.evmAccount.account,\n getClient: () =>\n createClient({\n chain: tempo,\n transport: http(TEMPO_RPC_URL),\n }),\n }),\n ],\n });\n\n return mppResultFromPromise(\n surface,\n client.createCredential(response),\n error => ({\n cause: 'create_mpp_credential',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to create MPP credential',\n })\n );\n};\n\nexport const safeGetMppReceipt = (surface: string, response: Response) => {\n return mppResultFromThrowable(\n surface,\n () => Receipt.fromResponse(response),\n error => ({\n cause: 'parse_mpp_receipt',\n message:\n error instanceof Error\n ? error.message\n : 'Failed to parse MPP receipt from response',\n })\n );\n};\n","import { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { safeGetMppChallenge } from '@/shared/protocols/mpp';\n\nimport { log } from '@/shared/log';\nimport { getBalance } from '@/shared/balance';\nimport { Network } from '@agentcash/networks';\n\nimport type { FetchWithPaymentOptions } from '@/operations/fetch-with-payment';\n\n/**\n * Pick the preferred protocol by comparing wallet balances.\n * Falls back to 'mpp' if both balances fail to fetch.\n */\nexport async function pickByBalance(\n response: Response,\n options: FetchWithPaymentOptions\n): Promise<'x402' | 'mpp'> {\n const { surface, wallets, flags } = options;\n\n // Get x402 (USDC on Base) balance\n const x402BalanceResult = await resultFromPromise(\n 'balance',\n surface,\n getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: Network.BASE,\n },\n flags\n ).then(r => (r.isOk() ? r.value.balance : 0)),\n () => ({\n cause: 'x402_balance' as const,\n message: 'Failed to get x402 balance',\n })\n );\n\n if (x402BalanceResult.isErr()) {\n log.debug('Balance comparison failed, defaulting to mpp');\n return 'mpp';\n }\n\n const x402Balance = x402BalanceResult.value;\n\n // Get MPP (Tempo) balance — need token address from the challenge\n let mppBalance = 0;\n const challengeResult = safeGetMppChallenge(surface, response);\n if (challengeResult.isOk()) {\n const currency = challengeResult.value.request.currency as\n | string\n | undefined;\n const decimals = 6;\n if (currency) {\n const tempoResult = await getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: Network.TEMPO,\n },\n flags\n );\n if (tempoResult.isOk()) {\n mppBalance = Number(tempoResult.value.balance ?? (0).toFixed(decimals));\n }\n }\n }\n\n log.info(`Protocol selection — x402: $${x402Balance}, mpp: $${mppBalance}`);\n return x402Balance >= mppBalance ? 'x402' : 'mpp';\n}\n","import { formatUnits } from 'viem';\n\nimport { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeGetMppChallenge,\n safeCreateMppCredential,\n safeGetMppReceipt,\n mppErr,\n mppOk,\n} from '@/shared/protocols/mpp';\n\nimport type { FetchWithPaymentResult } from '@/operations/fetch-with-payment';\nimport type { HandlePaymentParams } from '../types';\nimport { Network } from '@agentcash/networks';\n\nexport async function handleMppPayment({\n response,\n clonedRequest,\n options,\n maxAmount,\n}: HandlePaymentParams) {\n const { surface, wallets, beforePayment, timeout } = options;\n\n // Prevent retry loops\n if (clonedRequest.headers.has('Authorization')) {\n return mppErr(surface, {\n cause: 'mpp_payment_already_attempted',\n message: 'MPP payment already attempted',\n });\n }\n\n // Parse the challenge from the WWW-Authenticate header\n const challengeResult = safeGetMppChallenge(surface, response);\n\n if (challengeResult.isErr()) {\n return challengeResult;\n }\n\n const challenge = challengeResult.value;\n\n // Extract payment info from challenge request\n const amount = Number(formatUnits(BigInt(challenge.request.amount), 6));\n const currency = challenge.request.currency;\n\n if (amount > maxAmount) {\n return mppErr(surface, {\n cause: 'mpp_payment_amount_exceeds_max_amount' as const,\n message: `Endpoint requested $${amount} which exceeds the maximum allowed amount of $${maxAmount}. Pass a higher maxAmount on this call, or use update_settings to raise the default permanently.`,\n });\n }\n\n if (beforePayment) {\n const hookResult = await resultFromPromise(\n 'mpp',\n surface,\n beforePayment({\n protocol: 'mpp',\n amount,\n currency,\n network: Network.TEMPO,\n }),\n e => ({\n cause: 'before_payment_hook_failed' as const,\n message: e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return mppErr(surface, hookResult.error);\n }\n }\n\n const credentialResult = await safeCreateMppCredential(\n surface,\n wallets,\n response\n );\n\n if (credentialResult.isErr()) {\n return credentialResult;\n }\n\n const credential = credentialResult.value;\n\n // Set Authorization header on cloned request\n clonedRequest.headers.set('Authorization', credential);\n\n // Retry the fetch with the credential\n return await safeFetch(surface, clonedRequest, timeout).andThen(\n paidResponse => {\n // Parse the receipt for transaction hash\n const receiptResult = safeGetMppReceipt(surface, paidResponse);\n\n return mppOk<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'mpp',\n price: amount.toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n }),\n payment: receiptResult.isOk()\n ? {\n success: true,\n transactionHash: receiptResult.value.reference,\n }\n : null,\n },\n });\n }\n );\n}\n","import { getBalance } from '@/shared/balance';\nimport { Network, networkSchema } from '@agentcash/networks';\n\nimport type { PaymentRequirements } from '@x402/core/types';\nimport type { FetchWithPaymentOptions } from '@/operations/fetch-with-payment';\n\ninterface ChoosePaymentRequirementParams {\n paymentRequirements: PaymentRequirements[];\n options: FetchWithPaymentOptions;\n}\n\nexport const choosePaymentRequirement = async ({\n paymentRequirements,\n options,\n}: ChoosePaymentRequirementParams) => {\n const { surface, paymentNetwork, wallets, flags } = options;\n if (paymentNetwork) {\n return paymentRequirements.find(\n pr => pr.network === (paymentNetwork as string)\n );\n }\n\n const requirementsWithBalance = await Promise.all(\n paymentRequirements.map(async pr => {\n const parsedNetwork = networkSchema.safeParse(pr.network);\n if (!parsedNetwork.success) {\n return {\n balance: 0,\n requirement: pr,\n };\n }\n if (parsedNetwork.data === Network.SOLANA) {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.svmAccount.account.address,\n network: parsedNetwork.data,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n } else {\n const balanceResult = await getBalance(\n surface,\n {\n address: wallets.evmAccount.account.address,\n network: parsedNetwork.data,\n },\n flags\n );\n return {\n requirement: pr,\n balance: balanceResult.isOk() ? balanceResult.value.balance : 0,\n };\n }\n })\n );\n return requirementsWithBalance.sort((a, b) => b.balance - a.balance)[0]!\n .requirement;\n};\n","import { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { choosePaymentRequirement } from './choose-payment-requirement';\n\nimport { safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeCreatePaymentPayload,\n safeGetPaymentRequired,\n safeGetPaymentSettlement,\n x402Err,\n x402Ok,\n x402ProbeClient,\n} from '@/shared/protocols/x402';\nimport { tokenStringToNumber } from '@/shared/utils';\n\nimport type { FetchWithPaymentResult } from '@/operations/fetch-with-payment';\nimport type { HandlePaymentParams } from '../types';\nimport type { Network } from '@agentcash/networks';\n\nexport async function handleX402Payment({\n response,\n clonedRequest,\n options,\n maxAmount,\n}: HandlePaymentParams) {\n const { surface, wallets, beforePayment, timeout } = options;\n\n const paymentRequiredResult = await safeGetPaymentRequired(surface, response);\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const paymentRequired = paymentRequiredResult.value;\n\n if (paymentRequired.x402Version === 1) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint uses the x402 v1 format, which is not supported by agentcash. Only x402 v2 servers (with an `accepts` array in the Payment-Required header) are supported.',\n });\n }\n\n if (!paymentRequired.accepts || !Array.isArray(paymentRequired.accepts)) {\n return x402Err(surface, {\n cause: 'parse_payment_required' as const,\n message:\n 'This endpoint has a missing or malformed accepts array in the Payment-Required header.',\n });\n }\n\n // Check amount against maxAmount before any payment logic\n const accept = await choosePaymentRequirement({\n options,\n paymentRequirements: paymentRequired.accepts,\n });\n\n if (accept) {\n const amount = tokenStringToNumber(accept.amount);\n if (amount > maxAmount) {\n return x402Err(surface, {\n cause: 'payment_amount_exceeds_max_amount' as const,\n message: `Endpoint requested $${amount} which exceeds the maximum allowed amount of $${maxAmount}. Pass a higher maxAmount on this call, or use update_settings to raise the default permanently.`,\n });\n }\n\n if (beforePayment) {\n const amount = tokenStringToNumber(accept.amount);\n const hookResult = await resultFromPromise(\n 'x402',\n surface,\n beforePayment({\n protocol: 'x402',\n amount,\n currency: 'USDC',\n network: accept.network as Network,\n }),\n e => ({\n cause: 'payment_already_attempted' as const,\n message:\n e instanceof Error ? e.message : 'Before-payment hook failed',\n })\n );\n if (hookResult.isErr()) {\n return x402Err(surface, hookResult.error);\n }\n }\n }\n\n const paymentPayloadResult = await safeCreatePaymentPayload(\n surface,\n wallets,\n paymentRequired,\n accept ? () => accept : undefined\n );\n\n if (paymentPayloadResult.isErr()) {\n return paymentPayloadResult;\n }\n\n const paymentPayload = paymentPayloadResult.value;\n\n // Encode payment header\n const paymentHeaders =\n x402ProbeClient.encodePaymentSignatureHeader(paymentPayload);\n\n // Check if this is already a retry to prevent infinite loops\n if (\n clonedRequest.headers.has('PAYMENT-SIGNATURE') ||\n clonedRequest.headers.has('X-PAYMENT')\n ) {\n return x402Err(surface, {\n cause: 'payment_already_attempted',\n message: 'Payment already attempted',\n });\n }\n\n // Add payment headers to cloned request\n for (const [key, value] of Object.entries(paymentHeaders)) {\n clonedRequest.headers.set(key, value);\n }\n clonedRequest.headers.set(\n 'Access-Control-Expose-Headers',\n 'PAYMENT-RESPONSE,X-PAYMENT-RESPONSE'\n );\n\n // Retry the request with payment\n return await safeFetch(surface, clonedRequest, timeout).andThen(\n paidResponse => {\n const settlementResult = safeGetPaymentSettlement(surface, paidResponse);\n\n return x402Ok<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'x402',\n price: tokenStringToNumber(\n paymentPayload.accepted.amount\n ).toLocaleString('en-US', {\n style: 'currency',\n currency: 'USD',\n }),\n payment: settlementResult.isOk()\n ? {\n success: settlementResult.value.success,\n transactionHash: settlementResult.value.transaction,\n }\n : null,\n },\n });\n }\n );\n}\n","import type { GlobalFlags } from '@/types';\n\nimport { fetchErr, fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\n\nimport { detectPaymentProtocols } from '@/shared/protocols/detect';\nimport { pickByBalance } from '@/shared/protocols/pick';\n\nimport { handleMppPayment } from '@/shared/protocols/mpp/handle-payment';\nimport { handleX402Payment } from '@/shared/protocols/x402/handle-payment';\n\nimport { getSettings } from '@/shared/settings';\nimport { BLACKLISTED_ORIGINS } from '@/shared/origins';\n\nimport type { Wallets } from '@/wallet';\nimport type { PaymentProtocol } from '@/shared/protocols/types';\nimport type { Network } from '@agentcash/networks';\n\n/**\n * Hook called before a payment is executed.\n * Throw to abort. Return to proceed.\n * Matches existing checkBalance/checkTempoBalance throw-to-abort behavior.\n */\nexport type BeforePaymentHook = (ctx: {\n protocol: PaymentProtocol;\n amount: number;\n currency: string;\n network: Network;\n}) => Promise<void>;\n\nexport interface FetchWithPaymentResult {\n response: Response;\n paymentInfo: null | {\n protocol: PaymentProtocol;\n price: string;\n payment: {\n success: boolean;\n transactionHash: string;\n } | null;\n };\n}\n\n/** Default max amount (in USD/USDC) allowed without explicit opt-in. */\nexport const DEFAULT_MAX_AMOUNT = 5;\n\nexport interface FetchWithPaymentOptions {\n surface: string;\n wallets: Wallets;\n flags: GlobalFlags;\n paymentMethod?: PaymentProtocol;\n paymentNetwork?: Network;\n beforePayment?: BeforePaymentHook;\n timeout?: number;\n maxAmount?: number;\n}\n\n/**\n * Create a fetch function with automatic dual-protocol payment handling.\n *\n * 1. Makes initial request\n * 2. If 402 response, detects protocol(s)\n * 3. Calls beforePayment hook (for balance checks)\n * 4. Creates payment credential/payload\n * 5. Retries request with payment headers\n */\nexport function createFetchWithPayment(options: FetchWithPaymentOptions) {\n const { surface, paymentMethod, timeout, maxAmount } = options;\n const effectiveMaxAmount =\n maxAmount ?? getSettings().maxAmount ?? DEFAULT_MAX_AMOUNT;\n\n return async (request: Request) => {\n const blocked = BLACKLISTED_ORIGINS.find(origin =>\n request.url.startsWith(origin)\n );\n if (blocked) {\n return fetchErr(surface, {\n cause: 'network',\n message: `${blocked} is no longer available. This origin has been deprecated.`,\n });\n }\n\n const clonedRequest = request.clone();\n const fallbackRequest = request.clone();\n\n const probeResult = await safeFetch(surface, request, timeout);\n\n if (probeResult.isErr()) {\n return fetchErr(surface, probeResult.error);\n }\n\n // Not a 402 response — return as-is\n if (probeResult.value.status !== 402) {\n return probeResult.andThen(response =>\n fetchOk<FetchWithPaymentResult>({ response, paymentInfo: null })\n );\n }\n\n const response = probeResult.value;\n\n // User explicitly chose a protocol — use that, no fallback\n if (paymentMethod) {\n const handler = getHandler(paymentMethod);\n return handler({\n response,\n clonedRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n }\n\n // Auto: detect available protocols, pick by higher balance\n const available = detectPaymentProtocols(response);\n\n const preferred =\n available.length === 1\n ? available[0]!\n : await pickByBalance(response, options);\n\n const fallback =\n available.length > 1 ? (preferred === 'mpp' ? 'x402' : 'mpp') : null;\n\n const preferredHandler = getHandler(preferred);\n\n const result = await preferredHandler({\n response,\n clonedRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n\n if (result.isErr() && fallback) {\n const fallbackHandler = getHandler(fallback);\n return fallbackHandler({\n response,\n clonedRequest: fallbackRequest,\n options,\n maxAmount: effectiveMaxAmount,\n });\n }\n\n return result;\n };\n}\n\nconst getHandler = (protocol: PaymentProtocol) => {\n switch (protocol) {\n case 'mpp':\n return handleMppPayment;\n case 'x402':\n return handleX402Payment;\n default:\n throw new Error(`Unknown protocol: ${protocol as string}`);\n }\n};\n"],"mappings":"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","names":["amount","response"]}
@@ -0,0 +1,10 @@
1
+ // src/shared/origins.ts
2
+ var BLACKLISTED_ORIGINS = [
3
+ "https://twit.sh",
4
+ "https://x402.twit.sh"
5
+ ];
6
+
7
+ export {
8
+ BLACKLISTED_ORIGINS
9
+ };
10
+ //# sourceMappingURL=chunk-TTAO2EJK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/shared/origins.ts"],"sourcesContent":["/**\n * Known x402-protected API origins.\n * Using const enum so values are inlined at build time.\n */\nexport const enum Origin {\n StableEnrich = 'https://stableenrich.dev',\n StableSocial = 'https://stablesocial.dev',\n StableStudio = 'https://stablestudio.dev',\n StableUpload = 'https://stableupload.dev',\n StableEmail = 'https://stableemail.dev',\n X402Scan = 'https://x402scan.com',\n Shirt = 'https://shirt.sh',\n X402Puppet = 'https://x402puppet.com',\n X402Facilitator = 'https://x402facilitator.com',\n StableMerch = 'https://stablemerch.dev',\n}\n\n/**\n * Origins that are no longer available and should be rejected.\n */\nexport const BLACKLISTED_ORIGINS = [\n 'https://twit.sh',\n 'https://x402.twit.sh',\n] as const;\n"],"mappings":";AAoBO,IAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AACF;","names":[]}
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-OKHBFFZP.js";
11
11
  import {
12
12
  isMppEnabled
13
- } from "./chunk-SF3JWCTJ.js";
13
+ } from "./chunk-GQTOWVH6.js";
14
14
  import {
15
15
  EVM_CONFIGS,
16
16
  SOLANA_CONFIG,
@@ -109,4 +109,4 @@ export {
109
109
  getOnboardingCta,
110
110
  getWalletInfo
111
111
  };
112
- //# sourceMappingURL=chunk-P7WFI336.js.map
112
+ //# sourceMappingURL=chunk-UJO2BWV6.js.map