coinbase / coinbase/agentkit

Proposal: a neutral pre-payment recipient hook in the x402 action provider (inspect payTo before paying)

Open
#1,402 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.3k
Forks
815
Avg merge
13h 31m
Merged PRs (30d)
2

Description

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.:
```ts
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.