feat(x402): optional beforePayment hook to screen the recipient before paying - #1454
Open
hypeprinter007-stack wants to merge 1 commit into
Open
feat(x402): optional beforePayment hook to screen the recipient before paying#1454hypeprinter007-stack wants to merge 1 commit into
hypeprinter007-stack wants to merge 1 commit into
Conversation
…e paying Implements the neutral pre-payment hook proposed in coinbase#1402. Today the x402 action provider gates *where* the agent pays (registeredServices) and *how much* (maxPaymentUsdc), but nothing checks *who* the recipient is — a compromised or mistaken agent can pay a sanctioned/drainer address. Adds an optional `beforePayment` config hook that runs in retry_http_request_with_x402 after amount + network validation and immediately before the payment is signed/ settled, receiving the payment context (incl. the selected option's `payTo`). Returning { abort: true, reason } refuses the payment — no signature, no settlement. Deliberately provider-neutral: no screening backend is imported. Any implementation plugs in (sanctions / reputation / allowlist); the README shows anchor-x402-safe-pay's allow/review/block verdict as one example. Scope: the hook covers the recommended two-step flow (make_http_request -> retry_http_request_with_x402), which exposes payTo before paying. The one-shot make_http_request_with_x402 auto-settles a 402 inside wrapFetchWithPayment and does not expose the recipient pre-settlement, so it is intentionally not gated (noted in the README). Fully backward compatible — no behavior change unless beforePayment is set. Tests: added two cases mirroring the existing retry tests — abort (no payment signed) and allow (payment proceeds). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🟡 Heimdall Review Status
|
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.
What & why
Implements the neutral pre-payment hook proposed in #1402.
Today the x402 action provider gates where the agent can pay (
registeredServices) and how much (maxPaymentUsdc), but nothing checks who the recipient is. A compromised or mistaken agent can pay a sanctioned / drainer / phishing address that passes both existing gates. This adds the missing seat: an optional recipient check at the pre-payment chokepoint.The change
A new optional
beforePaymentconfig hook:retry_http_request_with_x402after amount + network validation and immediately before any signing/settlement.payTo.{ abort: true, reason }refuses the payment — no signature, no settlement; the action returns a structured error.anchor-x402-safe-pay'sallow/review/blockverdict as one example.This matches the design discussion on #1402 (three-state-friendly: the hook returns a decision + reason and is agnostic to how the verdict was reached).
Scope & compatibility
beforePaymentis set.make_http_request→retry_http_request_with_x402), which exposespayTobefore paying. The one-shotmake_http_request_with_x402auto-settles a402insidewrapFetchWithPaymentand does not expose the recipient pre-settlement, so it is intentionally not gated (documented in the README). Gating it would need a larger refactor of that path.Tests
Two cases added mirroring the existing
retryWithX402tests:beforePaymentreturns{ abort: true }→ hook sees thepayTo/context,wrapFetchWithPaymentis never called, action returns the abort error.beforePaymentallows → payment proceeds normally.Notes for reviewers
schemas.ts(config field +X402BeforePaymentContext/X402BeforePaymentDecisiontypes),x402ActionProvider.ts(resolve + call site),x402ActionProvider.test.ts(2 tests),README.md(docs + example).Closes #1402 (or partially addresses, if you'd prefer to keep it open for the Python side).