Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lightning-ucashpay

Use U.CASH Pay like Lightning: LNURL-pay / Lightning Address style. Non-custodial.

lightning-ucashpay is a small JavaScript/TypeScript-ready helper that wraps the U.CASH Pay checkout engine in the ergonomics of Lightning Network payments. You get two Lightning-flavored patterns on top of a multi-currency, non-custodial payment rail:

  • LNURL-pay-style: an endpoint that resolves a pay request into a payable URL (the U.CASH hosted checkout), which a wallet or app can open or embed.
  • Lightning-Address-style: resolve a human handle (alice@ucash) into a U.CASH checkout link, exactly the way a Lightning Address resolves to an invoice.

Settlement is non-custodial: the payer pays directly to the merchant's configured wallets. The store Cloud Token used here is a publishable client-side credential (like a Lightning node public key or a published LNURL-pay URL), so it is safe to embed in a browser, an edge worker, or a public .well-known handler.

Install

Published as an npm package. Once published:

npm install lightning-ucashpay
# or
pnpm add lightning-ucashpay
# or
yarn add lightning-ucashpay

ESM:

import { buildEmbedUrl, createServerCheckout } from "lightning-ucashpay";

CommonJS:

const { buildEmbedUrl, createServerCheckout } = require("lightning-ucashpay");

Quick start

1. Client-side checkout link (browser, no secret)

This builds a hosted U.CASH checkout URL straight from the publishable Cloud Token. Use it for "Pay" buttons, QR codes, or href links.

import { buildEmbedUrl } from "lightning-ucashpay";

const url = buildEmbedUrl({
  cloud: "st_your_store_cloud_token", // publishable
  amount: 5,
  currency: "USD",
  title: "Coffee",
  externalReference: "order_123", // idempotency / order ref
  redirect: "https://shop.example.com/thanks",
});
// -> https://pay.u.cash/embed.php?cloud=st_...&amount=5&currency=USD&...

window.location.href = url; // or render a link/QR

2. Lightning-Address-style handle resolution

Resolve a human handle into a checkout URL. You keep a map of handle -> store Cloud Token (just like a Lightning Address service keeps a map of handle -> node

  • preimage database).
import { resolveAddress } from "lightning-ucashpay";

const url = resolveAddress("alice@ucash", {
  cloudToken: "st_alice_store_token", // publishable
  amount: 2,
  currency: "USD",
});

3. Server-tracked checkout (capture a transaction id)

For a tracked checkout (idempotent per external_reference), call the server-side helper from a route you control. The Cloud Token is still publishable; using a server route just lets you capture the transactionId and store the paymentUrl on your own order record.

import { createServerCheckout } from "lightning-ucashpay";

const { success, paymentUrl, transactionId } = await createServerCheckout({
  cloud: "st_your_store_cloud_token",
  amount: 5,
  currencyCode: "USD",
  cryptocurrencyCode: "", // empty = payer chooses on checkout
  externalReference: "order_123", // idempotency key
  title: "Coffee",
  redirect: "https://shop.example.com/thanks",
});

if (success) {
  console.log(paymentUrl, transactionId);
}

4. LNURL-pay-resolvable handler

examples/server.mjs is a minimal HTTP server that exposes GET /.well-known/lnurlp/:user, returning LNURL-pay-shaped JSON whose payUrl is a U.CASH checkout. Point a Lightning-Address-style wallet at it.

UCASH_TOKENS='{"alice":"st_alice_token"}' PORT=8787 node examples/server.mjs
GET http://localhost:8787/.well-known/lnurlp/alice
GET http://localhost:8787/pay/alice?amount=5&currency=USD   # 302 -> U.CASH checkout

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.

API

buildEmbedUrl(params) / buildCheckoutUrl(params)

Build a hosted U.CASH checkout URL from the publishable Cloud Token. Browser-safe.

Param Type Required Notes
cloud string yes Publishable store Cloud Token
amount string/number no Omit to let the payer enter it
currency string no Default USD
title string no Title on the checkout page
externalReference string no Order id / idempotency ref
redirect string no Post-payment redirect URL

createServerCheckout(params, fetchImpl?) / createInvoice(...)

Create a server-tracked checkout. Idempotent per externalReference. Returns { success, paymentUrl, transactionId, raw }.

Param Type Required Notes
cloud string yes Publishable store Cloud Token
amount string/number yes Amount
currencyCode string no Default USD
cryptocurrencyCode string no Default "" (payer chooses)
externalReference string no Idempotency key
title string no Title on the checkout page
redirect string no Post-payment redirect URL

Requires a global fetch (Node >= 18). On older runtimes, pass a fetchImpl.

lnurlPayResponse({ payUrl, amount, currency, description, commentAllowed })

Build an LNURL-pay-style callback body you can serve from your own handler. The U.CASH checkout URL is surfaced as payUrl (plus Lightning-compatible metadata).

resolveAddress(handle, opts)

Lightning-Address-style resolution. opts.cloudToken (publishable) is required.

U.CASH Pay vs Lightning

The mental model is intentionally Lightning-shaped, but the two systems differ in important ways. Here is an honest comparison.

Concept Lightning Network U.CASH Pay (this lib)
Payable credential Node public key / LNURL-pay URL Publishable Store Cloud Token
Who you pay A node (via channels / invoices) The merchant's configured wallets directly
Custody Depends on wallet (often custodial) Non-custodial: funds go to merchant
Address style user@domain (Lightning Address) user@ucash via this lib (same UX)
Pay-request shape LNURL-pay JSON -> BOLT11 invoice Handler JSON -> U.CASH checkout URL
The "invoice" A BOLT11 BOLT11 string A hosted pay.u.cash/embed.php URL
Currencies BTC (sats) over Lightning Multi-currency: BTC, ETH, USDC, stablecoins
Fiat rails Indirect (third-party) Native via the merchant's own Stripe
Recurring / streaming Native (keysend, subscriptions) Per-checkout (use externalReference for refs)
Settlement speed Instant (L2) On-chain speed of the chosen asset
Server secret required? Often yes (preimage / node macaroon) No for the client-side embed URL

What maps cleanly

  • Handle -> URL resolution (Lightning Address -> resolveAddress).
  • Pay-request -> payable artifact (LNURL-pay -> lnurlPayResponse).
  • Publishable credential (node public key / LNURL URL -> store Cloud Token).
  • Non-custodial receiver (the merchant always self-custodies).

What is different (documented honestly)

  • The "invoice" is a checkout URL, not a BOLT11 string. A Lightning-only wallet cannot parse it directly; a U.CASH-aware wallet (or any browser) opens it. That is why lnurlPayResponse carries both the Lightning-style metadata and a U.CASH-specific payUrl.
  • U.CASH is multi-currency. amount is paired with a currency (USD, BTC, ETH, USDC, ...), unlike Lightning's sats-only model.
  • There is no native L2 streaming/keysend here. Recurring payments are modeled per-checkout, keyed by externalReference for reconciliation.
  • Settlement speed equals the on-chain (or L1) speed of the asset the payer picks, not Lightning-instant.

Publish

This repository is the source of the lightning-ucashpay npm package. To publish a new version (maintainers only):

npm version patch   # or minor / major
npm publish

(Do not publish from this repo's CI without the maintainer npm token.)

License

MIT - (c) 2026 U.CASH

About

Use U.CASH Pay like Lightning (LNURL-pay / Lightning Address style). Non-custodial.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages