Introducing IC Paywall: Seamless ICP-Powered Paywalls for Your Web Projects

Hey IC devs,

I’m excited to introduce IC Paywall, a decentralized application built on the Internet Computer Protocol (ICP) that makes it dead simple to monetize your websites, web apps, and vibe-coded projects. Whether you’re building static sites, dynamic dapps, or AI-generated experiences, IC Paywall lets you create configurable paywalls that charge users in ICP before granting access. It’s free to set up, integrates via a single script tag, and handles authentication and enforcement securely using Internet Identity and the ICP ledger.

You can check out the live app here: IC Paywall. The source code is open on GitHub: IC Paywall Repo.

What Makes IC Paywall Innovative?

IC Paywall stands out in the ICP ecosystem by providing a plug-and-play solution for gating content without requiring complex backend changes or third-party services. Here’s why it’s a game-changer:

  • Decentralized and Secure Enforcement: Paywalls use ICP’s Internet Identity for authentication, ensuring users are uniquely identified by their Principal ID (PID). Payments are processed via the ICP ledger, with automatic verification and session management. This prevents bypassing the paywall through simple hacks like disabling JavaScript—enforcement includes tamper detection (e.g., script integrity checks and dev tools monitoring) and periodic backend queries.

  • Flexible Access Durations: Configure how long a payment grants access—from seconds (e.g., for quick demos or contests) to essentially forever (e.g., 36,500 days for lifetime access). This opens up creative monetization models like time-limited “peep shows” or perpetual subscriptions.

  • Multi-Destination Splits with Cycles Conversion: Route payments to up to 3 destinations (Principals or Account IDs), with optional automatic conversion to cycles for topping up canisters. Splits are percentage-based and applied after a small platform fee.

  • Easy Multi-Paywall Support: Integrate multiple paywalls in a single project by adding different script tags to various HTML files or sections. This allows tiered pricing—e.g., free homepage, $0.1 ICP for basic features, $1 ICP for premium content.

  • Vibe-Coding Friendly: Generate a single prompt to integrate the paywall into AI-built apps (e.g., via Caffeine AI). It handles the script embed, CORS setup, and access checks in one pass.

  • Low Friction for Users: Users see a clean overlay prompting login/payment. Once paid, access is granted without page reloads, with a 60-second grace period for propagation.

Technically, it’s powered by a Motoko backend canister handling configs, payments, and access checks, with a React frontend for building paywalls. The embed script (paywall.js) uses @dfinity libraries for agent/actor interactions, ledger transfers, and tamper-proofing.

Technical Details

  • Core Flow: Users create a paywall by setting price (in ICP e8s), target URL (for origin matching), session duration (in nanoseconds), destinations, and optional prompts. The backend generates a unique ID (e.g., “pw-123”). The script tag embeds the paywall logic, which:

    • Checks access via hasAccess(principal, paywallId) query.
    • Handles payments from a user-specific subaccount on the ICP ledger.
    • Enforces via overlay, tamper checks, and interaction disabling.
  • Security Handshake: For manual installs, add a simple frontend check: window.paywallHandshake((hasAccess) => { if (!hasAccess) { /* hide UI or redirect */ } }) before rendering protected content. Re-check every 30 seconds. On the backend (e.g., Motoko), guard queries/updates with if (not (await Paywall.hasAccess(caller, "pw-123"))) { Debug.trap("Access denied"); }. This creates a secure “handshake” between the script and your app, making it harder to bypass than a plain script.

  • Payments: Uses ICRC-1 transfers with a 1% fee (min 0.001 ICP) deducted first. Remaining amount splits across destinations. Supports legacy Account IDs and cycle conversions via CMC (Cycles Minting Canister).

  • Tamper Resistance: The script monitors for dev tools, script modifications, and overlay removal. If detected, it logs to the backend and blocks access.

  • Edge Cases: Handles mobile/desktop differences, grace periods for delays, and periodic re-verification to enforce expirations.

Use Cases

IC Paywall shines for gating ICP-hosted content:

  • Monetize Vibe-Coded Projects: Build an app with AI tools like Caffeine, then add a paywall for instant revenue. Short durations (e.g., 1 minute) work for demos or contests—users pay to “peep” without long-term commitment. Long durations (e.g., 36,500 days ≈ 100 years) offer “lifetime” access, perfect for selling premium tools or games.

  • Website Tiering: Add scripts to different pages for varied pricing—e.g., free landing, 0.1 ICP for blog posts, 1 ICP for downloads. The handshake ensures secure enforcement across sections.

  • Web Apps and Dapps: Gate features in web apps. Use cycle conversion to auto-fund your canisters, keeping them running without manual top-ups.

  • Events and Experiences: Time-box access for virtual events, pay-per-view content, or limited-time challenges.

The script’s lightweight integration means minimal changes to your project files—just add the tag and handshake calls for robust security.

Pricing

  • Free to Create: No cost to build and configure paywalls.
  • Transaction Fee: We take 1% of each payment (min 0.001 ICP) to support development. This is deducted automatically before splits.

Step-by-Step Guide

1. Create a Paywall

  • Sign in with Internet Identity.
  • Set price (ICP), destinations (up to 3, with % splits and optional cycles conversion), target URL (must match your deploy URL), session duration, and prompts.
  • Click “Create paywall” to get your ID and script tag.

2. Integrate into Projects

  • Manual Install (e.g., HTML5 Sites):

    • Copy the script tag (e.g., <script type="module" data-paywall data-backend-id="..." src="https://.../paywall.js?paywallId=pw-123&v=..."></script>) and add it to your <head>.
    • For security, set up the handshake:
      • Frontend: Before rendering protected UI, call window.paywallHandshake((hasAccess) => { if (!hasAccess) { hideUI(); } }). Re-call every 30s.
      • Backend (if using canisters): In Motoko, add if (not (await Paywall.hasAccess(caller, "pw-123"))) { Debug.trap("Access denied"); } to guarded methods.
    • Adjust CORS if needed: Access-Control-Allow-Origin: * (or your origin).
    • Test: Unauthenticated users see overlay → pay → access granted without reload.
  • Vibe-Coded Apps (e.g., Caffeine AI):

    • Generate the prompt from the app (copies to clipboard).
    • Paste into your AI tool—it embeds the script, sets CORS, and adds checks in one pass.
    • Deploy to your target URL.

3. Manage Paywalls

  • View/edit/delete in “My paywalls”.
  • Refresh usage counts to see payments.

Advice and Best Practices

  • Vibe Coding: Integrate after your app’s core functionality is set to avoid conflicts. The prompt usually works in one go, but tweak if errors occur (e.g., CORS issues).
  • Deleting Paywalls: Only delete if replacing immediately or after warning users—they’ll lose any ICP in their paywall account. Give time for withdrawals.
  • Security: Always use the handshake for enforcement—don’t rely on the script alone. Periodically re-verify access to handle expirations.
  • Testing: Use short durations (e.g., 1 minute) to verify blocking post-expiry. Clear localStorage to simulate new users.
  • Cycles Top-Up: Great for keeping dapps alive—route 100% to your canister Principal with conversion enabled.
  • Multiple Paywalls: Use different IDs/scripts for tiered access, but ensure URLs match to avoid origin mismatches.
  • Troubleshooting: If the paywall reappears post-payment, avoid reloads (use grace period). For “disallowed origin,” update CORS and redeploy.

Examples

  • Asteroids 3D: Vibe-coded game charging 0.5 ICP for 100 years (lifetime) access.
  • WAR: HTML5 game with manual script install, charging 0.5004 ICP for 100 years.
  • Car Maintenance Tracker: Vibe-coded app charging 0.0103 ICP for 1-minute access (demo of quick expiry/blocking).

Demo Videos

If you have questions, feedback, or ideas, drop them here! Let’s build more monetized dapps on ICP.

Cheers,
Richard (dickhery)

3 Likes