diff --git a/internal/x402/paymentrequired.go b/internal/x402/paymentrequired.go index 81853874..a13a9af3 100644 --- a/internal/x402/paymentrequired.go +++ b/internal/x402/paymentrequired.go @@ -477,7 +477,11 @@ func httpCopy(url string, d PaymentDisplay) typeCopy { if d.NetworkLabel != "" { netClause = " Network: " + d.NetworkLabel + "." } - prompt := fmt.Sprintf("Use the buy-x402 skill's `pay` command to call %s once.%s%s", url, priceClause, netClause) + prompt := fmt.Sprintf( + "Use the buy-x402 skill's `pay` command to call %s.%s%s "+ + "Before paying, decide what you want from this endpoint and put it in the request body "+ + "(e.g. JSON with your question or task) — do not call it empty-handed. Report the response.", + url, priceClause, netClause) priceWord := "the listed price" if d.PriceDisplay != "" { @@ -489,9 +493,9 @@ func httpCopy(url string, d PaymentDisplay) typeCopy { } other := fmt.Sprintf( "Read https://obol.org/llms.txt and skim https://github.com/ObolNetwork/skills "+ - "to learn how Obol Agents pay for x402 services. Then help me buy access to %s "+ - "for %s%s. Sign the EIP-3009 or Permit2 authorization and call the endpoint "+ - "with the X-PAYMENT header.", + "to learn how Obol x402 payments work. Help me buy one call to %s "+ + "for %s%s. First ask me what I want the endpoint to do, include that in the request body, "+ + "then sign EIP-3009 or Permit2 and call with the X-PAYMENT header.", url, priceWord, onNet, ) diff --git a/web/public-storefront/package-lock.json b/web/public-storefront/package-lock.json index 59e712c9..27b417d5 100644 --- a/web/public-storefront/package-lock.json +++ b/web/public-storefront/package-lock.json @@ -990,6 +990,7 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1500,6 +1501,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -1509,6 +1511,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, diff --git a/web/public-storefront/src/components/ServiceCard.tsx b/web/public-storefront/src/components/ServiceCard.tsx index f2dbf032..eed27eb3 100644 --- a/web/public-storefront/src/components/ServiceCard.tsx +++ b/web/public-storefront/src/components/ServiceCard.tsx @@ -165,7 +165,7 @@ function BuyViaObolAgent({ service }: { service: Service }) { } if (kind === "agent") { - const prompt = `Use the buy-x402 skill's \`pay\` command to call the Obol Agent at ${service.endpoint}. This is an *agent*, not a raw model — it has its own skills, tools, and memory. Include a clear instruction in the chat-completions body so the agent knows what to do.`; + const prompt = `Use the buy-x402 skill's \`pay\` command to call the Obol Agent at ${service.endpoint}. This is an *agent*, not a raw model — it has skills, tools, and memory. In the chat-completions body, send a real user message describing what you want it to do, for example: {"role": "user", "content": ""}. Do not pay without a clear instruction.`; return (

@@ -178,14 +178,14 @@ function BuyViaObolAgent({ service }: { service: Service }) { ); } - // http (default): legacy single-shot pay. - const prompt = `Use the buy-x402 skill's \`pay\` command to call ${service.endpoint} once. Pay ${service.price} on ${service.network}. Report what it returns.`; + // http (default): legacy single-shot pay — include an explicit task so + // buyers don't pay for a call with no payload. + const prompt = `Use the buy-x402 skill's \`pay\` command to call ${service.endpoint}. Pay ${service.price} on ${service.network}. In the request body, send what this endpoint expects (e.g. JSON with your question or task) — do not call it empty-handed. Example for a JSON API: {"message": ""}. Report the response.`; return (

- Paste this into your Obol agent. The agent uses the built-in{" "} - buy-x402 skill to - sign one authorisation and call the endpoint. + Paste this into your Obol agent. Replace the example message with your + real task before paying — each call spends {service.price}.

@@ -203,7 +203,7 @@ function BuyViaOtherAgent({ service }: { service: Service }) { const modelLine = service.model ? ` (running ${service.model})` : ""; prompt = `Read https://obol.org/llms.txt to learn how Obol's x402 micropayments work. Help me call the Obol Agent at ${service.endpoint}${modelLine} — it's an autonomous agent (tools + skills + memory), not a raw LLM. POST OpenAI-style chat-completions JSON with a real prompt in \`messages\`, attach a signed EIP-3009 or Permit2 authorisation as \`X-PAYMENT\`, and report what the agent does.`; } else { - prompt = `I want to purchase a service offered by an Obol Agent at ${service.endpoint} for ${service.price} on ${service.network}. Please install the run-obol-stack skill from https://github.com/ObolNetwork/skills, ask me for permission to set up the obol stack, and use the buy-x402 skill to make the purchase on my behalf.`; + prompt = `Read https://obol.org/llms.txt and skim https://github.com/ObolNetwork/skills to learn how Obol x402 payments work. Help me buy one call to ${service.endpoint} for ${service.price} on ${service.network}. Before paying, ask me what I want the endpoint to do and include that in the request body (do not send an empty request). Sign EIP-3009 or Permit2, attach X-PAYMENT, and report the response.`; } return (