Skip to content

Commit 9f53811

Browse files
whoabuddyclaude
andauthored
fix(ax-discovery): bind agent card URLs to request origin (#114)
The static AGENT_CARD const hardcoded https://x402.aibtc.com everywhere — url, documentationUrl, openApiUrl, x402Manifest, and 5 topicDocs entries. The same code is deployed to x402.aibtc.com and x402.aibtc.dev, so testnet agents fetching x402.aibtc.dev/.well-known/agent.json received a card pointing entirely at mainnet. Discovery silently routed testnet traffic to mainnet endpoints. Convert AGENT_CARD to buildAgentCard(requestUrl) which derives the base from new URL(requestUrl).origin. The handler at /.well-known/agent.json now invokes the builder per request. Network binding is automatic — no env-flag plumbing required. Closes #113. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6410003 commit 9f53811

1 file changed

Lines changed: 21 additions & 16 deletions

File tree

src/endpoints/ax-discovery.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,34 +1500,38 @@ const TOPIC_DOCS: Record<string, string> = {
15001500
"payment-flow": PAYMENT_FLOW_DOC,
15011501
};
15021502

1503-
// Agent card
1504-
const AGENT_CARD = {
1503+
// Agent card builder. URLs are bound to the request origin so the same code
1504+
// deployed to x402.aibtc.com and x402.aibtc.dev returns network-appropriate
1505+
// discovery pointers — testnet agents discover testnet endpoints, not mainnet.
1506+
function buildAgentCard(requestUrl: string) {
1507+
const base = new URL(requestUrl).origin;
1508+
return {
15051509
name: "x402 Stacks API",
15061510
description:
15071511
"Pay-per-use API powered by x402 v2 protocol on Stacks blockchain. " +
15081512
"Agents pay per request via STX, sBTC, or USDCx — no API keys or accounts needed. " +
15091513
"Provides inference (LLM), hashing, Stacks utilities, and agent storage.",
1510-
url: "https://x402.aibtc.com",
1514+
url: base,
15111515
provider: {
15121516
organization: "AIBTC Working Group",
15131517
url: "https://aibtc.com",
15141518
},
15151519
// x402 protocol version (not the package version, which is in package.json)
15161520
version: "2.0.0",
1517-
documentationUrl: "https://x402.aibtc.com/llms.txt",
1518-
openApiUrl: "https://x402.aibtc.com/openapi.json",
1521+
documentationUrl: `${base}/llms.txt`,
1522+
openApiUrl: `${base}/openapi.json`,
15191523
documentation: {
1520-
quickStart: "https://x402.aibtc.com/llms.txt",
1521-
fullReference: "https://x402.aibtc.com/llms-full.txt",
1522-
openApiSpec: "https://x402.aibtc.com/openapi.json",
1523-
x402Manifest: "https://x402.aibtc.com/x402.json",
1524+
quickStart: `${base}/llms.txt`,
1525+
fullReference: `${base}/llms-full.txt`,
1526+
openApiSpec: `${base}/openapi.json`,
1527+
x402Manifest: `${base}/x402.json`,
15241528
platform: "https://aibtc.com/llms.txt",
15251529
topicDocs: {
1526-
index: "https://x402.aibtc.com/topics",
1527-
inference: "https://x402.aibtc.com/topics/inference",
1528-
hashing: "https://x402.aibtc.com/topics/hashing",
1529-
storage: "https://x402.aibtc.com/topics/storage",
1530-
paymentFlow: "https://x402.aibtc.com/topics/payment-flow",
1530+
index: `${base}/topics`,
1531+
inference: `${base}/topics/inference`,
1532+
hashing: `${base}/topics/hashing`,
1533+
storage: `${base}/topics/storage`,
1534+
paymentFlow: `${base}/topics/payment-flow`,
15311535
},
15321536
},
15331537
capabilities: {
@@ -1746,7 +1750,8 @@ const AGENT_CARD = {
17461750
outputModes: ["application/json"],
17471751
},
17481752
],
1749-
};
1753+
} as const;
1754+
}
17501755

17511756
// =============================================================================
17521757
// AX Discovery Router
@@ -1836,7 +1841,7 @@ axDiscoveryRouter.get("/topics/:topic", (c) => {
18361841
});
18371842

18381843
axDiscoveryRouter.get("/.well-known/agent.json", (c) => {
1839-
return c.json(AGENT_CARD, 200, {
1844+
return c.json(buildAgentCard(c.req.url), 200, {
18401845
"Cache-Control": "public, max-age=3600, s-maxage=86400",
18411846
});
18421847
});

0 commit comments

Comments
 (0)