forked from Kieran/snort
Compare commits
4 Commits
main
...
nostr-conn
Author | SHA1 | Date | |
---|---|---|---|
|
5244bf647f | ||
|
07588eaf32 | ||
|
4e3f9eaafd | ||
|
f56164e809 |
@ -9,8 +9,10 @@
|
|||||||
"@jukben/emoji-search": "^2.0.1",
|
"@jukben/emoji-search": "^2.0.1",
|
||||||
"@noble/hashes": "^1.2.0",
|
"@noble/hashes": "^1.2.0",
|
||||||
"@noble/secp256k1": "^1.7.0",
|
"@noble/secp256k1": "^1.7.0",
|
||||||
|
"@nostr-connect/connect": "^0.2.3",
|
||||||
"@protobufjs/base64": "^1.1.2",
|
"@protobufjs/base64": "^1.1.2",
|
||||||
"@reduxjs/toolkit": "^1.9.1",
|
"@reduxjs/toolkit": "^1.9.1",
|
||||||
|
"@snort/nostr": "^1.0.0",
|
||||||
"@szhsin/react-menu": "^3.3.1",
|
"@szhsin/react-menu": "^3.3.1",
|
||||||
"@types/jest": "^29.2.5",
|
"@types/jest": "^29.2.5",
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
@ -49,8 +51,7 @@
|
|||||||
"workbox-range-requests": "^6.4.2",
|
"workbox-range-requests": "^6.4.2",
|
||||||
"workbox-routing": "^6.4.2",
|
"workbox-routing": "^6.4.2",
|
||||||
"workbox-strategies": "^6.4.2",
|
"workbox-strategies": "^6.4.2",
|
||||||
"workbox-streams": "^6.4.2",
|
"workbox-streams": "^6.4.2"
|
||||||
"@snort/nostr": "^1.0.0"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-app-rewired start",
|
"start": "react-app-rewired start",
|
||||||
|
@ -5,6 +5,8 @@ import { useDispatch, useSelector } from "react-redux";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import * as secp from "@noble/secp256k1";
|
import * as secp from "@noble/secp256k1";
|
||||||
import { useIntl, FormattedMessage } from "react-intl";
|
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 { RootState } from "State/Store";
|
||||||
import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login";
|
import { setPrivateKey, setPublicKey, setRelays, setGeneratedPrivateKey } from "State/Login";
|
||||||
@ -12,6 +14,9 @@ import { DefaultRelays, EmailRegex } from "Const";
|
|||||||
import { bech32ToHex, unwrap } from "Util";
|
import { bech32ToHex, unwrap } from "Util";
|
||||||
import { HexKey } from "@snort/nostr";
|
import { HexKey } from "@snort/nostr";
|
||||||
import ZapButton from "Element/ZapButton";
|
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 useImgProxy from "Feed/ImgProxy";
|
||||||
|
|
||||||
import messages from "./messages";
|
import messages from "./messages";
|
||||||
@ -55,6 +60,8 @@ export default function LoginPage() {
|
|||||||
const [art, setArt] = useState<ArtworkEntry>();
|
const [art, setArt] = useState<ArtworkEntry>();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
//const { proxy } = useImgProxy();
|
//const { proxy } = useImgProxy();
|
||||||
|
const [connectKey, setConnectKey] = useState<string | null>("");
|
||||||
|
const [connectURI, setConnectURI] = useState<string | null>("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (publicKey) {
|
if (publicKey) {
|
||||||
@ -69,6 +76,27 @@ export default function LoginPage() {
|
|||||||
setArt(ret);
|
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) {
|
async function getNip05PubKey(addr: string) {
|
||||||
const [username, domain] = addr.split("@");
|
const [username, domain] = addr.split("@");
|
||||||
const rsp = await fetch(`https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(username)}`);
|
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() {
|
function altLogins() {
|
||||||
const nip07 = "nostr" in window;
|
const nip07 = "nostr" in window;
|
||||||
if (!nip07) {
|
if (!nip07) {
|
||||||
@ -189,6 +243,25 @@ export default function LoginPage() {
|
|||||||
<button type="button" onClick={doLogin}>
|
<button type="button" onClick={doLogin}>
|
||||||
<FormattedMessage defaultMessage="Login" description="Login button" />
|
<FormattedMessage defaultMessage="Login" description="Login button" />
|
||||||
</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()}
|
{altLogins()}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex login-or">
|
<div className="flex login-or">
|
||||||
|
64
yarn.lock
64
yarn.lock
@ -1662,12 +1662,17 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
eslint-scope "5.1.1"
|
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"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
|
||||||
integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==
|
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"
|
version "1.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
|
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
|
||||||
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
|
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
|
||||||
@ -1693,6 +1698,14 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.5"
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
fastq "^1.6.0"
|
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":
|
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
|
||||||
version "0.5.10"
|
version "0.5.10"
|
||||||
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8"
|
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"
|
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
|
||||||
integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==
|
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":
|
"@sinclair/typebox@^0.24.1":
|
||||||
version "0.24.51"
|
version "0.24.51"
|
||||||
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
|
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f"
|
||||||
@ -2186,9 +2221,9 @@
|
|||||||
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
|
integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
|
||||||
|
|
||||||
"@types/react-dom@^18.0.10":
|
"@types/react-dom@^18.0.10":
|
||||||
version "18.0.10"
|
version "18.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.10.tgz#3b66dec56aa0f16a6cc26da9e9ca96c35c0b4352"
|
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33"
|
||||||
integrity sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==
|
integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
@ -4588,7 +4623,7 @@ eventemitter3@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||||
|
|
||||||
events@^3.2.0:
|
events@^3.2.0, events@^3.3.0:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
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"
|
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
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:
|
npm-run-path@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
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"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632"
|
||||||
integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==
|
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:
|
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
|
||||||
|
Loading…
Reference in New Issue
Block a user