Skip to main content

▶ Voir le flux 402 en premier

Démo de terminal interactif — observez requête → 402 → paiement Lightning → 200 OK, en direct dans votre navigateur.

Option A — Créer un serveur complet en une seule commande (le plus rapide)

npx create-l402-app my-api
Cela crée un projet Express + l402-kit complet : server.ts, .env.example, tsconfig.json, et un endpoint /premium prêt à accepter les paiements Lightning.
my-api/
  src/server.ts      ← votre API avec le middleware l402
  .env.example       ← modèle de credentials Blink/OpenNode
  package.json       ← npm install l402-kit + tsx
  tsconfig.json
  README.md
Ensuite :
cd my-api
cp .env.example .env   # ajoutez votre clé API Blink
npm install
npm run dev
# ⚡ l402-kit server running on http://localhost:3000
# curl http://localhost:3000/premium  →  402 Payment Required

Option B — Ajouter à un projet existant

1. Choisissez votre mode

ManagedSoberano
Temps de configuration~2 min~5 min
Coût mensuel0 $0 $
Frais par transaction0,3 %0 %
Ce dont vous avez besoinUne adresse LightningUn compte Blink / Alby / BTCPay
Traitement de 10 000 sats30 sat de frais0 $ de frais
Idéal pourDémarrer rapidementVolume / production
Pas sûr ? Commencez avec Managed — pas de nœud, pas de compte, juste une adresse Lightning. Passez à Soberano en une ligne de code dès que vous souhaitez des frais à 0 %. Les tokens déjà payés continuent de fonctionner après le changement. Obtenez une adresse Lightning (gratuit, 2 min) : Inscrivez-vous sur dashboard.blink.sv — vous recevrez yourname@blink.sv. Ou utilisez Alby, Phoenix, ou Wallet of Satoshi. Configuration Soberano : Inscrivez-vous sur dashboard.blink.svAPI Keys → créez une clé → copiez votre BTC Wallet ID depuis la page du portefeuille. Définissez BLINK_API_KEY et BLINK_WALLET_ID dans votre .env.

2. Installer

npm install l402-kit

3. Ajouter à votre API

Aucun nœud Lightning nécessaire — juste votre adresse Lightning.
import express from "express";
import { l402, ManagedProvider } from "l402-kit";

const app = express();
const lightning = ManagedProvider.fromAddress("you@yourdomain.com");

app.get("/premium", l402({ priceSats: 100, lightning }), (_req, res) => {
  res.json({ data: "You paid 100 sats. Here is your data." });
});

app.listen(3000);
// 0.3% fee · no node setup · works immediately

4. Tester

curl http://localhost:3000/premium
Réponse :
{
  "error": "Payment Required",
  "price_sats": 100,
  "invoice": "lnbc1u1p...",
  "macaroon": "eyJoYXNo..."
}
Payez la facture avec n’importe quel portefeuille Lightning, puis :
curl http://localhost:3000/premium \
  -H "Authorization: L402 <macaroon>:<preimage>"
Réponse :
{ "data": "You paid 100 sats. Here is your data." }
Votre API accepte désormais les paiements en Bitcoin.

Tester sans vrais sats

Vous n’avez pas besoin d’un portefeuille Lightning pour tester votre intégration. Utilisez un fournisseur mock — il génère des paires de tokens cryptographiques valides localement, sans aucun appel réseau :
import { createHash, randomBytes } from "crypto";
import { l402 } from "l402-kit";
import type { LightningProvider, Invoice } from "l402-kit";

// Drop-in mock — generates real SHA256 hash/preimage pairs
function makeMockProvider(): LightningProvider & { preimage: string } {
  const preimage = randomBytes(32).toString("hex");
  const paymentHash = createHash("sha256").update(Buffer.from(preimage, "hex")).digest("hex");
  return {
    preimage, // use this in your test Authorization header
    async createInvoice(amountSats: number): Promise<Invoice> {
      const macaroon = Buffer.from(
        JSON.stringify({ hash: paymentHash, exp: Date.now() + 3_600_000 })
      ).toString("base64");
      return { paymentRequest: "lnbc_mock", paymentHash, macaroon, amountSats };
    },
    async checkPayment(): Promise<boolean> { return true; },
  };
}

// Usage in tests:
const mock = makeMockProvider();
app.get("/premium", l402({ priceSats: 10, lightning: mock }), handler);

// Step 1 — unauthenticated → 402
const res402 = await request(app).get("/premium");
// res402.body.macaroon  ← use this

// Step 2 — pay with mock preimage → 200
const res200 = await request(app)
  .get("/premium")
  .set("Authorization", `L402 ${res402.body.macaroon}:${mock.preimage}`);
// res200.status === 200 ✓
Pour des tests avec de l’argent réel en bac à sable, utilisez le mode test d’OpenNode :
const lightning = new OpenNodeProvider(process.env.OPENNODE_KEY!, true); // testMode: no real sats
Guide de test complet → Testing