Compare commits

...

4 Commits

Author SHA1 Message Date
tiero
5244bf647f
remove react-qr-code 2023-02-20 18:53:03 +01:00
tiero
07588eaf32
use QrCode component 2023-02-20 18:52:26 +01:00
tiero
4e3f9eaafd
modal layout 2023-02-20 18:36:32 +01:00
tiero
f56164e809
add nip46 2023-02-20 04:01:05 +01:00
3 changed files with 134 additions and 8 deletions

View File

@ -9,8 +9,10 @@
"@jukben/emoji-search": "^2.0.1",
"@noble/hashes": "^1.2.0",
"@noble/secp256k1": "^1.7.0",
"@nostr-connect/connect": "^0.2.3",
"@protobufjs/base64": "^1.1.2",
"@reduxjs/toolkit": "^1.9.1",
"@snort/nostr": "^1.0.0",
"@szhsin/react-menu": "^3.3.1",
"@types/jest": "^29.2.5",
"@types/node": "^18.11.18",
@ -49,8 +51,7 @@
"workbox-range-requests": "^6.4.2",
"workbox-routing": "^6.4.2",
"workbox-strategies": "^6.4.2",
"workbox-streams": "^6.4.2",
"@snort/nostr": "^1.0.0"
"workbox-streams": "^6.4.2"
},
"scripts": {
"start": "react-app-rewired start",

View File

@ -5,6 +5,8 @@ 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 { Connect, ConnectURI } from "@nostr-connect/connect";
import { generatePrivateKey, getPublicKey } from "nostr-tools";
import { RootState } from "State/Store";
import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login";
@ -12,6 +14,9 @@ import { DefaultRelays, EmailRegex } from "Const";
import { bech32ToHex, unwrap } from "Util";
import { HexKey } from "@snort/nostr";
import ZapButton from "Element/ZapButton";
import QrCode from "Element/QrCode";
import Modal from "Element/Modal";
import Copy from "Element/Copy";
// import useImgProxy from "Feed/ImgProxy";
import messages from "./messages";
@ -55,6 +60,8 @@ export default function LoginPage() {
const [art, setArt] = useState<ArtworkEntry>();
const { formatMessage } = useIntl();
//const { proxy } = useImgProxy();
const [connectKey, setConnectKey] = useState<string | null>("");
const [connectURI, setConnectURI] = useState<string | null>("");
useEffect(() => {
if (publicKey) {
@ -69,6 +76,27 @@ export default function LoginPage() {
setArt(ret);
}, []);
useEffect(() => {
(async () => {
// Connect to Nostr
if (connectKey) {
const connect = new Connect({
secretKey: connectKey,
target: publicKey,
relay: "wss://nostr.vulpem.com",
});
connect.events.on("connect", (pub: string) => {
console.log("connected with wallet: " + pub);
dispatch(setPublicKey(pub));
});
connect.events.on("disconnect", () => {
setConnectKey(null);
});
await connect.init();
}
})();
}, [connectKey, dispatch]);
async function getNip05PubKey(addr: string) {
const [username, domain] = addr.split("@");
const rsp = await fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(username)}`);
@ -134,6 +162,32 @@ export default function LoginPage() {
}
}
async function doNip46Connect() {
let sk = connectKey;
if (!sk) {
sk = generatePrivateKey();
setConnectKey(sk);
}
const connectURI = new ConnectURI({
target: getPublicKey(sk),
relay: "wss://nostr.vulpem.com",
metadata: {
name: "Snort.Social",
description: "Fast nostr web ui.",
url: "https://snort.social",
icons: ["https://snort.social/nostrich_512.png"],
},
});
const uri = connectURI.toString();
setConnectURI(uri);
}
async function closeSession() {
setConnectURI(null);
setConnectKey(null);
}
function altLogins() {
const nip07 = "nostr" in window;
if (!nip07) {
@ -189,6 +243,25 @@ export default function LoginPage() {
<button type="button" onClick={doLogin}>
<FormattedMessage defaultMessage="Login" description="Login button" />
</button>
{connectURI && !publicKey ? (
<Modal className="qr-modal" onClose={closeSession}>
<div>
<p dir="auto">
<FormattedMessage
defaultMessage="Scan with a Nostr Connect app"
description="Scan with a Nostr Connect app"
/>
</p>
<QrCode data={connectURI} link={connectURI} />
<Copy text={connectURI} />
</div>
</Modal>
) : (
<button type="button" onClick={doNip46Connect}>
<FormattedMessage defaultMessage="Nostr Connect" description="Nostr Connect button" />
</button>
)}
{altLogins()}
</div>
<div className="flex login-or">

View File

@ -1662,12 +1662,17 @@
dependencies:
eslint-scope "5.1.1"
"@noble/hashes@^1.2.0":
"@noble/hashes@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae"
integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==
"@noble/hashes@^1.2.0", "@noble/hashes@~1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==
"@noble/secp256k1@^1.7.0":
"@noble/secp256k1@^1.7.0", "@noble/secp256k1@^1.7.1", "@noble/secp256k1@~1.7.0":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
@ -1693,6 +1698,14 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@nostr-connect/connect@^0.2.3":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@nostr-connect/connect/-/connect-0.2.3.tgz#6e7ba032dea5b853a3e272a61eebb5f2fed9c14b"
integrity sha512-04zMTyL+L9lic7MS6O5jvqTcFzh1wAj6Onj89uRsVbM89D8QlEAD4xYAFfAy6dIHL0LHAj1s6eRZUIiJbyPdbg==
dependencies:
events "^3.3.0"
nostr-tools "^1.0.1"
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
version "0.5.10"
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
@ -1770,6 +1783,28 @@
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==
"@scure/base@^1.1.1", "@scure/base@~1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
"@scure/bip32@^1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300"
integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==
dependencies:
"@noble/hashes" "~1.2.0"
"@noble/secp256k1" "~1.7.0"
"@scure/base" "~1.1.0"
"@scure/bip39@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5"
integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==
dependencies:
"@noble/hashes" "~1.2.0"
"@scure/base" "~1.1.0"
"@sinclair/typebox@^0.24.1":
version "0.24.51"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
@ -2186,9 +2221,9 @@
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
"@types/react-dom@^18.0.10":
version "18.0.10"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.10.tgz#3b66dec56aa0f16a6cc26da9e9ca96c35c0b4352"
integrity sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==
version "18.0.11"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33"
integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==
dependencies:
"@types/react" "*"
@ -4588,7 +4623,7 @@ eventemitter3@^4.0.0:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events@^3.2.0:
events@^3.2.0, events@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@ -7144,6 +7179,18 @@ normalize-url@^6.0.1:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
nostr-tools@^1.0.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.5.0.tgz#b8b8d4d9e122c4acbdfe8b580e82f539f0866b42"
integrity sha512-9zZdS3OF1hC8Tzpx2ycFLFx0AYSXBkLZ5EaXcPWIdZlQgSkpDrHl/TUYk2E8K7OocK+3VNbo4+7K2N38qdCjsg==
dependencies:
"@noble/hashes" "1.0.0"
"@noble/secp256k1" "^1.7.1"
"@scure/base" "^1.1.1"
"@scure/bip32" "^1.1.5"
"@scure/bip39" "^1.1.1"
prettier "^2.8.4"
npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
@ -8090,6 +8137,11 @@ prettier@2.8.3:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632"
integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==
prettier@^2.8.4:
version "2.8.4"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
version "5.6.0"
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"