A Paywall block in the editor
Authors insert a Paywall block and type a price in USDC for that entry. Text above it is the free teaser; everything below is paid. Put it first to paywall the whole entry.
EmDash CMS Early access
Put a whole entry, or just part of one, behind a USDC payment. Authors add one block and set a price. Readers pay with a browser wallet, AI agents pay over x402, and the money settles to your wallet on Base or Solana.
The demo runs on test networks (Base Sepolia, Solana Devnet) with test USDC. No real money moves.
What it does
A native EmDash plugin plus an Astro integration, built for publishers.
Authors insert a Paywall block and type a price in USDC for that entry. Text above it is the free teaser; everything below is paid. Put it first to paywall the whole entry.
An optional End paywall block makes the content after it free again, so you can charge for one section and keep the conclusion open.
Paid blocks are removed before the page renders. They are never hidden with CSS or JavaScript, so view-source and reader mode show only the teaser.
EVM wallets via EIP-6963 (MetaMask, Coinbase Wallet and others) and Solana wallets via Wallet Standard (Phantom and others). Readers only sign; it is gasless for them.
Agents request the page, get a 402 with a PAYMENT-REQUIRED header, and retry with PAYMENT-SIGNATURE. No account and no cookie needed.
Access is granted only after the facilitator confirms the payment settled. Spent payments are recorded in a ledger and rejected if replayed.
For anyone who cannot edit the entry, paid text is also removed from EmDash's own search, content API and MCP responses.
Choose what happens when a known AI crawler requests a paywalled entry: block it, charge it, or treat it like a reader.
Payout wallet (changed only in two confirmed steps), payment service, appearance, access, payments, a health and leak audit, and an audit log.
For authors
No code. Once the site owner has set a payout wallet, pricing a post happens in the editor.
Open an entry in the EmDash editor. Place the cursor where the free part should end.
Pick Paywall from the Monetization group of the block menu and type a price in USDC, for example 0.25. Leave it empty to use the site's default price.
Insert End paywall below the paid part if the rest of the entry should be free again.
Readers see the teaser, a box with the price and an Unlock button, and any free text after End paywall. Once they pay, they see everything in order.
Free introduction ...
[ Paywall 0.25 USDC ]
The paid section ...
[ End paywall ] (optional)
Free conclusion ... Payments
Same page URL, same price, two ways to pay. Access unlocks only after the facilitator confirms settlement.
402 with a PAYMENT-REQUIRED header listing what to pay.PAYMENT-SIGNATURE header.PAYMENT-RESPONSE header. Each request is paid; a re-sent payment is rejected.USDC only, on these networks. No other tokens or chains.
For developers
Register the plugin, edit the template that renders entry bodies, then set your payout wallet in the dashboard.
Early access. @x402-wp/emdash-paywall is being published
to npm shortly. These snippets show the whole setup; join the
early-access list to be told the moment npm install
works.
astro.config.mjs// astro.config.mjs
import node from "@astrojs/node";
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { x402Paywall } from "@x402-wp/emdash-paywall";
const paywall = x402Paywall(); // every option is optional
export default defineConfig({
output: "server",
adapter: node({ mode: "standalone" }),
integrations: [
emdash({
// ...your existing database and storage settings
plugins: [paywall.plugin], // 1. the EmDash plugin
}),
paywall.integration, // 2. the Astro integration
],
}); ---
// src/pages/posts/[slug].astro
import { paywall } from "@x402-wp/emdash-paywall/astro";
import PaywalledContent from "@x402-wp/emdash-paywall/PaywalledContent.astro";
const { entry: post } = await getEmDashEntry("posts", slug);
const gate = await paywall(Astro, { collection: "posts", entry: post });
if (gate.response) return gate.response;
---
<!-- was: <PortableText value={post.data.content} /> -->
<PaywalledContent gate={gate} /> Open Plugins → Paywall settings and set the payout wallet. It becomes active only after a second confirmation step. Until then, paywalled entries stay locked. Test mode and the free x402.org facilitator are the defaults; switch to Coinbase CDP or PayAI when you go live.
If a template is missed, that page fails closed with an error instead of showing paid text.
output: "server"Compared
@emdash-cms/x402EmDash ships its own x402 package: an Astro integration that makes a page request require payment from template code, a good fit for charging agents per request. This plugin uses the same protocol and extends it for publishers: partial paywalls, human wallets, and a dashboard.
| Capability | @emdash-cms/x402 | x402 Paywall for EmDash |
|---|---|---|
| What gets paywalled | The page request, from template code | A whole entry or a section of it, from an editor block |
| Where the price is set | In astro.config (default) or per page in code | Per entry by the author in the editor; site default in the dashboard |
| Who pays | x402 clients such as AI agents, per request | Human readers with a wallet, and AI agents per request |
| Reader wallet UI | Not included | EVM and Solana browser wallets, with mobile wallet-app links |
| Reader access after paying | Each request carries its own payment | Pay once, read for a set period (default 7 days) |
| Configuration | Integration options in astro.config | Settings dashboard in the EmDash admin, with an audit log |
Use one or the other on a given site, not both. Upstream column
describes @emdash-cms/x402 1.0.1.
FAQ
USDC only, on Base and Solana. Base Sepolia and Solana Devnet are available for testing. Test and live networks are never mixed. No other token or chain is supported.
The plugin is free during early access. We take no cut of your payments: USDC settles straight to your wallet. Readers only sign the payment and the facilitator pays the network fee. The x402.org facilitator is free but works on testnets only; for live payments you use Coinbase CDP or PayAI under their own terms.
Yes, one small edit per template that renders an entry body: call the paywall gate at the top and render its content component instead of PortableText. EmDash has no render hook, so the template has to call the gate. If a template is missed, the request fails closed with an error instead of showing paid text.
Yes, for anyone who cannot edit the entry: paywalled entries are dropped from EmDash search results and paid blocks are removed from content API and MCP responses. If your own template calls search() directly, wrap the results with the provided filter helper. Title, excerpt and featured image stay public, so write the excerpt as a teaser.
Yes. The live demo at demodash.x402-wp.com runs on Base Sepolia and Solana Devnet test networks, so payments use test USDC with no real value. Your own site also starts in test mode with the free x402.org facilitator.
EmDash 1.0.1 or later (not 1.0.0), Astro 6 or later with server output, and Node.js 22.16 or later. It is tested with the Astro Node adapter.
Shortly — it is published as @x402-wp/emdash-paywall. Until then it is in early access: try the live demo and join the early-access list to hear the moment it is on npm.
Try the paywall on the testnet demo now, and hear from us when the package is published.
Demo: demodash.x402-wp.com (test networks only)
EmDash is a project of Cloudflare; x402 Paywall is not affiliated with or endorsed by Cloudflare or the EmDash project. x402™ is a trademark of LF Projects, LLC. USDC is a trademark of Circle Internet Group, Inc. Names are used only to describe compatibility.