CommunityRédaction et éditiongithub.com

dyegolara/lnurl-auth-agents

Signataire LNURL-auth (LUD-04) pour agents de codage LLM — Connexion avec Lightning, sans portefeuille nécessaire

Qu'est-ce que lnurl-auth-agents ?

Cette compétence implémente le protocole LNURL-auth (LUD-04) côté client, permettant à un agent d'IA de s'authentifier auprès d'un service utilisant "Sign in with Lightning", sans avoir besoin d'un portefeuille Lightning ni d'un nœud. L'agent reçoit une chaîne `lnurl1...`, la décode, récupère le défi `k1` du serveur, le signe avec une clé privée secp256k1, puis soumet la signature via une requête GET au callback. Elle gère automatiquement la génération et la persistance d'un secret maître, la dérivation par domaine de clés de liaison (préservation de la vie privée), et la création optionnelle d'une clé globale unique via `--single-key`. Destinée à des agents de codage comme Claude Code, Cursor, ou Codex, elle s'exécute avec Node.js (sans dépendances natives) et inclut un test automatisé complet sans services externes.

Compatible avec✓Claude Code✓Codex CLI✓Cursor✓OpenCode
npx skills add dyegolara/lnurl-auth-agents

Installed? Explore more Rédaction et édition skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

lnurl-auth (LUD-04)

Authentifiez-vous à un service en utilisant LNURL-auth (Lightning "Connexion avec Lightning") entièrement côté client. Ceci est uniquement de l'authentification : le serveur envoie un défi k1, vous signez le k1 brut de 32 octets avec une clé privée secp256k1 et retournez sig + key via une requête GET au callback. Pas de facture, pas de paiement, pas de nœud Lightning.

Quand l'utiliser

  • Un site affiche "Connexion avec Lightning" / LNURL-auth.
  • On vous donne une chaîne lnurl1... (depuis un QR code, un lien, ou du texte collé).
  • Vous ne devez PAS dépenser d'argent ni exécuter un nœud Lightning.

Commande

Exécutez avec Node (déjà installé). Le script se trouve à :

<skill_dir>/lnurl_auth.js
node <skill_dir>/lnurl_auth.js --lnurl <lnurl1...> [options]
# ou passez le lnurl en position :
node <skill_dir>/lnurl_auth.js <lnurl1...>

Options

OptionDescription
--lnurl <str>La chaîne lnurl1... (ou passez-la en position)
--key <hex>Utilisez cette clé privée hexadécimale comme secret maître
--keyfile <path>Lisez le secret maître (hex) depuis un fichier
--keyout <path>Où persister un secret maître généré (par défaut ~/.config/lnurl-auth/master.key)
--generateForcer la génération d'un nouveau secret maître, écrasant tout fichier de clé existant
--single-keyUtiliser une seule clé de liaison globale pour tous les services (pas de dérivation par domaine)
--no-tOption de compatibilité ; le callback n'ajoute pas de paramètre t
--action <a>Affirmer/remplacer l'action : register, login, link, ou auth
--callback <url>Remplacer l'URL à laquelle la signature est soumise
--dry-runDécoder, récupérer k1, signer — mais ne pas soumettre le callback
--jsonÉmettre du JSON lisible par machine
-v, --verboseJournalisation verbeuse
-q, --quietSupprimer les journaux de progression
-h, --helpAfficher l'aide

Gestion des clés (par défaut, respectueuse de la vie privée)

  • Lors de la première utilisation, un secret maître de 32 octets est généré et sauvegardé dans ~/.config/lnurl-auth/master.key (mode 0600).
  • Pour chaque service, une clé de liaison est dérivée de manière déterministe : linkingPriv = HMAC-SHA256(master, serviceDomain).
  • Même service → même clé (utilisateur connu). Services différents → clés différentes (vie privée — dans l'esprit de LUD-05/LUD-13).
  • Utilisez --single-key pour une seule clé de liaison globale pour tous les services.

Déroulement du protocole (LUD-04)

  1. lnurl1... est bech32("lnurl", utf8(serviceURL)). Décoder -> URL contenant k1 (défi hexadécimal de 32 octets) et éventuellement action.
  2. Signer le k1 brut de 32 octets avec la clé privée de liaison en utilisant ECDSA (secp256k1, prehash: false), puis encoder en DER la signature.
  3. GET l'URL du service avec &sig=<sig DER hex>&key=<clé publique compressée hex> ajouté tout en préservant les paramètres de requête existants.
  4. Le serveur vérifie la signature et répond {"status":"OK"} ou {"status":"ERROR","reason":"..."}.

Référence : https://github.com/lnurl/luds/blob/luds/04.md

Sortie

  • Les messages de progression vont vers stderr.
  • La réponse du serveur (JSON) va vers stdout.
  • {"status":"OK"} → code de sortie 0.
  • {"status":"ERROR",...} → code de sortie 3.
  • Réponse non JSON ou non 200 → code de sortie 4.

Exemples

Connexion de base

node <skill_dir>/lnurl_auth.js --lnurl "lnurl1dp68gurn8ghj7..."

Test à sec d'abord (inspecter sans soumettre)

node <skill_dir>/lnurl_auth.js "lnurl1..." --dry-run --json

Utiliser une clé spécifique

node <skill_dir>/lnurl_auth.js "lnurl1..." --key <64-char-hex-private-key>

Forcer une nouvelle identité

node <skill_dir>/lnurl_auth.js "lnurl1..." --generate

Dépendances

  • Node.js v20.19+ (v22 recommandée).
  • Deux petits paquets npm pur JS, vendus dans node_modules/ :
    • @noble/secp256k1 (signer/vérifier, petit, zéro dépendance)
    • bech32 (décoder/encoder lnurl)
  • Pas de build natif ; les appels réseau sont limités au GET optionnel du défi et au GET final du callback.
  • Aucun coût, aucun nœud Lightning.

Installation / rafraîchissement des dépendances vendues

cd <skill_dir>
npm install

Auto-test (aucun service externe, aucun coût)

Un serveur LUD-04 simulé local valide le cycle complet signer → soumettre → vérifier :

cd <skill_dir>
npm test

Couvre : chemin nominal, rejet de rejeu, sécurité du dry-run, rejet de k1 modifié, stabilité de la clé par domaine, écrasement --generate, et validation des hex impairs.

Vérification réelle

Vérifié contre deux services publics :

ServiceRéponse
bitsimp.com{"status":"OK"}
lightninglogin.live{"status":"OK"}

Limitations

  • Cela effectue la poignée de main cryptographique ; la création de compte/connexion dépend de la reconnaissance de la clé par le service distant.
  • La clé de liaison par défaut est dérivée par domaine à partir d'un secret maître local — ce n'est pas la même identité que produirait le portefeuille téléphonique d'un utilisateur. Suffisant pour l'authentification d'un agent.
  • Nécessite une sortie réseau pour le GET optionnel du défi et le GET final du callback (pas de paiement, pas de nœud Lightning).

Skills associés