Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lens-ucashpay

Let Lens Protocol profiles receive U.CASH Pay links (tip / collect). Non-custodial.

This is a small Next.js app that, given a Lens profile handle, resolves the profile and renders a Pay-with-U.CASH button. Clicking it opens a hosted U.CASH checkout prefilled with the profile as the title and the Lens profileId/handle as the external_reference. Funds always settle to the creator's own receive addresses configured in their pay.u.cash store.

The store Cloud Token is publishable: it is safe to embed in the browser/app and does not give anyone custody of funds. No keys, no signing, no custodial rails.

What you get

  • app/page.js - resolve a Lens handle (public Lens API) and show a U.CASH tip button.
  • components/UcashTipButton.js - the reusable Pay button + modal checkout (client-side hosted link).
  • app/embed/route.js - optional server-side tracked checkout (idempotent per external_reference).
  • lib/ucashpay.js - the pay.u.cash contract in one place (buildEmbedUrl, createTrackedCheckout).
  • public/embed.example.html - a zero-dependency static page showing the hosted pay link.

Quick start

# 1. Install
npm install

# 2. Set your publishable store Cloud Token (see "Set up your pay.u.cash account" below)
export NEXT_PUBLIC_UCASH_CLOUD_TOKEN=your_store_cloud_token_here

# 3. Run
npm run dev
# open http://localhost:3000

Enter a Lens handle (e.g. lens/stani), pick an amount, and click Tip with U.CASH.

Usage

Client-side hosted pay link (recommended for embeds)

The simplest path. Build a hosted link with the publishable Cloud Token and open it in a tab or iframe. No server needed:

import { buildEmbedUrl } from "@/lib/ucashpay";

const url = buildEmbedUrl({
  cloud: "YOUR_STORE_CLOUD_TOKEN", // publishable, non-custodial
  amount: "1",
  currency: "USD",
  title: "Tip lens/stani",
  external_reference: "lens:stani",
  redirect: "https://your-app.example/thanks",
});
window.open(url, "_blank", "noopener");

Contract:

GET https://pay.u.cash/embed.php
  ?cloud=<store cloud token>
  &amount=<amount>
  &currency=USD
  &title=<title>
  &external_reference=<optional ref>
  &redirect=<optional redirect url>

Reusable button component

<UcashTipButton
  cloud={process.env.NEXT_PUBLIC_UCASH_CLOUD_TOKEN}
  lensProfile={{ handle: "stani", profileId: "0x...", displayName: "Stani" }}
  amount="1"
  currency="USD"
/>

Server-side tracked checkout

When you want a tracked transaction (e.g. a "collect" action behind a login), call the server route. It posts to https://pay.u.cash/payment/ajax.php with function=create-transaction and idempotent=1, so repeated requests for the same external_reference return the same payment URL rather than creating duplicates.

curl "http://localhost:3000/embed?cloud=YOUR_STORE_CLOUD_TOKEN&handle=stani&amount=1&currency=USD"
# -> { "success": true, "paymentUrl": "https://pay.u.cash/...", "transactionId": "...", ... }

The route also accepts POST with a JSON body. You may instead set UCASH_CLOUD_TOKEN (server env) so callers never need to pass the token at all.

Response handling: the pay.u.cash response is { success: true, response: [paymentUrl, transactionId, ...] }. The payment URL is the array element that starts with http(s)://.

Lens SDK note

Profile resolution in app/page.js uses the public Lens GraphQL API (https://api.lens.dev/graphql) for a read-only lookup of the profile's handle, id, and metadata.displayName. No wallet, no signing, no collect module interaction happens here, which keeps the flow non-custodial.

For richer integrations (collecting a Lens post, session-based profile context, or interacting with Lens publications), use the official Lens SDK (@lens-protocol/react-web + @lens-protocol/client) or the Lens React Native SDK. Those packages give you authenticated sessions and typed access to publications, follow modules, and collect/open-action modules. They are optional for this starter, which intentionally stays dependency-light so the pay link works anywhere a link can be opened.

Install if you want them:

npm install @lens-protocol/react-web @lens-protocol/client viem

Set up your pay.u.cash account

  1. Sign up at pay.u.cash, then click the verification link in the email.
  2. Set receive addresses under Settings -> Addresses (raw address, ENS, Unstoppable Domains, or FIO).
  3. Create a store under Account -> Stores and copy its Store Cloud Token (use the store-level token, not the account-wide one).
  4. For fiat cards, connect your own Stripe under Settings -> Payment processors.

Environment variables

Variable Where Purpose
NEXT_PUBLIC_UCASH_CLOUD_TOKEN client Publishable store Cloud Token for the hosted embed button.
UCASH_CLOUD_TOKEN server only Optional: lets the /embed route own the token so callers don't pass it.

Limitations

  • Recurring crypto billing is not automatic. pay.u.cash checkouts are one-time payments; there is no on-chain recurring crypto subscription. Recurring revenue needs a membership/collect schedule on your side that opens a fresh one-time pay link each cycle.
  • This app never holds funds or keys. The Cloud Token is publishable and only authorizes creating checkouts that pay to the merchant's configured receive addresses.

Build and deploy

npm run build
npm start           # production server
# or deploy on Vercel / any Node host; set the env vars in the host dashboard.

Publish (npm) - optional

This repo is an app, not a published package. If you extract lib/ucashpay.js into a library later:

npm login
npm version patch
npm publish --access public

License

MIT - see LICENSE.

About

Let Lens Protocol profiles receive U.CASH Pay links (tip / collect). Non-custodial.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages