Add public key (npub) login support

- Backend: POST /auth/login-npub endpoint, JWT carries login method
- Backend: Enforce Lightning address lock for npub logins in claim/quote
- Frontend: LoginModal supports npub via new endpoint, clear copy
- Frontend: Track loginMethod, lock LN address editing for npub users
- Handle missing Lightning address for npub users with helpful message

Made-with: Cursor
This commit is contained in:
Michaël
2026-02-27 17:56:15 -03:00
parent 5b516f02cb
commit 9fff2d427f
12 changed files with 127 additions and 44 deletions
+13 -3
View File
@@ -1,6 +1,6 @@
import { useState, useEffect, useCallback } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { getToken, getAuthMe, clearToken } from "./api";
import { getToken, getAuthMe, clearToken, type LoginMethod } from "./api";
import { Header } from "./components/Header";
import { Footer } from "./components/Footer";
import { ClaimWizard } from "./components/ClaimWizard";
@@ -26,19 +26,29 @@ const FaucetSvg = () => (
export default function App() {
const [pubkey, setPubkey] = useState<string | null>(null);
const [loginMethod, setLoginMethod] = useState<LoginMethod | null>(null);
const [statsRefetchTrigger, setStatsRefetchTrigger] = useState(0);
useEffect(() => {
const token = getToken();
if (!token) return;
getAuthMe()
.then((r) => setPubkey(r.pubkey))
.then((r) => {
setPubkey(r.pubkey);
setLoginMethod(r.method ?? "nip98");
})
.catch(() => {
clearToken();
setPubkey(null);
setLoginMethod(null);
});
}, []);
const handlePubkeyChange = useCallback((pk: string | null, method?: LoginMethod) => {
setPubkey(pk);
setLoginMethod(pk ? (method ?? "nip98") : null);
}, []);
const handleClaimSuccess = useCallback(() => {
setStatsRefetchTrigger((t) => t + 1);
}, []);
@@ -74,7 +84,7 @@ export default function App() {
<FaucetSvg />
<h1>Sats Faucet</h1>
</div>
<ClaimWizard pubkey={pubkey} onPubkeyChange={setPubkey} onClaimSuccess={handleClaimSuccess} />
<ClaimWizard pubkey={pubkey} loginMethod={loginMethod} onPubkeyChange={handlePubkeyChange} onClaimSuccess={handleClaimSuccess} />
</main>
<aside className="sidebar sidebar-right">
<StatsSection refetchTrigger={statsRefetchTrigger} />