import "./Login.css"; import { CSSProperties, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useNavigate } from "react-router-dom"; import * as secp from "@noble/secp256k1"; import { useIntl, FormattedMessage } from "react-intl"; import { RootState } from "State/Store"; import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login"; import { DefaultRelays, EmailRegex, MnemonicRegex } from "Const"; import { bech32ToHex, generateBip39Entropy, entropyToDerivedKey, unwrap } from "Util"; import { HexKey } from "@snort/nostr"; import ZapButton from "Element/ZapButton"; // import useImgProxy from "Feed/ImgProxy"; import messages from "./messages"; interface ArtworkEntry { name: string; pubkey: HexKey; link: string; } // todo: fill more const Artwork: Array = [ { name: "", pubkey: bech32ToHex("npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac"), link: "https://void.cat/d/VKhPayp9ekeXYZGzAL9CxP", }, { name: "", pubkey: bech32ToHex("npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac"), link: "https://void.cat/d/3H2h8xxc3aEN6EVeobd8tw", }, { name: "", pubkey: bech32ToHex("npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac"), link: "https://void.cat/d/7i9W9PXn3TV86C4RUefNC9", }, { name: "", pubkey: bech32ToHex("npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac"), link: "https://void.cat/d/KtoX4ei6RYHY7HESg3Ve3k", }, ]; export async function getNip05PubKey(addr: string): Promise { const [username, domain] = addr.split("@"); const rsp = await fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(username)}`); if (rsp.ok) { const data = await rsp.json(); const pKey = data.names[username]; if (pKey) { return pKey; } } throw new Error("User key not found"); } export default function LoginPage() { const dispatch = useDispatch(); const navigate = useNavigate(); const publicKey = useSelector(s => s.login.publicKey); const [key, setKey] = useState(""); const [error, setError] = useState(""); const [art, setArt] = useState(); const { formatMessage } = useIntl(); //const { proxy } = useImgProxy(); useEffect(() => { if (publicKey) { navigate("/"); } }, [publicKey, navigate]); useEffect(() => { const ret = unwrap(Artwork.at(Artwork.length * Math.random())); // disable for now because imgproxy is ded // proxy(ret.link).then(a => setArt({ ...ret, link: a })); setArt(ret); }, []); async function doLogin() { try { if (key.startsWith("nsec")) { const hexKey = bech32ToHex(key); if (secp.utils.isValidPrivateKey(hexKey)) { dispatch(setPrivateKey(hexKey)); } else { throw new Error("INVALID PRIVATE KEY"); } } else if (key.startsWith("npub")) { const hexKey = bech32ToHex(key); dispatch(setPublicKey(hexKey)); } else if (key.match(EmailRegex)) { const hexKey = await getNip05PubKey(key); dispatch(setPublicKey(hexKey)); } else if (key.match(MnemonicRegex)) { const ent = generateBip39Entropy(key); const keyHex = entropyToDerivedKey(ent); dispatch(setPrivateKey(keyHex)); } else if (secp.utils.isValidPrivateKey(key)) { dispatch(setPrivateKey(key)); } else { throw new Error("INVALID PRIVATE KEY"); } } catch (e) { setError(`Failed to load NIP-05 pub key (${e})`); console.error(e); } } async function makeRandomKey() { const ent = generateBip39Entropy(); const entHex = secp.utils.bytesToHex(ent); const newKeyHex = entropyToDerivedKey(ent); dispatch(setGeneratedPrivateKey({ key: newKeyHex, entropy: entHex })); navigate("/new"); } async function doNip07Login() { const pubKey = await window.nostr.getPublicKey(); dispatch(setPublicKey(pubKey)); if ("getRelays" in window.nostr) { const relays = await window.nostr.getRelays(); dispatch( setRelays({ relays: { ...relays, ...Object.fromEntries(DefaultRelays.entries()), }, createdAt: 1, }) ); } } function altLogins() { const nip07 = "nostr" in window; if (!nip07) { return null; } return ( ); } return (
navigate("/")}> Snort

setKey(e.target.value)} />
{error.length > 0 ? {error} : null}

{/* */}
{altLogins()}

Karnage, }} />
); }