Conversation
SELAT-DEV
requested review from
SkywalkerJi,
hzb1115 and
tangmengqiu
as code owners
July 29, 2026 16:11
7 tasks
- Add optional `payment` ("" | "x402"), `max_usd_per_call` and
`max_usd_per_day` to ExternalDataSource; all default to unset,
existing configs are unaffected
- Mirror the optional fields in web/src/types/strategy.ts so Strategy
Studio round-trips the config without stripping them
No engine behavior changes in this commit.
Refs NoFxAiOS#1532
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
External data sources can only send static headers today, so any x402-payable API fails with an unhandled 402 even though the payment client and wallet key already exist for claw402 inference. - On 402 from a source with payment="x402", sign and retry via the existing payment.DoX402Request using the trader's wallet key - Enforce max_usd_per_call against the authorized amount from accepts[0] before signing — under "upto" that amount is the worst case, so it remains the right bound; refuse above cap, never pay silently - Require max_usd_per_day and enforce it client-side per source (UTC day window): polling via refresh_secs makes a per-call cap alone unbounded. Counter is in-memory (resets on restart; persisted counter offered as follow-up) - Accept "exact" and "upto" on Base (eip155:8453) only; refuse other schemes and networks - Keep SSRF URL validation and SafeHTTPClient on the paid path - Queue settled payments (source name + USD) for cost tracking and render fetched external data into the AI context via a new deterministic formatter section Sources without payment set keep exact current behavior (regression-tested). Refs NoFxAiOS#1532 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Fetch configured external_data_sources in buildTradingContext and attach the result to the AI context - Drain settled x402 data payments into ai_charges via RecordWithCost (model = source name, provider = "x402-data") so data spend appears in the cost dashboard next to inference spend Refs NoFxAiOS#1532 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SELAT-DEV
force-pushed
the
feature/x402-external-data-sources
branch
from
August 28, 2026 18:48
5b7e08d to
d280a64
Compare
Author
|
Rebased onto current The only conflict was in Re-verified on the rebased branch:
Ready for review. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
external_data_sourcesonly support static headers, so x402-payable data APIs fail with an unhandled 402 — even though the x402 payment client and wallet key already exist for claw402 inference ([FEATURE] x402-payable external data sources (pay per call with the existing wallet, no API keys) #1532). The feature was also not wired into the trading loop, so configured sources never reached the AI context or the cost dashboard.payment: "x402"+ bothmax_usd_per_callandmax_usd_per_day. A 402 offer is validated before signing (schemeexact/upto, Baseeip155:8453only, authorized amount fromaccepts[0]≤ per-call cap, daily budget not exhausted), then paid via the existingpayment.DoX402Requestwith the trader's wallet key. Settled spend is logged per call, counted against the per-source UTC daily budget, and recorded intoai_charges(model= source name,provider="x402-data") so data spend shows next to inference spend. External data is fetched inbuildTradingContextand rendered into the AI context via a deterministic formatter section.paymentkeep exact current behavior (regression-tested — a 402 stays an error, nothing is ever paid). No new dependencies. No Strategy Studio form UI (types round-trip only). Non-Base networks and other schemes are refused, not supported. Daily counter is in-memory (resets on restart) — persisting it (seeding fromai_charges) is offered as a follow-up.Change Type
Scope
Linked Issues
Testing
What you verified and how:
go build ./...passesgo test ./...passes (all packages; 9 new tests inkernel/engine_external_x402_test.gofollowing themcp/payment/x402_test.gohttptest patterns)New tests cover: happy path (402 → cap check → sign → paid retry → JSON in context, charge queued, daily counter incremented, drain-once semantics); per-call cap refusal with zero payment attempts; daily-budget exhaustion on the second call; UTC day-window rollover; both-caps-required validation; missing-wallet-key error;
uptoaccepted with authorized amount as the worst-case bound; empty scheme defaulting toexact; unknown scheme refused; non-Base network refused; amount parsing (decimal + 0x-hex atomic units); unpaid-source 402 regression guard; deterministic sorted formatter output.Manual:
gofmtclean on touched files,go vet ./kernel/...clean,cd web && npm run buildpasses.Security Impact
NewStrategyEnginefor claw402; parsed once, never logged.security.ValidateURL+SafeHTTPClientas unpaid ones, including the paid retry; offers are validated (scheme/network/amount/caps) before anything is signed; both caps are mandatory, fail-closed.Compatibility
paymentis byte-for-byte current behavior.external_data_sourcesentries.Follow-ups I'm happy to pick up if wanted: persisted daily counter seeded from
ai_charges; a Strategy Studio form field for the new options; a README example config.🤖 Generated with Claude Code