x402 Progressive Demo · Chapter 7 of 7

Monitored Address

What if the buyer just sends crypto to an address — and the shop watches for it?
Published 2026-04-16 · Northwoods Software · x402 Payment Protocol

The Observation

One of our early publisher partners noticed something while shopping on other crypto-enabled sites:

"I saw a couple of other shopping experiences where the prompt on the screen was to send crypto to a known address. That address is monitored. When it sees the payment it notifies the cart that everything is OK and payment has been made."

He added: "This might be something we want to explore further, especially if we move past micropayments. It'll be interesting to see how micropayments evolve on the phone. That could be a big barrier at the moment."

This is a pattern that has a name in the crypto payment industry: the monitored address (or "payment address") flow. And it turns out, it might solve the iPhone problem more cleanly than anything else we've tried.

How It Works

┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Buyer's │ │ Shop's │ │ Solana │ │ Browser │ │ Server │ │ network │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ 1. │ "I want to pay" │ │ │───────────────────▶│ │ │ │ │ 2. │ QR code + address │ │ │ + reference key │ │ │◀───────────────────│ │ │ │ │ 3. │ (buyer opens │ │ │ ANY wallet on │ │ │ ANY device, │ │ │ sends manually) │ │ │ │ ┌──────────┤ │ │ │ tx lands │ │ │ │ on-chain │ │ │◀────────┘ │ 4. │ │ monitors via │ │ │ RPC / webhook │ │ │ │ 5. │ "Payment received │ │ │ — order confirmed│ │ │◀───────────────────│ │ │ │ │

The key insight: the shop's browser and the buyer's wallet never need to talk to each other. The buyer opens their wallet independently, sends to the address they see on screen, and the server detects the payment by watching the blockchain. No browser extension. No relay server. No deep links. No app switching.

Why This Matters for Mobile

Every mobile crypto payment solution we've explored so far has the same fundamental constraint: the shop's browser needs to communicate with the buyer's wallet app. That's hard on iPhone because iOS isolates apps from each other.

ApproachHow browser talks to walletiPhone friction
Browser extension (Ch 1–4)Wallet injects into browserImpossible — iOS doesn't allow extensions
Deep links (Ch 5, Phase 1)Universal link opens wallet browserUser leaves Safari entirely
WalletConnect (Ch 5, Phase 2)Relay server bridges browser ↔ walletClunky — relay instability, experimental Solana support
Monitored address (Ch 7)They don't talk at allZero friction — wallet is independent
The monitored-address pattern is device-agnostic by design. The buyer can use Phantom on their iPhone, Solflare on their Android, a hardware wallet on their desktop, or even a centralized exchange withdrawal — as long as the USDC arrives at the right address with the right reference, the order is fulfilled. The shop doesn't care how or where the payment was initiated.

The Technology: Solana Pay Reference Keys

The Solana Pay specification defines exactly this pattern with an elegant correlation mechanism called a reference key.

For each order, the server generates a random keypair. The public key becomes the "reference" — it's included as a non-signing account in the buyer's transfer instruction. The server then calls getSignaturesForAddress(reference) to find the exact transaction that matches this order. No address reuse, no memo parsing, no ambiguity.

// Server generates a payment request
const reference = Keypair.generate().publicKey  // unique per order
const paymentUrl = encodeURL({
  recipient: merchantWallet,
  amount: new BigNumber(12.00),
  splToken: USDC_MINT,
  reference,               // ← this is the magic
  label: 'My Shop',
  message: 'Premium Content Access',
})

// Server monitors for the payment
const signatures = await connection.getSignaturesForAddress(reference)
// When signatures.length > 0, the payment arrived

Latency: How Fast Is Detection?

Detection MethodLatencyCostBest For
RPC polling (getSignaturesForAddress every 2-3s)2–5 secondsFree (RPC credits only)Demo, low-volume shops
Helius enhanced webhooks<2 seconds$25/month (developer tier)Production, real-time UX
Custom validator subscription (websocket)<1 secondRPC provider costHigh-volume, latency-critical

For a typical small publisher, RPC polling is free and fast enough. A buyer sends USDC from their phone, and within 3–5 seconds the shop page updates to "Payment received!" — comparable to a Venmo notification.

Security Considerations

What we gain vs. what we give up

The current x402 signing flow (Chapters 1–4) has the buyer sign a specific transaction — exact amount, exact recipient, exact token. The server verifies that exact transaction. The monitored-address pattern is more permissive: it accepts any incoming transfer that matches the expected amount and reference.

ConcernSigning Flow (Ch 1–4)Monitored Address (Ch 7)
Proves payer authorized the transferYes — cryptographic signatureNo — only proves funds arrived
Amount verificationServer checks exact amount on-chainSame — server checks received ≥ expected
Front-running riskNone — tx is pre-signedPossible — mitigated by random reference keys
Order correlationServer knows exactly which txReference key links payment to order
ExpirationTx expires with blockhash (~2 min)Reference must expire server-side (15 min recommended)
For a $12 purchase, the security trade-off is acceptable. For high-value orders ($100+), the signing flow should remain the primary path, with the monitored address as a mobile fallback. The framework should auto-detect wallet availability and offer the right path for the environment.

Required mitigations

Where Micropayments Fit

A natural follow-up question: "How do micropayments work in this model?"

The monitored-address pattern works beautifully for $1+ payments — the buyer is already thinking "I'm buying something, let me open my wallet and send." But below $1, the manual-send UX breaks down. Asking a human to open a wallet app, paste an address, carefully type "$0.03", and confirm — for three cents — is absurd.

Amount RangeBest Payment PatternWhy
< $0.10Embedded wallet + auto-sign (Ch 6 future)Must be invisible — user shouldn't "feel" the payment
$0.10 – $1.00Browser signing (Ch 1–4) or embedded walletOne-click approve is fast enough for small amounts
$1.00 – $100Monitored address (Ch 7) or browser signingManual send is natural at this range — like Venmo
> $100Browser signing (primary) + monitored address (fallback)High-value needs cryptographic payer proof

The x402 framework doesn't force one pattern. It provides adapters for each — and the checkout UI auto-detects the buyer's environment and offers the best available option.

What the Framework Adds

A new adapter — createSolanaMonitorAdapter — implements the same ChainAdapter interface as the signing and WalletConnect adapters. The framework's registry pattern means adding this path doesn't change any existing code:

// Register alongside existing adapters
client.registerChain('solana', solanaAdapter)           // browser signing
client.registerChain('solana-wc', walletConnectAdapter) // mobile deep links
client.registerChain('solana-qr', monitorAdapter)       // monitored address (new)

// Auto-detect: if browser wallet found → use signing flow
//              if mobile + no wallet   → offer QR pay
//              if desktop + no wallet  → show onboarding

Who Does This Well Today

What's Next

This chapter is currently in the research and design phase. The team has analyzed the pattern, identified the security mitigations, and confirmed the infrastructure exists (Solana Pay SDK + Helius webhooks). The next step is building a working demo — a new page in the progressive proof that shows the QR code flow end-to-end.

Estimated effort: 2–3 days for a working demo, 1 additional week for production hardening (expiry, partial payment handling, Helius webhook integration).

The bigger picture: this chapter emerged from a real publisher's observation — they saw a pattern that works in other shops, mentioned it, and the team validated it. That's the value of building a framework alongside real deployments: the design gets tempered by actual buyer behavior, not just engineering theory. Every chapter in this progression exists because someone hit a real wall and we found a way through.