agentcash 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/run-server.cjs +118 -73
- package/dist/esm/{check-endpoint-BGFpMl2m.d.ts → check-endpoint-Df0YnKdr.d.ts} +8 -3
- package/dist/esm/{chunk-BAQ3QDQY.js → chunk-3STID4ZW.js} +4 -4
- package/dist/esm/chunk-3STID4ZW.js.map +1 -0
- package/dist/esm/chunk-L3LTEB5B.js +7 -0
- package/dist/esm/{chunk-CPB4JGR7.js → chunk-NFGTXPUD.js} +54 -40
- package/dist/esm/chunk-NFGTXPUD.js.map +1 -0
- package/dist/esm/{chunk-KZOOVRXW.js → chunk-RN73GKUU.js} +3 -3
- package/dist/esm/{chunk-UC3J43CE.js → chunk-YXENPVZ4.js} +2 -2
- package/dist/esm/{commands-CJHVEMHK.js → commands-D3PD4CNW.js} +15 -10
- package/dist/esm/{commands-CJHVEMHK.js.map → commands-D3PD4CNW.js.map} +1 -1
- package/dist/esm/index.js +20 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{install-7FG62LQT.js → install-KD7XNKVI.js} +2 -2
- package/dist/esm/lib.d.ts +1 -1
- package/dist/esm/lib.js +2 -2
- package/dist/esm/lib.js.map +1 -1
- package/dist/esm/{server-AO2FSPPT.js → server-NX7XT2F6.js} +70 -38
- package/dist/esm/server-NX7XT2F6.js.map +1 -0
- package/dist/esm/shared/operations/index.d.ts +1 -1
- package/dist/esm/shared/operations/index.js +4 -4
- package/dist/esm/shared/operations/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/esm/chunk-BAQ3QDQY.js.map +0 -1
- package/dist/esm/chunk-CPB4JGR7.js.map +0 -1
- package/dist/esm/chunk-EGM7SQKO.js +0 -7
- package/dist/esm/server-AO2FSPPT.js.map +0 -1
- /package/dist/esm/{chunk-EGM7SQKO.js.map → chunk-L3LTEB5B.js.map} +0 -0
- /package/dist/esm/{chunk-KZOOVRXW.js.map → chunk-RN73GKUU.js.map} +0 -0
- /package/dist/esm/{chunk-UC3J43CE.js.map → chunk-YXENPVZ4.js.map} +0 -0
- /package/dist/esm/{install-7FG62LQT.js.map → install-KD7XNKVI.js.map} +0 -0
package/dist/cjs/run-server.cjs
CHANGED
|
@@ -104303,7 +104303,7 @@ var import_path2 = require("path");
|
|
|
104303
104303
|
var import_url = require("url");
|
|
104304
104304
|
function getVersion2() {
|
|
104305
104305
|
if (true) {
|
|
104306
|
-
return "0.6.
|
|
104306
|
+
return "0.6.4";
|
|
104307
104307
|
}
|
|
104308
104308
|
const __dirname3 = (0, import_path2.dirname)((0, import_url.fileURLToPath)(importMetaUrl));
|
|
104309
104309
|
const pkg = JSON.parse(
|
|
@@ -104466,7 +104466,7 @@ var TEMPO_TOKEN_ADDRESS = "0x20c0000000000000000000000000000000000000";
|
|
|
104466
104466
|
|
|
104467
104467
|
// src/shared/mpp-enabled.ts
|
|
104468
104468
|
init_cjs_shims();
|
|
104469
|
-
var isMppEnabled = () => "0.6.
|
|
104469
|
+
var isMppEnabled = () => "0.6.4".includes("-mpp");
|
|
104470
104470
|
|
|
104471
104471
|
// src/shared/operations/fetch-with-payment.ts
|
|
104472
104472
|
init_cjs_shims();
|
|
@@ -109252,27 +109252,31 @@ var parsedResponseToToolContentPart = (data) => {
|
|
|
109252
109252
|
};
|
|
109253
109253
|
|
|
109254
109254
|
// src/server/tools/response/error.ts
|
|
109255
|
-
var buildMcpError = (content) => {
|
|
109255
|
+
var buildMcpError = (content, options) => {
|
|
109256
109256
|
return {
|
|
109257
109257
|
content,
|
|
109258
|
-
|
|
109258
|
+
// Default: omit isError so siblings survive parallel calls.
|
|
109259
|
+
// Tools with outputSchema MUST pass isError: true so the SDK
|
|
109260
|
+
// skips output validation on error paths.
|
|
109261
|
+
...options?.isError ? { isError: true } : {}
|
|
109259
109262
|
};
|
|
109260
109263
|
};
|
|
109261
|
-
var mcpErrorJson = (error48) => {
|
|
109264
|
+
var mcpErrorJson = (error48, options) => {
|
|
109262
109265
|
return safeStringifyJson("mcp-error-json", error48).match(
|
|
109263
|
-
(success3) => buildMcpError([{ type: "text", text: success3 }]),
|
|
109264
|
-
(error49) => buildMcpError(
|
|
109265
|
-
{ type: "text", text: JSON.stringify(error49, null, 2) }
|
|
109266
|
-
|
|
109266
|
+
(success3) => buildMcpError([{ type: "text", text: success3 }], options),
|
|
109267
|
+
(error49) => buildMcpError(
|
|
109268
|
+
[{ type: "text", text: JSON.stringify(error49, null, 2) }],
|
|
109269
|
+
options
|
|
109270
|
+
)
|
|
109267
109271
|
);
|
|
109268
109272
|
};
|
|
109269
|
-
var mcpError = async (err3) => {
|
|
109273
|
+
var mcpError = async (err3, options) => {
|
|
109270
109274
|
const { error: error48 } = err3;
|
|
109271
109275
|
if (isFetchError(error48)) {
|
|
109272
109276
|
switch (error48.cause) {
|
|
109273
109277
|
case "network":
|
|
109274
109278
|
case "parse":
|
|
109275
|
-
return mcpErrorJson({ ...error48 });
|
|
109279
|
+
return mcpErrorJson({ ...error48 }, options);
|
|
109276
109280
|
case "http":
|
|
109277
109281
|
const { response, ...rest } = error48;
|
|
109278
109282
|
const parseResponseResult = await safeParseResponse(
|
|
@@ -109286,10 +109290,10 @@ var mcpError = async (err3) => {
|
|
|
109286
109290
|
() => []
|
|
109287
109291
|
)
|
|
109288
109292
|
];
|
|
109289
|
-
return buildMcpError(httpContent);
|
|
109293
|
+
return buildMcpError(httpContent, options);
|
|
109290
109294
|
}
|
|
109291
109295
|
}
|
|
109292
|
-
return mcpErrorJson({ ...error48 });
|
|
109296
|
+
return mcpErrorJson({ ...error48 }, options);
|
|
109293
109297
|
};
|
|
109294
109298
|
var mcpErrorFetch = async (surface2, response) => {
|
|
109295
109299
|
return mcpError(fetchHttpErr(surface2, response));
|
|
@@ -109327,10 +109331,26 @@ var mcpSuccessResponse = (data, extra) => {
|
|
|
109327
109331
|
]);
|
|
109328
109332
|
};
|
|
109329
109333
|
|
|
109334
|
+
// src/server/tools/response/safe-handler.ts
|
|
109335
|
+
init_cjs_shims();
|
|
109336
|
+
function safeHandler(handler) {
|
|
109337
|
+
return async (input) => {
|
|
109338
|
+
try {
|
|
109339
|
+
return await handler(input);
|
|
109340
|
+
} catch (e) {
|
|
109341
|
+
log.error("Unhandled tool error", e);
|
|
109342
|
+
return mcpErrorJson({
|
|
109343
|
+
error: e instanceof Error ? e.message : String(e),
|
|
109344
|
+
cause: "unhandled_exception"
|
|
109345
|
+
});
|
|
109346
|
+
}
|
|
109347
|
+
};
|
|
109348
|
+
}
|
|
109349
|
+
|
|
109330
109350
|
// src/server/tools/lib/request.ts
|
|
109331
109351
|
init_cjs_shims();
|
|
109332
109352
|
var requestSchema = zod_default.object({
|
|
109333
|
-
url: zod_default.
|
|
109353
|
+
url: zod_default.string().describe("The endpoint URL"),
|
|
109334
109354
|
method: zod_default.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).optional().describe("HTTP method. Defaults to GET for fetch operations."),
|
|
109335
109355
|
body: zod_default.unknown().optional().describe("Request body for POST/PUT/PATCH methods"),
|
|
109336
109356
|
headers: zod_default.record(zod_default.string(), zod_default.string()).optional().describe("Additional headers to include").default({}),
|
|
@@ -110108,7 +110128,7 @@ var registerFetchTool = ({
|
|
|
110108
110128
|
openWorldHint: true
|
|
110109
110129
|
}
|
|
110110
110130
|
},
|
|
110111
|
-
async (input) => {
|
|
110131
|
+
safeHandler(async (input) => {
|
|
110112
110132
|
const paymentMethod = input.paymentMethod ?? "auto";
|
|
110113
110133
|
const coreClient = x402Client.fromConfig({
|
|
110114
110134
|
schemes: [
|
|
@@ -110183,7 +110203,7 @@ var registerFetchTool = ({
|
|
|
110183
110203
|
parseResponseResult.value,
|
|
110184
110204
|
paymentInfo
|
|
110185
110205
|
);
|
|
110186
|
-
}
|
|
110206
|
+
})
|
|
110187
110207
|
);
|
|
110188
110208
|
};
|
|
110189
110209
|
|
|
@@ -110287,7 +110307,7 @@ var registerAuthTools = ({
|
|
|
110287
110307
|
openWorldHint: true
|
|
110288
110308
|
}
|
|
110289
110309
|
},
|
|
110290
|
-
async (input) => {
|
|
110310
|
+
safeHandler(async (input) => {
|
|
110291
110311
|
const result = await createFetchWithAuth({
|
|
110292
110312
|
surface: toolName2,
|
|
110293
110313
|
account,
|
|
@@ -110314,7 +110334,7 @@ var registerAuthTools = ({
|
|
|
110314
110334
|
return mcpError(parseResponseResult);
|
|
110315
110335
|
}
|
|
110316
110336
|
return mcpSuccessResponse(parseResponseResult.value);
|
|
110317
|
-
}
|
|
110337
|
+
})
|
|
110318
110338
|
);
|
|
110319
110339
|
};
|
|
110320
110340
|
|
|
@@ -110385,7 +110405,7 @@ var registerWalletTools = ({
|
|
|
110385
110405
|
async () => {
|
|
110386
110406
|
const result = await getWalletInfo("get_wallet_info", address, flags);
|
|
110387
110407
|
if (result.isErr()) {
|
|
110388
|
-
return mcpError(result);
|
|
110408
|
+
return mcpError(result, { isError: true });
|
|
110389
110409
|
}
|
|
110390
110410
|
return mcpSuccessStructuredJson({
|
|
110391
110411
|
address: result.value.address,
|
|
@@ -110407,14 +110427,16 @@ init_cjs_shims();
|
|
|
110407
110427
|
|
|
110408
110428
|
// src/shared/openapi-cache.ts
|
|
110409
110429
|
init_cjs_shims();
|
|
110410
|
-
var
|
|
110430
|
+
var OPENAPI_SPEC_PATHS = [
|
|
110431
|
+
"/openapi.json",
|
|
110432
|
+
"/.well-known/openapi.json"
|
|
110433
|
+
];
|
|
110411
110434
|
async function fetchOpenApiSpec(origin) {
|
|
110412
|
-
const
|
|
110413
|
-
|
|
110414
|
-
|
|
110415
|
-
|
|
110416
|
-
|
|
110417
|
-
];
|
|
110435
|
+
const uniqueUrls = OPENAPI_SPEC_PATHS.map((p) => `${origin}${p}`);
|
|
110436
|
+
let failure = {
|
|
110437
|
+
ok: false,
|
|
110438
|
+
cause: "not_found"
|
|
110439
|
+
};
|
|
110418
110440
|
for (const url3 of uniqueUrls) {
|
|
110419
110441
|
log.debug(`Fetching OpenAPI spec from: ${url3}`);
|
|
110420
110442
|
const fetchResult = await safeFetch(
|
|
@@ -110423,6 +110445,10 @@ async function fetchOpenApiSpec(origin) {
|
|
|
110423
110445
|
DEFAULT_FETCH_TIMEOUT
|
|
110424
110446
|
);
|
|
110425
110447
|
if (fetchResult.isErr()) {
|
|
110448
|
+
const { cause, message } = fetchResult.error;
|
|
110449
|
+
if (cause === "network" || cause === "timeout") {
|
|
110450
|
+
failure = { ok: false, cause, message };
|
|
110451
|
+
}
|
|
110426
110452
|
log.debug(`Failed to fetch OpenAPI spec from: ${url3}`);
|
|
110427
110453
|
continue;
|
|
110428
110454
|
}
|
|
@@ -110438,18 +110464,24 @@ async function fetchOpenApiSpec(origin) {
|
|
|
110438
110464
|
})
|
|
110439
110465
|
);
|
|
110440
110466
|
if (jsonResult.isErr()) {
|
|
110441
|
-
|
|
110467
|
+
if (failure.cause === "not_found") {
|
|
110468
|
+
failure = {
|
|
110469
|
+
ok: false,
|
|
110470
|
+
cause: "parse",
|
|
110471
|
+
message: `Failed to parse JSON from: ${url3}`
|
|
110472
|
+
};
|
|
110473
|
+
}
|
|
110474
|
+
log.debug(`Failed to parse OpenAPI spec from: ${url3}`);
|
|
110442
110475
|
continue;
|
|
110443
110476
|
}
|
|
110444
110477
|
const spec = jsonResult.value;
|
|
110445
110478
|
if (spec && typeof spec === "object" && spec.paths) {
|
|
110446
|
-
|
|
110447
|
-
|
|
110448
|
-
return spec;
|
|
110479
|
+
log.info(`Fetched OpenAPI spec for origin: ${origin}`);
|
|
110480
|
+
return { ok: true, spec };
|
|
110449
110481
|
}
|
|
110450
110482
|
}
|
|
110451
110483
|
log.debug(`No OpenAPI spec found for origin: ${origin}`);
|
|
110452
|
-
return
|
|
110484
|
+
return failure;
|
|
110453
110485
|
}
|
|
110454
110486
|
function resolveRef2(spec, ref, seen) {
|
|
110455
110487
|
if (!ref.startsWith("#/")) return void 0;
|
|
@@ -110504,8 +110536,9 @@ function extractPath(url3, origin) {
|
|
|
110504
110536
|
async function getEndpointSchema(endpointUrl, method) {
|
|
110505
110537
|
if (!URL.canParse(endpointUrl)) return null;
|
|
110506
110538
|
const origin = new URL(endpointUrl).origin;
|
|
110507
|
-
const
|
|
110508
|
-
if (!
|
|
110539
|
+
const result = await fetchOpenApiSpec(origin);
|
|
110540
|
+
if (!result.ok) return null;
|
|
110541
|
+
const spec = result.spec;
|
|
110509
110542
|
const paths = spec.paths;
|
|
110510
110543
|
if (!paths) return null;
|
|
110511
110544
|
const path2 = extractPath(endpointUrl, origin);
|
|
@@ -110536,12 +110569,10 @@ async function getEndpointSchema(endpointUrl, method) {
|
|
|
110536
110569
|
const resolved = resolveRefs(spec, operation, /* @__PURE__ */ new Set());
|
|
110537
110570
|
return { path: path2, method: httpMethod, ...resolved };
|
|
110538
110571
|
}
|
|
110539
|
-
var indexCache = /* @__PURE__ */ new Map();
|
|
110540
110572
|
async function getOriginIndex(origin) {
|
|
110541
|
-
const
|
|
110542
|
-
if (
|
|
110543
|
-
const spec =
|
|
110544
|
-
if (!spec?.paths) return null;
|
|
110573
|
+
const result = await fetchOpenApiSpec(origin);
|
|
110574
|
+
if (!result.ok) return null;
|
|
110575
|
+
const spec = result.spec;
|
|
110545
110576
|
const endpoints = [];
|
|
110546
110577
|
for (const [path2, methods] of Object.entries(
|
|
110547
110578
|
spec.paths
|
|
@@ -110565,7 +110596,6 @@ async function getOriginIndex(origin) {
|
|
|
110565
110596
|
}
|
|
110566
110597
|
}
|
|
110567
110598
|
}
|
|
110568
|
-
indexCache.set(origin, endpoints);
|
|
110569
110599
|
return endpoints;
|
|
110570
110600
|
}
|
|
110571
110601
|
var OPENAPI_HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -110581,9 +110611,9 @@ var OPENAPI_HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
110581
110611
|
async function getSpecMethods(endpointUrl) {
|
|
110582
110612
|
if (!URL.canParse(endpointUrl)) return null;
|
|
110583
110613
|
const origin = new URL(endpointUrl).origin;
|
|
110584
|
-
const
|
|
110585
|
-
if (!
|
|
110586
|
-
const paths = spec.paths;
|
|
110614
|
+
const result = await fetchOpenApiSpec(origin);
|
|
110615
|
+
if (!result.ok) return null;
|
|
110616
|
+
const paths = result.spec.paths;
|
|
110587
110617
|
const path2 = extractPath(endpointUrl, origin);
|
|
110588
110618
|
let pathEntry = paths[path2];
|
|
110589
110619
|
if (!pathEntry) {
|
|
@@ -110600,8 +110630,8 @@ async function getSpecMethods(endpointUrl) {
|
|
|
110600
110630
|
if (!pathEntry) return null;
|
|
110601
110631
|
return Object.keys(pathEntry).filter((k) => OPENAPI_HTTP_METHODS.has(k)).map((k) => k.toUpperCase());
|
|
110602
110632
|
}
|
|
110603
|
-
function getIndexEntry(origin, path2, method) {
|
|
110604
|
-
const entries =
|
|
110633
|
+
async function getIndexEntry(origin, path2, method) {
|
|
110634
|
+
const entries = await getOriginIndex(origin);
|
|
110605
110635
|
if (!entries) return void 0;
|
|
110606
110636
|
const m = method.toUpperCase();
|
|
110607
110637
|
return entries.find((e) => e.path === path2 && e.method === m);
|
|
@@ -110680,14 +110710,14 @@ async function probeMethod({
|
|
|
110680
110710
|
if (!schema2) return null;
|
|
110681
110711
|
let estimatedPrice2;
|
|
110682
110712
|
let summary2;
|
|
110683
|
-
const indexResult2 =
|
|
110713
|
+
const indexResult2 = await resultFromPromise(
|
|
110684
110714
|
"openapi",
|
|
110685
110715
|
surface2,
|
|
110686
|
-
() => {
|
|
110716
|
+
(async () => {
|
|
110687
110717
|
const origin = new URL(url3).origin;
|
|
110688
110718
|
const path2 = new URL(url3).pathname || "/";
|
|
110689
110719
|
return getIndexEntry(origin, path2, method);
|
|
110690
|
-
},
|
|
110720
|
+
})(),
|
|
110691
110721
|
(e) => ({
|
|
110692
110722
|
cause: "index_lookup",
|
|
110693
110723
|
message: e instanceof Error ? e.message : String(e)
|
|
@@ -110798,14 +110828,14 @@ async function probeMethod({
|
|
|
110798
110828
|
}
|
|
110799
110829
|
let estimatedPrice;
|
|
110800
110830
|
let summary;
|
|
110801
|
-
const indexResult =
|
|
110831
|
+
const indexResult = await resultFromPromise(
|
|
110802
110832
|
"openapi",
|
|
110803
110833
|
surface2,
|
|
110804
|
-
() => {
|
|
110834
|
+
(async () => {
|
|
110805
110835
|
const origin = new URL(url3).origin;
|
|
110806
110836
|
const path2 = new URL(url3).pathname || "/";
|
|
110807
110837
|
return getIndexEntry(origin, path2, method);
|
|
110808
|
-
},
|
|
110838
|
+
})(),
|
|
110809
110839
|
(e) => ({
|
|
110810
110840
|
cause: "index_lookup",
|
|
110811
110841
|
message: e instanceof Error ? e.message : String(e)
|
|
@@ -110864,7 +110894,7 @@ function buildProbeRequest(url3, method, body, headers) {
|
|
|
110864
110894
|
// src/server/tools/check-endpoint.ts
|
|
110865
110895
|
var toolName3 = "check_endpoint_schema";
|
|
110866
110896
|
var checkEndpointInputSchema = zod_default.object({
|
|
110867
|
-
url: zod_default.
|
|
110897
|
+
url: zod_default.string().describe("The endpoint URL"),
|
|
110868
110898
|
method: zod_default.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).optional().describe(
|
|
110869
110899
|
"HTTP method to check. If omitted, all methods are probed in parallel."
|
|
110870
110900
|
),
|
|
@@ -110889,7 +110919,7 @@ var registerCheckEndpointTool = ({
|
|
|
110889
110919
|
openWorldHint: true
|
|
110890
110920
|
}
|
|
110891
110921
|
},
|
|
110892
|
-
async (input) => {
|
|
110922
|
+
safeHandler(async (input) => {
|
|
110893
110923
|
log.info("Querying endpoint", input);
|
|
110894
110924
|
const { url: url3, results } = await checkEndpoint({
|
|
110895
110925
|
surface: toolName3,
|
|
@@ -110910,7 +110940,7 @@ var registerCheckEndpointTool = ({
|
|
|
110910
110940
|
});
|
|
110911
110941
|
}
|
|
110912
110942
|
return mcpSuccessJson(toJsonObject({ url: url3, results }));
|
|
110913
|
-
}
|
|
110943
|
+
})
|
|
110914
110944
|
);
|
|
110915
110945
|
};
|
|
110916
110946
|
|
|
@@ -111023,7 +111053,7 @@ var registerRedeemInviteTool = ({
|
|
|
111023
111053
|
surface: "redeem_invite"
|
|
111024
111054
|
});
|
|
111025
111055
|
if (result.isErr()) {
|
|
111026
|
-
return mcpError(result);
|
|
111056
|
+
return mcpError(result, { isError: true });
|
|
111027
111057
|
}
|
|
111028
111058
|
const { amount: amount2, txHash } = result.value;
|
|
111029
111059
|
return mcpSuccessStructuredJson({
|
|
@@ -111128,7 +111158,7 @@ var registerTelemetryTools = ({
|
|
|
111128
111158
|
);
|
|
111129
111159
|
if (result.isErr()) {
|
|
111130
111160
|
log.error("Failed to submit error report", result.error);
|
|
111131
|
-
return mcpError(result);
|
|
111161
|
+
return mcpError(result, { isError: true });
|
|
111132
111162
|
}
|
|
111133
111163
|
log.info("Error report submitted successfully", {
|
|
111134
111164
|
reportId: result.value.reportId
|
|
@@ -111153,7 +111183,6 @@ var ORIGINS = [
|
|
|
111153
111183
|
"https://stablestudio.dev" /* StableStudio */,
|
|
111154
111184
|
"https://stableupload.dev" /* StableUpload */,
|
|
111155
111185
|
"https://stableemail.dev" /* StableEmail */,
|
|
111156
|
-
"https://stablejobs.dev" /* StableJobs */,
|
|
111157
111186
|
"https://x402scan.com" /* X402Scan */,
|
|
111158
111187
|
"https://shirt.sh" /* Shirt */,
|
|
111159
111188
|
"https://x402puppet.com" /* X402Puppet */
|
|
@@ -111178,20 +111207,23 @@ async function fetchLlmsTxt(surface2, origin) {
|
|
|
111178
111207
|
async function discoverResources(surface2, url3) {
|
|
111179
111208
|
const origin = URL.canParse(url3) ? new URL(url3).origin : url3;
|
|
111180
111209
|
log.info(`Discovering resources for origin: ${origin}`);
|
|
111181
|
-
const [
|
|
111210
|
+
const [specResult, instructions] = await Promise.all([
|
|
111182
111211
|
fetchOpenApiSpec(origin),
|
|
111183
111212
|
fetchLlmsTxt(surface2, origin)
|
|
111184
111213
|
]);
|
|
111185
|
-
if (!
|
|
111186
|
-
log.debug(
|
|
111187
|
-
|
|
111188
|
-
|
|
111189
|
-
|
|
111214
|
+
if (!specResult.ok) {
|
|
111215
|
+
log.debug(`No OpenAPI spec found for ${origin}: ${specResult.cause}`);
|
|
111216
|
+
return {
|
|
111217
|
+
found: false,
|
|
111218
|
+
cause: specResult.cause,
|
|
111219
|
+
..."message" in specResult ? { message: specResult.message } : {}
|
|
111220
|
+
};
|
|
111190
111221
|
}
|
|
111222
|
+
const spec = specResult.spec;
|
|
111191
111223
|
const endpoints = await getOriginIndex(origin);
|
|
111192
111224
|
if (!endpoints || endpoints.length === 0) {
|
|
111193
111225
|
log.debug(`OpenAPI spec found for ${origin} but no endpoints extracted`);
|
|
111194
|
-
return
|
|
111226
|
+
return { found: false, cause: "not_found" };
|
|
111195
111227
|
}
|
|
111196
111228
|
log.info(`Found ${endpoints.length} endpoints for: ${origin}`);
|
|
111197
111229
|
const rawInfo = spec.info;
|
|
@@ -111242,7 +111274,7 @@ function registerDiscoveryTools(server) {
|
|
|
111242
111274
|
- ${"https://stableemail.dev" /* StableEmail */} -> send emails.
|
|
111243
111275
|
`,
|
|
111244
111276
|
inputSchema: external_exports3.object({
|
|
111245
|
-
url: external_exports3.
|
|
111277
|
+
url: external_exports3.string().describe(
|
|
111246
111278
|
"The origin URL or any URL on the origin to discover resources from"
|
|
111247
111279
|
)
|
|
111248
111280
|
}),
|
|
@@ -111253,7 +111285,14 @@ function registerDiscoveryTools(server) {
|
|
|
111253
111285
|
openWorldHint: true
|
|
111254
111286
|
}
|
|
111255
111287
|
},
|
|
111256
|
-
async ({ url: url3 }) => {
|
|
111288
|
+
safeHandler(async ({ url: url3 }) => {
|
|
111289
|
+
if (!URL.canParse(url3)) {
|
|
111290
|
+
return mcpErrorJson({
|
|
111291
|
+
error: "Invalid URL",
|
|
111292
|
+
url: url3,
|
|
111293
|
+
hint: "Provide a fully-formed URL like https://example.com"
|
|
111294
|
+
});
|
|
111295
|
+
}
|
|
111257
111296
|
log.info(`Discovering resources for: ${url3}`);
|
|
111258
111297
|
const discoverResult = await resultFromPromise(
|
|
111259
111298
|
"discover",
|
|
@@ -111268,7 +111307,7 @@ function registerDiscoveryTools(server) {
|
|
|
111268
111307
|
return mcpError(discoverResult);
|
|
111269
111308
|
}
|
|
111270
111309
|
const result = discoverResult.value;
|
|
111271
|
-
if (result) {
|
|
111310
|
+
if ("endpoints" in result) {
|
|
111272
111311
|
return mcpSuccessJson({
|
|
111273
111312
|
found: true,
|
|
111274
111313
|
origin: result.origin,
|
|
@@ -111280,12 +111319,22 @@ function registerDiscoveryTools(server) {
|
|
|
111280
111319
|
});
|
|
111281
111320
|
}
|
|
111282
111321
|
const origin = URL.canParse(url3) ? new URL(url3).origin : url3;
|
|
111322
|
+
const tried = OPENAPI_SPEC_PATHS.join(", ");
|
|
111323
|
+
if (result.cause === "not_found") {
|
|
111324
|
+
return mcpSuccessJson({
|
|
111325
|
+
found: false,
|
|
111326
|
+
origin,
|
|
111327
|
+
error: `No OpenAPI spec found. Tried: ${tried}`
|
|
111328
|
+
});
|
|
111329
|
+
}
|
|
111283
111330
|
return mcpSuccessJson({
|
|
111284
111331
|
found: false,
|
|
111285
111332
|
origin,
|
|
111286
|
-
|
|
111333
|
+
cause: result.cause,
|
|
111334
|
+
error: result.message ?? `Failed to fetch OpenAPI spec (${result.cause})`,
|
|
111335
|
+
hint: result.cause === "timeout" ? "The server may be slow or unreachable. Try again later." : result.cause === "network" ? "Could not reach the server. Check the network connection and try again." : `The server returned an unparseable response. Tried: ${tried}`
|
|
111287
111336
|
});
|
|
111288
|
-
}
|
|
111337
|
+
})
|
|
111289
111338
|
);
|
|
111290
111339
|
}
|
|
111291
111340
|
|
|
@@ -111312,10 +111361,6 @@ var ORIGIN_METADATA = {
|
|
|
111312
111361
|
title: "StableEmail",
|
|
111313
111362
|
description: "Send emails"
|
|
111314
111363
|
},
|
|
111315
|
-
["https://stablejobs.dev" /* StableJobs */]: {
|
|
111316
|
-
title: "StableJobs",
|
|
111317
|
-
description: "Search job postings"
|
|
111318
|
-
},
|
|
111319
111364
|
["https://x402scan.com" /* X402Scan */]: {
|
|
111320
111365
|
title: "X402 Scan",
|
|
111321
111366
|
description: "x402 protocol explorer"
|
|
@@ -111775,7 +111820,7 @@ var import_path3 = require("path");
|
|
|
111775
111820
|
var import_url2 = require("url");
|
|
111776
111821
|
function getVersion3() {
|
|
111777
111822
|
if (true) {
|
|
111778
|
-
return "0.6.
|
|
111823
|
+
return "0.6.4";
|
|
111779
111824
|
}
|
|
111780
111825
|
const __dirname3 = (0, import_path3.dirname)((0, import_url2.fileURLToPath)(importMetaUrl));
|
|
111781
111826
|
const pkg = JSON.parse(
|
|
@@ -24,13 +24,18 @@ interface DiscoveryResult {
|
|
|
24
24
|
endpoints: EndpointSummary[];
|
|
25
25
|
instructions?: string;
|
|
26
26
|
}
|
|
27
|
+
interface DiscoverFailure {
|
|
28
|
+
found: false;
|
|
29
|
+
cause: 'not_found' | 'network' | 'timeout' | 'parse';
|
|
30
|
+
message?: string;
|
|
31
|
+
}
|
|
27
32
|
/**
|
|
28
33
|
* Discover payment-protected resources on an origin.
|
|
29
34
|
* Fetches OpenAPI spec, builds endpoint index, and fetches llms.txt instructions.
|
|
30
35
|
*
|
|
31
|
-
* Returns DiscoveryResult on success,
|
|
36
|
+
* Returns DiscoveryResult on success, DiscoverFailure with cause on failure.
|
|
32
37
|
*/
|
|
33
|
-
declare function discoverResources(surface: string, url: string): Promise<DiscoveryResult |
|
|
38
|
+
declare function discoverResources(surface: string, url: string): Promise<DiscoveryResult | DiscoverFailure>;
|
|
34
39
|
|
|
35
40
|
type PaymentProtocol = 'x402' | 'mpp';
|
|
36
41
|
|
|
@@ -106,4 +111,4 @@ interface CheckEndpointOptions {
|
|
|
106
111
|
*/
|
|
107
112
|
declare function checkEndpoint({ surface, url, methods, body, headers, includeMethodErrors, probeAllMethods, }: CheckEndpointOptions): Promise<CheckEndpointResult>;
|
|
108
113
|
|
|
109
|
-
export { type CheckEndpointOptions as C, type
|
|
114
|
+
export { type CheckEndpointOptions as C, type DiscoverFailure as D, type MppPaymentOption as M, type OpenApiInfo as O, type PaymentOption as P, SUPPORTED_METHODS as S, type X402PaymentOption as X, type CheckEndpointResult as a, type DiscoveryResult as b, type ProbeMethodResult as c, type SupportedMethod as d, checkEndpoint as e, discoverResources as f };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getTempoBalance
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RN73GKUU.js";
|
|
4
4
|
import {
|
|
5
5
|
detectPaymentProtocols,
|
|
6
6
|
getSiwxExtension,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
tokenStringToNumber,
|
|
12
12
|
x402Err,
|
|
13
13
|
x402Ok
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NFGTXPUD.js";
|
|
15
15
|
import {
|
|
16
16
|
getBalance
|
|
17
17
|
} from "./chunk-UFSCGP67.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
// src/server/tools/lib/request.ts
|
|
31
31
|
import z from "zod";
|
|
32
32
|
var requestSchema = z.object({
|
|
33
|
-
url: z.
|
|
33
|
+
url: z.string().describe("The endpoint URL"),
|
|
34
34
|
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).optional().describe("HTTP method. Defaults to GET for fetch operations."),
|
|
35
35
|
body: z.unknown().optional().describe("Request body for POST/PUT/PATCH methods"),
|
|
36
36
|
headers: z.record(z.string(), z.string()).optional().describe("Additional headers to include").default({}),
|
|
@@ -411,4 +411,4 @@ export {
|
|
|
411
411
|
createFetchWithPayment,
|
|
412
412
|
createFetchWithAuth
|
|
413
413
|
};
|
|
414
|
-
//# sourceMappingURL=chunk-
|
|
414
|
+
//# sourceMappingURL=chunk-3STID4ZW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/tools/lib/request.ts","../../src/shared/neverthrow/mpp/index.ts","../../src/shared/operations/fetch-with-payment.ts","../../src/shared/operations/fetch-with-auth.ts"],"sourcesContent":["import z from 'zod';\n\nimport type { Address } from 'viem';\n\nexport const requestSchema = z.object({\n url: z.string().describe('The endpoint URL'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])\n .optional()\n .describe('HTTP method. Defaults to GET for fetch operations.'),\n body: z\n .unknown()\n .optional()\n .describe('Request body for POST/PUT/PATCH methods'),\n headers: z\n .record(z.string(), z.string())\n .optional()\n .describe('Additional headers to include')\n .default({}),\n timeout: z\n .number()\n .int()\n .positive()\n .optional()\n .describe('Request timeout in milliseconds'),\n});\n\ninterface BuildRequestProps {\n input: z.infer<typeof requestSchema>;\n address?: Address;\n sessionId?: string;\n provider?: string;\n}\n\nexport const buildRequest = ({\n input,\n address,\n sessionId,\n provider,\n}: BuildRequestProps) => {\n return new Request(input.url, {\n method: input.method ?? 'GET',\n body: input.body\n ? typeof input.body === 'string'\n ? input.body\n : JSON.stringify(input.body)\n : undefined,\n headers: {\n ...(input.body ? { 'Content-Type': 'application/json' } : {}),\n ...input.headers,\n ...(address\n ? { 'X-Wallet-Address': address, 'X-Client-ID': provider }\n : {}),\n ...(sessionId ? { 'X-Session-ID': sessionId } : {}),\n },\n });\n};\n","import { Challenge, Receipt } from 'mppx';\nimport {\n err,\n ok,\n resultFromPromise,\n resultFromThrowable,\n} from '@agentcash/neverthrow';\n\nimport type { BaseMppError } from './types';\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),\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 mppxClient: { createCredential: (response: Response) => Promise<string> },\n response: Response\n) => {\n return mppResultFromPromise(\n surface,\n mppxClient.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 { formatUnits } from 'viem';\n\nimport type { x402HTTPClient } from '@x402/core/client';\nimport type { Address } from 'viem';\nimport type { GlobalFlags } from '@/types';\n\nimport { resultFromPromise } from '@agentcash/neverthrow';\n\nimport { fetchErr, fetchOk, safeFetch } from '@/shared/neverthrow/fetch';\nimport {\n safeCreatePaymentPayload,\n safeGetPaymentRequired,\n safeGetPaymentSettlement,\n x402Err,\n x402Ok,\n} from '@/shared/neverthrow/x402';\nimport {\n safeGetMppChallenge,\n safeCreateMppCredential,\n safeGetMppReceipt,\n mppErr,\n mppOk,\n} from '@/shared/neverthrow/mpp';\n\nimport { log } from '@/shared/log';\nimport { detectPaymentProtocols } from '@/shared/protocol';\nimport { tokenStringToNumber } from '@/shared/token';\nimport { getBalance } from '@/shared/balance';\nimport { getTempoBalance } from '@/shared/tempo-balance';\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: 'x402' | 'mpp';\n amount: number;\n currency: string;\n network: string;\n}) => Promise<void>;\n\nexport interface PaymentClients {\n x402: x402HTTPClient;\n mpp: { createCredential: (response: Response) => Promise<string> };\n}\n\nexport interface PaymentInfo {\n protocol: 'x402' | 'mpp';\n price?: string;\n payment?: {\n success: boolean;\n transactionHash?: string;\n };\n}\n\nexport interface FetchWithPaymentResult {\n response: Response;\n paymentInfo: PaymentInfo | null;\n}\n\nexport interface FetchWithPaymentOptions {\n surface: string;\n clients: PaymentClients;\n paymentMethod: 'x402' | 'mpp' | 'auto';\n account: { address: Address };\n flags: GlobalFlags;\n beforePayment?: BeforePaymentHook;\n timeout?: 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, clients, paymentMethod, beforePayment, timeout } = options;\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 !== 'auto') {\n if (paymentMethod === 'mpp') {\n return handleMppPayment(surface, response, clonedRequest, options);\n }\n return handleX402Payment(\n surface,\n response,\n clonedRequest,\n clients.x402,\n beforePayment,\n timeout\n );\n }\n\n // Auto: detect available protocols, pick by higher balance\n const available = detectPaymentProtocols(response);\n\n let preferred: 'x402' | 'mpp';\n\n if (available.length === 1) {\n preferred = available[0]!;\n } else {\n // Both protocols available — pick by balance\n preferred = await pickByBalance(surface, response, options);\n }\n\n const fallback =\n available.length > 1 ? (preferred === 'mpp' ? 'x402' : 'mpp') : null;\n\n const result =\n preferred === 'mpp'\n ? await handleMppPayment(surface, response, clonedRequest, options)\n : await handleX402Payment(\n surface,\n response,\n clonedRequest,\n clients.x402,\n beforePayment,\n timeout\n );\n\n if (result.isErr() && fallback) {\n // Preferred failed — try fallback with a fresh request clone\n return fallback === 'mpp'\n ? handleMppPayment(surface, response, fallbackRequest, options)\n : handleX402Payment(\n surface,\n response,\n fallbackRequest,\n clients.x402,\n beforePayment,\n timeout\n );\n }\n\n return result;\n };\n}\n\n/**\n * Pick the preferred protocol by comparing wallet balances.\n * Falls back to 'mpp' if both balances fail to fetch.\n */\nasync function pickByBalance(\n surface: string,\n response: Response,\n options: FetchWithPaymentOptions\n): Promise<'x402' | 'mpp'> {\n const { account } = options;\n\n // Get x402 (USDC on Base) balance\n const x402BalanceResult = await resultFromPromise(\n 'balance',\n surface,\n getBalance({\n address: account.address,\n surface,\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 =\n (challengeResult.value.request.decimals as number | undefined) ?? 6;\n if (currency) {\n const tempoResult = await resultFromPromise(\n 'tempo',\n surface,\n getTempoBalance({\n address: account.address,\n tokenAddress: currency as Address,\n }),\n () => ({\n cause: 'tempo_balance' as const,\n message: 'Tempo balance check failed',\n })\n );\n if (tempoResult.isOk()) {\n mppBalance = Number(formatUnits(tempoResult.value.balance, decimals));\n }\n }\n }\n\n log.info(`Protocol selection — x402: $${x402Balance}, mpp: $${mppBalance}`);\n return x402Balance >= mppBalance ? 'x402' : 'mpp';\n}\n\nasync function handleX402Payment(\n surface: string,\n response: Response,\n clonedRequest: Request,\n client: x402HTTPClient,\n beforePayment?: BeforePaymentHook,\n timeout?: number\n) {\n const paymentRequiredResult = await safeGetPaymentRequired(\n surface,\n client,\n response\n );\n\n if (paymentRequiredResult.isErr()) {\n return paymentRequiredResult;\n }\n\n const paymentRequired = paymentRequiredResult.value;\n\n // Call beforePayment hook (e.g. balance check) before signing\n if (beforePayment) {\n const accept = paymentRequired.accepts[0];\n if (accept) {\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,\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 client,\n paymentRequired\n );\n\n if (paymentPayloadResult.isErr()) {\n return paymentPayloadResult;\n }\n\n const paymentPayload = paymentPayloadResult.value;\n\n // Encode payment header\n const paymentHeaders = client.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(\n surface,\n client,\n paidResponse\n );\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 ...(settlementResult.isOk()\n ? {\n payment: {\n success: settlementResult.value.success,\n transactionHash: settlementResult.value.transaction,\n },\n }\n : {}),\n },\n });\n }\n );\n}\n\nasync function handleMppPayment(\n surface: string,\n response: Response,\n clonedRequest: Request,\n options: FetchWithPaymentOptions\n) {\n const { clients, beforePayment, timeout } = options;\n const mppxClient = clients.mpp;\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 = challenge.request.amount as string | undefined;\n const decimals = (challenge.request.decimals as number | undefined) ?? 6;\n const currency = challenge.request.currency as string | undefined;\n\n // Call beforePayment hook (e.g. balance check)\n if (beforePayment && amount && currency) {\n const numericAmount = Number(formatUnits(BigInt(amount), decimals));\n const hookResult = await resultFromPromise(\n 'mpp',\n surface,\n beforePayment({\n protocol: 'mpp',\n amount: numericAmount,\n currency,\n network: `tempo:${challenge.method}`,\n }),\n e => ({\n cause: 'mpp_payment_already_attempted' 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 // Create credential (signs transaction on Tempo)\n const credentialResult = await safeCreateMppCredential(\n surface,\n mppxClient,\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 const priceDisplay = amount\n ? Number(formatUnits(BigInt(amount), decimals)).toLocaleString(\n 'en-US',\n {\n style: 'currency',\n currency: 'USD',\n }\n )\n : undefined;\n\n return mppOk<FetchWithPaymentResult>({\n response: paidResponse,\n paymentInfo: {\n protocol: 'mpp',\n ...(priceDisplay ? { price: priceDisplay } : {}),\n ...(receiptResult.isOk()\n ? {\n payment: {\n success: true,\n transactionHash: receiptResult.value.reference,\n },\n }\n : {}),\n },\n });\n }\n );\n}\n","import { x402Client, x402HTTPClient } from '@x402/core/client';\nimport { encodeSIWxHeader } from '@x402/extensions/sign-in-with-x';\n\nimport type { PrivateKeyAccount } from 'viem';\n\nimport {\n DEFAULT_USER_FETCH_TIMEOUT,\n fetchOk,\n safeFetch,\n} from '@/shared/neverthrow/fetch';\nimport {\n safeCreateSIWxPayload,\n safeGetPaymentRequired,\n} from '@/shared/neverthrow/x402';\nimport { getSiwxExtension } from '@/server/lib/x402-extensions';\n\nexport type FetchWithAuthResult =\n | { outcome: 'response'; response: Response; authenticated: boolean }\n | { outcome: 'no_siwx_extension'; extensions: string[] };\n\nexport interface FetchWithAuthOptions {\n surface: string;\n account: PrivateKeyAccount;\n timeout?: number;\n}\n\n/**\n * Create a fetch function with automatic SIWX (Sign-In With X) authentication.\n *\n * 1. Makes initial request\n * 2. If 402, parses for SIWX extension\n * 3. Creates signed wallet proof\n * 4. Retries with SIGN-IN-WITH-X header\n *\n * Returns a discriminated result:\n * - `outcome: 'response'` — a Response (authenticated or not), consumer handles ok/error\n * - `outcome: 'no_siwx_extension'` — 402 without SIWX, consumer decides how to present\n */\nexport function createFetchWithAuth(options: FetchWithAuthOptions) {\n const { surface, account, timeout = DEFAULT_USER_FETCH_TIMEOUT } = options;\n\n return async (request: Request) => {\n const retryRequest = request.clone();\n const httpClient = new x402HTTPClient(new x402Client());\n\n const firstResult = await safeFetch(surface, request, timeout);\n\n if (firstResult.isErr()) return firstResult;\n\n const firstResponse = firstResult.value;\n\n if (firstResponse.status !== 402) {\n return fetchOk<FetchWithAuthResult>({\n outcome: 'response',\n response: firstResponse,\n authenticated: false,\n });\n }\n\n const paymentRequiredResult = await safeGetPaymentRequired(\n surface,\n httpClient,\n firstResponse\n );\n\n if (paymentRequiredResult.isErr()) return paymentRequiredResult;\n\n const paymentRequired = paymentRequiredResult.value;\n const siwxExtension = getSiwxExtension(paymentRequired.extensions);\n\n if (!siwxExtension) {\n return fetchOk<FetchWithAuthResult>({\n outcome: 'no_siwx_extension',\n extensions: Object.keys(paymentRequired.extensions ?? {}),\n });\n }\n\n const payloadResult = await safeCreateSIWxPayload(\n surface,\n siwxExtension,\n account\n );\n\n if (payloadResult.isErr()) return payloadResult;\n\n const siwxHeader = encodeSIWxHeader(payloadResult.value);\n\n retryRequest.headers.set('SIGN-IN-WITH-X', siwxHeader);\n\n return (await safeFetch(surface, retryRequest, timeout)).andThen(response =>\n fetchOk<FetchWithAuthResult>({\n outcome: 'response',\n response,\n authenticated: true,\n })\n );\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,OAAO;AAIP,IAAM,gBAAgB,EAAE,OAAO;AAAA,EACpC,KAAK,EAAE,OAAO,EAAE,SAAS,kBAAkB;AAAA,EAC3C,QAAQ,EACL,KAAK,CAAC,OAAO,QAAQ,OAAO,UAAU,OAAO,CAAC,EAC9C,SAAS,EACT,SAAS,oDAAoD;AAAA,EAChE,MAAM,EACH,QAAQ,EACR,SAAS,EACT,SAAS,yCAAyC;AAAA,EACrD,SAAS,EACN,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAC7B,SAAS,EACT,SAAS,+BAA+B,EACxC,QAAQ,CAAC,CAAC;AAAA,EACb,SAAS,EACN,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,EACT,SAAS,iCAAiC;AAC/C,CAAC;AASM,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAyB;AACvB,SAAO,IAAI,QAAQ,MAAM,KAAK;AAAA,IAC5B,QAAQ,MAAM,UAAU;AAAA,IACxB,MAAM,MAAM,OACR,OAAO,MAAM,SAAS,WACpB,MAAM,OACN,KAAK,UAAU,MAAM,IAAI,IAC3B;AAAA,IACJ,SAAS;AAAA,MACP,GAAI,MAAM,OAAO,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,MAC3D,GAAG,MAAM;AAAA,MACT,GAAI,UACA,EAAE,oBAAoB,SAAS,eAAe,SAAS,IACvD,CAAC;AAAA,MACL,GAAI,YAAY,EAAE,gBAAgB,UAAU,IAAI,CAAC;AAAA,IACnD;AAAA,EACF,CAAC;AACH;;;ACxDA,SAAS,WAAW,eAAe;AASnC,IAAM,YAAY;AAEX,IAAM,QAAQ,CAAI,UAAa,GAAG,KAAK;AACvC,IAAM,SAAS,CAAC,SAAiB,UACtC,IAAI,WAAW,SAAS,KAAK;AAE/B,IAAM,uBAAuB,CAC3B,SACA,SACA,UACG,kBAAkB,WAAW,SAAS,SAAS,KAAK;AAEzD,IAAM,yBAAyB,CAC7B,SACA,IACA,UACG,oBAAoB,WAAW,SAAS,IAAI,KAAK;AAE/C,IAAM,sBAAsB,CAAC,SAAiB,aAAuB;AAC1E,SAAO;AAAA,IACL;AAAA,IACA,MAAM,UAAU,aAAa,QAAQ;AAAA,IACrC,YAAU;AAAA,MACR,OAAO;AAAA,MACP,SACE,iBAAiB,QACb,MAAM,UACN;AAAA,IACR;AAAA,EACF;AACF;AAEO,IAAM,0BAA0B,CACrC,SACA,YACA,aACG;AACH,SAAO;AAAA,IACL;AAAA,IACA,WAAW,iBAAiB,QAAQ;AAAA,IACpC,YAAU;AAAA,MACR,OAAO;AAAA,MACP,SACE,iBAAiB,QACb,MAAM,UACN;AAAA,IACR;AAAA,EACF;AACF;AAEO,IAAM,oBAAoB,CAAC,SAAiB,aAAuB;AACxE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ,aAAa,QAAQ;AAAA,IACnC,YAAU;AAAA,MACR,OAAO;AAAA,MACP,SACE,iBAAiB,QACb,MAAM,UACN;AAAA,IACR;AAAA,EACF;AACF;;;ACvEA,SAAS,mBAAmB;AAgFrB,SAAS,uBAAuB,SAAkC;AACvE,QAAM,EAAE,SAAS,SAAS,eAAe,eAAe,QAAQ,IAAI;AAEpE,SAAO,OAAO,YAAqB;AACjC,UAAM,gBAAgB,QAAQ,MAAM;AACpC,UAAM,kBAAkB,QAAQ,MAAM;AAEtC,UAAM,cAAc,MAAM,UAAU,SAAS,SAAS,OAAO;AAE7D,QAAI,YAAY,MAAM,GAAG;AACvB,aAAO,SAAS,SAAS,YAAY,KAAK;AAAA,IAC5C;AAGA,QAAI,YAAY,MAAM,WAAW,KAAK;AACpC,aAAO,YAAY;AAAA,QAAQ,CAAAA,cACzB,QAAgC,EAAE,UAAAA,WAAU,aAAa,KAAK,CAAC;AAAA,MACjE;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAG7B,QAAI,kBAAkB,QAAQ;AAC5B,UAAI,kBAAkB,OAAO;AAC3B,eAAO,iBAAiB,SAAS,UAAU,eAAe,OAAO;AAAA,MACnE;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,uBAAuB,QAAQ;AAEjD,QAAI;AAEJ,QAAI,UAAU,WAAW,GAAG;AAC1B,kBAAY,UAAU,CAAC;AAAA,IACzB,OAAO;AAEL,kBAAY,MAAM,cAAc,SAAS,UAAU,OAAO;AAAA,IAC5D;AAEA,UAAM,WACJ,UAAU,SAAS,IAAK,cAAc,QAAQ,SAAS,QAAS;AAElE,UAAM,SACJ,cAAc,QACV,MAAM,iBAAiB,SAAS,UAAU,eAAe,OAAO,IAChE,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAEN,QAAI,OAAO,MAAM,KAAK,UAAU;AAE9B,aAAO,aAAa,QAChB,iBAAiB,SAAS,UAAU,iBAAiB,OAAO,IAC5D;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACN;AAEA,WAAO;AAAA,EACT;AACF;AAMA,eAAe,cACb,SACA,UACA,SACyB;AACzB,QAAM,EAAE,QAAQ,IAAI;AAGpB,QAAM,oBAAoB,MAAM;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,WAAW;AAAA,MACT,SAAS,QAAQ;AAAA,MACjB;AAAA,IACF,CAAC,EAAE,KAAK,OAAM,EAAE,KAAK,IAAI,EAAE,MAAM,UAAU,CAAE;AAAA,IAC7C,OAAO;AAAA,MACL,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,kBAAkB,MAAM,GAAG;AAC7B,QAAI,MAAM,8CAA8C;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,kBAAkB;AAGtC,MAAI,aAAa;AACjB,QAAM,kBAAkB,oBAAoB,SAAS,QAAQ;AAC7D,MAAI,gBAAgB,KAAK,GAAG;AAC1B,UAAM,WAAW,gBAAgB,MAAM,QAAQ;AAG/C,UAAM,WACH,gBAAgB,MAAM,QAAQ,YAAmC;AACpE,QAAI,UAAU;AACZ,YAAM,cAAc,MAAM;AAAA,QACxB;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,UACd,SAAS,QAAQ;AAAA,UACjB,cAAc;AAAA,QAChB,CAAC;AAAA,QACD,OAAO;AAAA,UACL,OAAO;AAAA,UACP,SAAS;AAAA,QACX;AAAA,MACF;AACA,UAAI,YAAY,KAAK,GAAG;AACtB,qBAAa,OAAO,YAAY,YAAY,MAAM,SAAS,QAAQ,CAAC;AAAA,MACtE;AAAA,IACF;AAAA,EACF;AAEA,MAAI,KAAK,oCAA+B,WAAW,WAAW,UAAU,EAAE;AAC1E,SAAO,eAAe,aAAa,SAAS;AAC9C;AAEA,eAAe,kBACb,SACA,UACA,eACA,QACA,eACA,SACA;AACA,QAAM,wBAAwB,MAAM;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,sBAAsB,MAAM,GAAG;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,sBAAsB;AAG9C,MAAI,eAAe;AACjB,UAAM,SAAS,gBAAgB,QAAQ,CAAC;AACxC,QAAI,QAAQ;AACV,YAAM,SAAS,oBAAoB,OAAO,MAAM;AAChD,YAAM,aAAa,MAAM;AAAA,QACvB;AAAA,QACA;AAAA,QACA,cAAc;AAAA,UACZ,UAAU;AAAA,UACV;AAAA,UACA,UAAU;AAAA,UACV,SAAS,OAAO;AAAA,QAClB,CAAC;AAAA,QACD,QAAM;AAAA,UACJ,OAAO;AAAA,UACP,SACE,aAAa,QAAQ,EAAE,UAAU;AAAA,QACrC;AAAA,MACF;AACA,UAAI,WAAW,MAAM,GAAG;AACtB,eAAO,QAAQ,SAAS,WAAW,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,uBAAuB,MAAM;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,qBAAqB,MAAM,GAAG;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,qBAAqB;AAG5C,QAAM,iBAAiB,OAAO,6BAA6B,cAAc;AAGzE,MACE,cAAc,QAAQ,IAAI,mBAAmB,KAC7C,cAAc,QAAQ,IAAI,WAAW,GACrC;AACA,WAAO,QAAQ,SAAS;AAAA,MACtB,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AACzD,kBAAc,QAAQ,IAAI,KAAK,KAAK;AAAA,EACtC;AACA,gBAAc,QAAQ;AAAA,IACpB;AAAA,IACA;AAAA,EACF;AAGA,SAAO,MAAM,UAAU,SAAS,eAAe,OAAO,EAAE;AAAA,IACtD,kBAAgB;AACd,YAAM,mBAAmB;AAAA,QACvB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,aAAO,OAA+B;AAAA,QACpC,UAAU;AAAA,QACV,aAAa;AAAA,UACX,UAAU;AAAA,UACV,OAAO;AAAA,YACL,eAAe,SAAS;AAAA,UAC1B,EAAE,eAAe,SAAS;AAAA,YACxB,OAAO;AAAA,YACP,UAAU;AAAA,UACZ,CAAC;AAAA,UACD,GAAI,iBAAiB,KAAK,IACtB;AAAA,YACE,SAAS;AAAA,cACP,SAAS,iBAAiB,MAAM;AAAA,cAChC,iBAAiB,iBAAiB,MAAM;AAAA,YAC1C;AAAA,UACF,IACA,CAAC;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,eAAe,iBACb,SACA,UACA,eACA,SACA;AACA,QAAM,EAAE,SAAS,eAAe,QAAQ,IAAI;AAC5C,QAAM,aAAa,QAAQ;AAG3B,MAAI,cAAc,QAAQ,IAAI,eAAe,GAAG;AAC9C,WAAO,OAAO,SAAS;AAAA,MACrB,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAGA,QAAM,kBAAkB,oBAAoB,SAAS,QAAQ;AAE7D,MAAI,gBAAgB,MAAM,GAAG;AAC3B,WAAO;AAAA,EACT;AAEA,QAAM,YAAY,gBAAgB;AAGlC,QAAM,SAAS,UAAU,QAAQ;AACjC,QAAM,WAAY,UAAU,QAAQ,YAAmC;AACvE,QAAM,WAAW,UAAU,QAAQ;AAGnC,MAAI,iBAAiB,UAAU,UAAU;AACvC,UAAM,gBAAgB,OAAO,YAAY,OAAO,MAAM,GAAG,QAAQ,CAAC;AAClE,UAAM,aAAa,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,MACA,cAAc;AAAA,QACZ,UAAU;AAAA,QACV,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,SAAS,UAAU,MAAM;AAAA,MACpC,CAAC;AAAA,MACD,QAAM;AAAA,QACJ,OAAO;AAAA,QACP,SAAS,aAAa,QAAQ,EAAE,UAAU;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,WAAW,MAAM,GAAG;AACtB,aAAO,OAAO,SAAS,WAAW,KAAK;AAAA,IACzC;AAAA,EACF;AAGA,QAAM,mBAAmB,MAAM;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,iBAAiB,MAAM,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,iBAAiB;AAGpC,gBAAc,QAAQ,IAAI,iBAAiB,UAAU;AAGrD,SAAO,MAAM,UAAU,SAAS,eAAe,OAAO,EAAE;AAAA,IACtD,kBAAgB;AAEd,YAAM,gBAAgB,kBAAkB,SAAS,YAAY;AAE7D,YAAM,eAAe,SACjB,OAAO,YAAY,OAAO,MAAM,GAAG,QAAQ,CAAC,EAAE;AAAA,QAC5C;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,UAAU;AAAA,QACZ;AAAA,MACF,IACA;AAEJ,aAAO,MAA8B;AAAA,QACnC,UAAU;AAAA,QACV,aAAa;AAAA,UACX,UAAU;AAAA,UACV,GAAI,eAAe,EAAE,OAAO,aAAa,IAAI,CAAC;AAAA,UAC9C,GAAI,cAAc,KAAK,IACnB;AAAA,YACE,SAAS;AAAA,cACP,SAAS;AAAA,cACT,iBAAiB,cAAc,MAAM;AAAA,YACvC;AAAA,UACF,IACA,CAAC;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC1bA,SAAS,YAAY,sBAAsB;AAC3C,SAAS,wBAAwB;AAqC1B,SAAS,oBAAoB,SAA+B;AACjE,QAAM,EAAE,SAAS,SAAS,UAAU,2BAA2B,IAAI;AAEnE,SAAO,OAAO,YAAqB;AACjC,UAAM,eAAe,QAAQ,MAAM;AACnC,UAAM,aAAa,IAAI,eAAe,IAAI,WAAW,CAAC;AAEtD,UAAM,cAAc,MAAM,UAAU,SAAS,SAAS,OAAO;AAE7D,QAAI,YAAY,MAAM,EAAG,QAAO;AAEhC,UAAM,gBAAgB,YAAY;AAElC,QAAI,cAAc,WAAW,KAAK;AAChC,aAAO,QAA6B;AAAA,QAClC,SAAS;AAAA,QACT,UAAU;AAAA,QACV,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAEA,UAAM,wBAAwB,MAAM;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,sBAAsB,MAAM,EAAG,QAAO;AAE1C,UAAM,kBAAkB,sBAAsB;AAC9C,UAAM,gBAAgB,iBAAiB,gBAAgB,UAAU;AAEjE,QAAI,CAAC,eAAe;AAClB,aAAO,QAA6B;AAAA,QAClC,SAAS;AAAA,QACT,YAAY,OAAO,KAAK,gBAAgB,cAAc,CAAC,CAAC;AAAA,MAC1D,CAAC;AAAA,IACH;AAEA,UAAM,gBAAgB,MAAM;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,QAAI,cAAc,MAAM,EAAG,QAAO;AAElC,UAAM,aAAa,iBAAiB,cAAc,KAAK;AAEvD,iBAAa,QAAQ,IAAI,kBAAkB,UAAU;AAErD,YAAQ,MAAM,UAAU,SAAS,cAAc,OAAO,GAAG;AAAA,MAAQ,cAC/D,QAA6B;AAAA,QAC3B,SAAS;AAAA,QACT;AAAA,QACA,eAAe;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AACF;","names":["response"]}
|