Community라이팅 & 에디팅github.com

dyegolara/lnurl-auth-agents

LNURL-auth (LUD-04) 서명 도구 — LLM 코딩 에이전트용 '라이트닝으로 로그인' 구현, 라이트닝 지갑 불필요

lnurl-auth-agents란 무엇인가요?

이 도구는 LNURL-auth(LUD-04) 프로토콜을 클라이언트 측에서 완전히 구현한 것으로, LLM 기반 코딩 에이전트(예: Claude Code, Cursor, Codex)가 '라이트닝으로 로그인' 인증을 수행할 수 있게 해줍니다. 서버에서 전송하는 32바이트 k1 챌린지를 secp256k1 개인키로 서명하고, 서명(sig)과 공개키(key)를 콜백 URL에 GET 요청으로 전송하는 방식으로 작동합니다. 인보이스 결제나 라이트닝 노드가 전혀 필요 없으며, 비용이 발생하지 않습니다. Node.js 기반으로 동작하며, @noble/secp256k1과 bech32 패키지를 사용합니다. 기본적으로 도메인별로 파생된 링킹 키를 사용하여 프라이버시를 보호하며, --single-key 옵션으로 모든 서비스에서 동일한 키를 사용할 수도 있습니다.

지원 대상✓Claude Code✓Codex CLI✓Cursor✓OpenCode
npx skills add dyegolara/lnurl-auth-agents

Installed? Explore more 라이팅 & 에디팅 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

lnurl-auth (LUD-04)

LNURL-auth(라이트닝 '라이트닝으로 로그인')을 사용하여 서비스에 인증합니다. 전적으로 클라이언트 측에서 처리됩니다. 이 도구는 인증 전용입니다: 서버가 k1 챌린지를 보내면, 사용자는 secp256k1 개인키로 원시 32바이트 k1에 서명하고 sig + key를 콜백 URL에 GET 파라미터로 전송합니다. 인보이스, 결제, 라이트닝 노드가 필요하지 않습니다.

사용 시점

  • 사이트에 '라이트닝으로 로그인' / LNURL-auth가 표시될 때.
  • lnurl1... 문자열(QR 코드, 링크, 또는 텍스트 붙여넣기)을 전달받았을 때.
  • 비용을 지출하거나 라이트닝 노드를 실행하면 안 되는 경우.

명령어

Node(이미 설치됨)로 실행합니다. 스크립트는 다음 위치에 있습니다:

<skill_dir>/lnurl_auth.js
node <skill_dir>/lnurl_auth.js --lnurl <lnurl1...> [옵션]
# 또는 lnurl을 위치 인자로 전달:
node <skill_dir>/lnurl_auth.js <lnurl1...>

옵션

옵션설명
--lnurl <str>lnurl1... 문자열 (또는 위치 인자로 전달)
--key <hex>이 16진수 개인키를 마스터 시크릿으로 사용
--keyfile <path>파일에서 마스터 시크릿(16진수) 읽기
--keyout <path>생성된 마스터 시크릿을 저장할 위치 (기본값 ~/.config/lnurl-auth/master.key)
--generate새 마스터 시크릿을 강제 생성, 기존 키파일을 덮어씀
--single-key모든 서비스에 하나의 전역 링킹 키 사용 (도메인별 파생 없음)
--no-t호환성 옵션; 콜백에 t 파라미터를 추가하지 않음
--action <a>action 강제 지정: register, login, link, 또는 auth
--callback <url>서명을 제출할 URL 재정의
--dry-run디코딩, k1 가져오기, 서명 — 하지만 콜백을 보내지 않음
--json기계가 읽을 수 있는 JSON 출력
-v, --verbose상세 로깅
-q, --quiet진행 로그 억제
-h, --help도움말 표시

키 관리 (기본값, 프라이버시 보호)

  • 처음 사용 시 32바이트 마스터 시크릿이 생성되어 ~/.config/lnurl-auth/master.key에 저장됩니다 (모드 0600).
  • 각 서비스에 대해 링킹 키가 결정론적으로 파생됩니다: linkingPriv = HMAC-SHA256(master, serviceDomain).
  • 같은 서비스 → 같은 키 (재방문 사용자). 다른 서비스 → 다른 키 (프라이버시 — LUD-05/LUD-13 정신).
  • 모든 서비스에 단일 전역 링킹 키를 사용하려면 --single-key를 사용하세요.

프로토콜 흐름 (LUD-04)

  1. lnurl1...은 bech32("lnurl", utf8(serviceURL))입니다. 디코딩 → k1(32바이트 16진수 챌린지)과 선택적으로 action을 포함하는 URL이 생성됩니다.
  2. ECDSA(secp256k1, prehash: false)를 사용하여 링킹 개인키로 원시 32바이트 k1 에 서명한 다음, 서명을 DER 인코딩합니다.
  3. 기존 쿼리 파라미터를 유지하면서 &sig=<16진수 DER 서명>&key=<16진수 압축 공개키>를 추가하여 서비스 URL에 GET 요청을 보냅니다.
  4. 서버가 서명을 확인하고 {"status":"OK"} 또는 {"status":"ERROR","reason":"..."}로 응답합니다.

참고: https://github.com/lnurl/luds/blob/luds/04.md

출력

  • 진행 메시지는 stderr로 전송됩니다.
  • 서버 응답(JSON)은 stdout으로 전송됩니다.
  • {"status":"OK"} → 종료 코드 0.
  • {"status":"ERROR",...} → 종료 코드 3.
  • JSON이 아니거나 200이 아닌 응답 → 종료 코드 4.

예제

기본 로그인

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

드라이 런 먼저 (제출하지 않고 검사)

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

특정 키 사용

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

새 신원 강제 생성

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

의존성

  • Node.js v20.19+ (v22 권장).
  • 두 개의 작은 순수 JS npm 패키지가 node_modules/ 내부에 vendor되어 있습니다:
    • @noble/secp256k1 (서명/검증, 작고, 의존성 없음)
    • bech32 (lnurl 디코딩/인코딩)
  • 네이티브 빌드 없음; 네트워크 호출은 선택적인 챌린지 GET과 최종 콜백 GET으로 제한됩니다.
  • 비용 없음, 라이트닝 노드 없음.

Vendor 의존성 설치/갱신

cd <skill_dir>
npm install

자체 테스트 (외부 서비스 없음, 비용 없음)

로컬 모의 LUD-04 서버가 전체 서명 → 제출 → 검증 왕복을 검증합니다:

cd <skill_dir>
npm test

다음 항목을 포함합니다: 정상 경로, 재전송 거부, 드라이 런 안전성, 변조된 k1 거부, 도메인별 키 안정성, --generate 덮어쓰기, 홀수 16진수 유효성 검사.

실제 검증

두 개의 공개 서비스에서 검증되었습니다:

서비스응답
bitsimp.com{"status":"OK"}
lightninglogin.live{"status":"OK"}

제한 사항

  • 이 도구는 암호학적 핸드셰이크를 수행합니다. 계정 생성/로그인은 원격 서비스가 키를 인식하는지에 따라 달라집니다.
  • 기본 링킹 키는 로컬 마스터 시크릿에서 도메인별로 파생됩니다. 사용자의 휴대폰 지갑이 생성하는 동일한 신원이 아닙니다. 에이전트 인증에는 충분합니다.
  • 선택적인 챌린지 GET 및 최종 콜백 GET을 위해 네트워크 아웃바운드가 필요합니다 (결제 또는 라이트닝 노드 없음).

관련 스킬