Skip to content

feat(examples): add subscription paywall (Next.js) example (#354)#360

Open
Ipramking wants to merge 1 commit into
Miracle656:mainfrom
Ipramking:feat/354-subscription-paywall-example
Open

feat(examples): add subscription paywall (Next.js) example (#354)#360
Ipramking wants to merge 1 commit into
Miracle656:mainfrom
Ipramking:feat/354-subscription-paywall-example

Conversation

@Ipramking

Copy link
Copy Markdown
Contributor

Summary

Implements #354 — Subscription paywall (Next.js): a new examples/subscription-paywall/ app demonstrating a recurring on-chain subscription paywall built on invisible-wallet-sdk.

How the subscription works

The subscription is a Soroban token allowance from the user's wallet contract to a merchant address, with an expiry:

Action Call Meaning
Unlock wallet.approve(feePayer, merchant, token, price, expiry) Authorize the merchant to pull up to price until expiry — the recurring payment authorization, confirmed with the user's passkey.
Status get_allowance(merchant, token) (read-only simulation) Subscription is active while the wallet holds a positive, unexpired allowance to the merchant.

Because the status is a read-only simulation it works on the client (useInvisibleWallet().getAllowance) and the server (lib/subscription.ts) alike.

Routes

Route Access Notes
/ Free Landing + passkey wallet creation
/paywall Free On-chain status + Unlock button
/premium Paid Gated by middleware.ts; server component re-verifies from chain
/api/subscription Node route that reads status from chain

middleware.ts matches /premium/:path*, reads the wallet cookie, asks the Node /api/subscription route (which reads the on-chain allowance), and redirects to /paywall when inactive — keeping the Stellar SDK out of the Edge runtime. It fails closed on read errors.

Acceptance criteria

  • Free vs paid routes/ + /paywall open; /premium gated by middleware + a server-side re-check.
  • Subscription status read from chainget_allowance simulated against the wallet contract (server in lib/subscription.ts, client via the SDK).

Verification

Built against a locally-compiled sdk/dist. tsc --noEmit, next lint, and next build all pass (6 routes generated). Follows the conventions of the existing examples/nextjs.

Set NEXT_PUBLIC_MERCHANT_ADDRESS in .env.local to run — see the example README.

Closes #354

@Ipramking Ipramking requested a review from Miracle656 as a code owner June 27, 2026 09:24
@vercel

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

@Ipramking is attempting to deploy a commit to the miracle656's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@Ipramking Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@gitguardian

gitguardian Bot commented Jun 27, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@Ipramking Ipramking force-pushed the feat/354-subscription-paywall-example branch from b6de639 to 5984f1b Compare June 27, 2026 12:43
A recurring on-chain subscription paywall built on invisible-wallet-sdk.

- /paywall "Unlock" creates a recurring payment authorization via
  wallet.approve(merchant, token, price, expiry) — a Soroban allowance with an
  expiry, confirmed with the user's passkey.
- Subscription status is read from chain (get_allowance simulation) both on the
  server (lib/subscription.ts, used by the API route and middleware) and on the
  client.
- Free routes (/ , /paywall) vs paid route (/premium). middleware.ts gates
  /premium on subscription status; the /premium server component re-verifies from
  chain. The Edge middleware stays SDK-free and defers the chain read to a Node
  route handler.

Verified: tsc --noEmit, next lint, and next build all pass.

Closes Miracle656#354
@Ipramking Ipramking force-pushed the feat/354-subscription-paywall-example branch from 5984f1b to 3313e15 Compare June 27, 2026 13:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subscription paywall (Next.js)

1 participant