The x402 action provider gates payments on two axes today — host (isUrlAllowed) and amount (validatePaymentLimit) — but nothing lets an operator inspect the payment recipient wallet (payTo) before wrapFetchWithPayment signs in retryWithX402.
The gap. "Is the address my agent is about to send USDC to sanctioned / a known drainer / phishing?" is a distinct axis from host-allowlist and amount-cap, and arguably the one an autonomous payer most wants closed before signing. The selected requirements already carry payTo (it is on PaymentRequirements), so the data is in hand — there is just no decision point exposed to config.
Precedent. The official @x402 core client already exposes onBeforePaymentCreation(context) returning { abort, reason }, with context.selectedRequirements.payTo available. AgentKit wraps @x402/fetch but does not surface an equivalent pre-pay decision point to x402ActionProvider config.
Proposal. A neutral, optional config hook — e.g.:
beforePayment?: (req: { payTo: string; network: string; scheme: string; amountUsdc: number; url: string })
=> { allow: boolean; reason?: string } | Promise<{ allow: boolean; reason?: string }>;
evaluated in retryWithX402 right after validatePaymentLimit and before wrapFetchWithPayment — same shape as the existing isUrlAllowed / validatePaymentLimit gates. It just hands the operator the selected requirements and lets them allow/deny. No vendor coupling — the hook is provider-agnostic.
Use case / one implementation. Recipient sanctions + address-reputation screening before an autonomous send. anchor-x402-safe-pay (npm/PyPI) is one drop-in that returns an allow/review/block verdict for a payTo, but the hook itself is generic.
Happy to send the PR (config field + hook eval in retryWithX402 + a test, mirroring validatePaymentLimit) if you are open to the addition — proposing first since it is a new public config surface.
The x402 action provider gates payments on two axes today — host (
isUrlAllowed) and amount (validatePaymentLimit) — but nothing lets an operator inspect the payment recipient wallet (payTo) beforewrapFetchWithPaymentsigns inretryWithX402.The gap. "Is the address my agent is about to send USDC to sanctioned / a known drainer / phishing?" is a distinct axis from host-allowlist and amount-cap, and arguably the one an autonomous payer most wants closed before signing. The selected requirements already carry
payTo(it is onPaymentRequirements), so the data is in hand — there is just no decision point exposed to config.Precedent. The official
@x402core client already exposesonBeforePaymentCreation(context)returning{ abort, reason }, withcontext.selectedRequirements.payToavailable. AgentKit wraps@x402/fetchbut does not surface an equivalent pre-pay decision point tox402ActionProviderconfig.Proposal. A neutral, optional config hook — e.g.:
evaluated in
retryWithX402right aftervalidatePaymentLimitand beforewrapFetchWithPayment— same shape as the existingisUrlAllowed/validatePaymentLimitgates. It just hands the operator the selected requirements and lets them allow/deny. No vendor coupling — the hook is provider-agnostic.Use case / one implementation. Recipient sanctions + address-reputation screening before an autonomous send.
anchor-x402-safe-pay(npm/PyPI) is one drop-in that returns an allow/review/block verdict for apayTo, but the hook itself is generic.Happy to send the PR (config field + hook eval in
retryWithX402+ a test, mirroringvalidatePaymentLimit) if you are open to the addition — proposing first since it is a new public config surface.