Skip to content

feat(x402): add x402-protected chat endpoint at $0.01#178

Open
sweetmantech wants to merge 7 commits intotestfrom
sweetmantech/myc-4077-api-apix402chat-x402-001
Open

feat(x402): add x402-protected chat endpoint at $0.01#178
sweetmantech wants to merge 7 commits intotestfrom
sweetmantech/myc-4077-api-apix402chat-x402-001

Conversation

@sweetmantech
Copy link
Contributor

Summary

  • Add new x402-protected chat endpoint at /api/x402/chat with $0.01 price
  • Route all /api/chat traffic through x402 endpoint with credit deductions
  • Follow image generation x402 pattern for credit deduction and USDC payments

Test plan

  • All 831 tests pass
  • Build compiles successfully
  • Verify /api/x402/chat endpoint works with x402 payment
  • Verify /api/chat properly routes through x402 with credit deduction
  • Test streaming responses work correctly

🤖 Generated with Claude Code

This commit adds a new x402-protected chat endpoint at /api/x402/chat
with a price of $0.01 per request. All traffic to /api/chat now flows
through the x402 endpoint using credit deductions and USDC payments.

Changes:
- Add CHAT_PRICE constant ($0.01) to lib/const.ts
- Configure x402 middleware to protect POST /api/x402/chat
- Create /api/x402/chat/route.ts endpoint handler
- Add handleChatStreamX402 for x402-specific streaming
- Add validateChatRequestX402 for x402 body validation (accountId required)
- Add validateChatAuth for auth-only validation
- Add fetchWithPaymentStream for POST requests with streaming
- Add x402Chat wrapper function for calling x402 endpoint
- Update /api/chat to route through x402 with credit deduction
- Add comprehensive tests for all new functions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Contributor

vercel bot commented Jan 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
recoup-api Ready Ready Preview Jan 29, 2026 11:22pm

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sweetmantech/myc-4077-api-apix402chat-x402-001

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

Braintrust eval report

Catalog Opportunity Analysis Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Catalog_availability 26.1% (-32pp) 3 🟢 2 🔴
Llm_calls 0 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 34.21s (-8.1s) 4 🟢 1 🔴

Catalog Songs Count Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
AnswerCorrectness 19.7% (+0pp) 2 🟢 1 🔴
Factuality 33.3% (-33pp) 1 🟢 2 🔴
Llm_calls 4 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 14.77s (+0.98s) 2 🟢 1 🔴

First Week Album Sales Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Factuality 55% (-15pp) - 1 🔴
Llm_calls 1 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 16.74s (+0.81s) 1 🟢 3 🔴

Memory & Storage Tools Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Tools_called 0% (+0pp) - -
Llm_calls 0 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 18.87s (-4.5s) 1 🟢 -

Monthly Listeners Tracking Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
AnswerSimilarity 77.8% (-1pp) 3 🟢 2 🔴
Llm_calls 2 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 13.87s (-2.2s) 4 🟢 1 🔴

Search Web Tool Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
AnswerCorrectness 28% (+0pp) 6 🟢 5 🔴
Llm_calls 3 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 20.08s (-5.9s) 9 🟢 2 🔴

Social Scraping Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Tools_called 0% (+0pp) - -
Llm_calls 0 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 20.9s (-5.35s) 4 🟢 2 🔴

Spotify Followers Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
AnswerCorrectness 20.4% (0pp) 2 🟢 3 🔴
Llm_calls 3 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 13.96s (+2.72s) - 5 🔴

Spotify Tools Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Tools_called 0% (+0pp) - -
Llm_calls 0 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 34.27s (+5.24s) 1 🟢 1 🔴

TikTok Analytics Questions Evaluation (HEAD-1769728888)

Score Average Improvements Regressions
Question_answered 0% (+0pp) - -
Llm_calls 0 (+0) - -
Tool_calls 0 (+0) - -
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 0tok (+0tok) - -
Prompt_cached_tokens 0tok (+0tok) - -
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 0tok (+0tok) - -
Completion_reasoning_tokens 0tok (+0tok) - -
Total_tokens 0tok (+0tok) - -
Duration 11.58s (-0.83s) 1 🟢 1 🔴

Extract the shared streaming logic into streamChatResponse function
that both handleChatStream and handleChatStreamX402 can use. This
eliminates code duplication and follows the KISS principle.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Since /api/chat now routes through x402, handleChatStream is no longer
used. Remove it and its tests to follow YAGNI principle.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The middleware matcher was running on all /api/* routes, which caused
CORS preflight (OPTIONS) requests to /api/chat to be intercepted and
redirected by the x402 middleware. Now the middleware only runs on
/api/x402/* routes where x402 payment protection is needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The x402 internal response already contains CORS headers, and we were
adding our own on top, resulting in 'Access-Control-Allow-Origin: *, *'.
Now we filter out any access-control-* headers from the internal
response before adding our own CORS headers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
loadAccount was hardcoded to use IMAGE_GENERATE_PRICE ($0.15) for all
transfers. Now it accepts a price parameter so chat uses CHAT_PRICE
($0.01) and image generation uses IMAGE_GENERATE_PRICE ($0.15).

Changes:
- Update loadAccount to accept price parameter
- Update fetchWithPayment to pass IMAGE_GENERATE_PRICE
- Update fetchWithPaymentStream to pass the price parameter
- Add tests for loadAccount
- Update fetchWithPaymentStream tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When streaming responses go through proxy middleware, they can be
buffered/compressed causing glitchy streaming. Adding Content-Encoding:
none header prevents this.

See: https://ai-sdk.dev/docs/troubleshooting/streaming-not-working-when-proxied

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant