# Payer Binding: agentbadge-pay:v1 — Anti-Sniping for Self-Settle x402

## Summary

On Arc self-settle payments (`eip3009-client-broadcast`), the txHash is
a bearer credential: public in the mempool, presentable by anyone.
Payer binding closes this: the payer signs a canonical challenge
naming wallet + method + path + txHash + timestamp (EIP-191), and the
server compares the recovered signer to the on-chain `Transfer.from`
BEFORE the replay slot is claimed. A rejected snipe never consumes the
payment.

## Canonical Challenge (sign verbatim)

```
agentbadge-pay:v1
wallet:<WALLET lowercase>
method:<METHOD>
path:<PATH>
payref:<TXHASH lowercase>
timestamp:<UNIX SEC>
```

## Request Headers

| Header | Content |
|---|---|
| `payment-signature` | x402 payload (base64) containing `payload.txHash` |
| `X-Wallet` | payer address |
| `X-Sig` | EIP-191 signature over the challenge |
| `X-Timestamp` | unix seconds, ±300s drift |

## Errors

| Status | Code | Meaning |
|---|---|---|
| 402 | `payer_binding_required` | txHash payload without binding headers |
| 403 | `WRONG_SIGNER` | X-Sig signer ≠ on-chain payer |
| 402 | replay | txHash already consumed |

Rejected snipes do NOT burn the replay slot — the legit payer's retry
succeeds.

## Verify Yourself

1. `recoverMessageAddress(challenge, X-Sig)` → must equal `X-Wallet`
2. Read the txHash's `Transfer(from,to,value)` log → `from` must equal `X-Wallet`

No registry, no token store — signature + receipt + comparison.

## Endpoints

| Need | Endpoint |
|---|---|
| Full binding spec | `GET /payer-binding.md` |
| 402 declaration | `extensions.payerBinding` + `accepts[].extra.payerBinding` on every paid route |
| SDK | `buildPayerChallenge`, `signPayerChallenge` in `@agentbadge/circle-payments` |
| Live dogfood | `scripts/payer-bind-dogfood.mts` (ENDPOINT/PAYER_KEY/ATTACKER_KEY) |



    <section class="mt-8 rounded-xl border border-emerald-800/30 bg-slate-900/50 p-6">
      <h3 class="text-lg font-bold text-slate-100">Relevant Engineering Capabilities</h3>
      <p class="mt-1 text-sm text-slate-400">The AgentBadge team can help with what you're reading about.</p>
      <div class="mt-4 grid gap-3">
        
        <div class="rounded-lg border border-slate-700 bg-slate-800/50 p-4">
          <div class="flex items-center justify-between">
            <h4 class="text-sm font-semibold text-emerald-400">AI Agent Architecture</h4>
            <span class="text-xs text-slate-400">Confidence: 0.93</span>
          </div>
          <p class="mt-1 text-xs text-slate-400">Design and implementation of AI agent infrastructure, agent APIs, machine-readable interfaces, and agent tooling.
</p>
          <div class="mt-2 flex items-center gap-3 text-xs text-slate-500">
            <span>People: Paul</span>
            <span>Status: VERIFIED</span>
          </div>
        </div>
        <div class="rounded-lg border border-slate-700 bg-slate-800/50 p-4">
          <div class="flex items-center justify-between">
            <h4 class="text-sm font-semibold text-emerald-400">Backend Development</h4>
            <span class="text-xs text-slate-400">Confidence: 0.92</span>
          </div>
          <p class="mt-1 text-xs text-slate-400">Node.js, NestJS, PostgreSQL, Redis, REST APIs, and event-driven systems.
</p>
          <div class="mt-2 flex items-center gap-3 text-xs text-slate-500">
            <span>People: Paul</span>
            <span>Status: VERIFIED</span>
          </div>
        </div>
      </div>
      
        <div class="mt-3">
          <p class="text-xs text-slate-500 mb-1">Related services:</p>
          <div class="flex flex-wrap gap-2">
            <span class="text-xs rounded-full bg-slate-700 px-2 py-1 text-slate-300">AI Agent Consulting</span>
          </div>
        </div>
      <div class="mt-4">
        <a href="/agent-guide/team/capabilities" class="inline-flex items-center text-sm font-medium text-emerald-400 hover:text-emerald-300">
          View all capabilities →
        </a>
      </div>
    </section>