From 9644a9f86755976347ba8e0eaa013419a6756bc3 Mon Sep 17 00:00:00 2001 From: keyan Date: Wed, 18 Jan 2023 12:49:20 -0600 Subject: [PATCH] slashtags auth --- api/resolvers/lnurl.js | 3 + api/resolvers/user.js | 27 +- api/slashtags/index.js | 61 ++ api/ssrApollo.js | 4 +- api/typeDefs/lnurl.js | 1 + api/typeDefs/user.js | 5 +- components/invoice.js | 4 +- components/item-full.js | 1 - components/lightning-auth.js | 43 +- components/login-button.js | 8 +- components/login.js | 82 +- components/{lnqr.js => qr.js} | 6 +- fragments/users.js | 5 +- package-lock.json | 930 ++++++++++++++++++ package.json | 2 + pages/api/auth/[...nextauth].js | 44 +- pages/api/graphql.js | 4 +- pages/api/lnauth.js | 7 + pages/invoices/[id].js | 4 +- pages/settings.js | 138 +-- pages/wallet.js | 8 +- .../20230117185647_slashtags/migration.sql | 11 + prisma/schema.prisma | 1 + styles/globals.scss | 4 + svgs/slashtags.svg | 4 + 25 files changed, 1257 insertions(+), 150 deletions(-) create mode 100644 api/slashtags/index.js rename components/{lnqr.js => qr.js} (86%) create mode 100644 prisma/migrations/20230117185647_slashtags/migration.sql create mode 100644 svgs/slashtags.svg diff --git a/api/resolvers/lnurl.js b/api/resolvers/lnurl.js index 10b431a4..19ea5e6c 100644 --- a/api/resolvers/lnurl.js +++ b/api/resolvers/lnurl.js @@ -39,6 +39,9 @@ export default { LnAuth: { encodedUrl: async (lnAuth, args, { models }) => { return encodedUrl(process.env.LNAUTH_URL, 'login', lnAuth.k1) + }, + slashtagUrl: async (lnAuth, args, { models, slashtags }) => { + return slashtags.formatURL(lnAuth.k1) } }, LnWith: { diff --git a/api/resolvers/user.js b/api/resolvers/user.js index 94cde4a1..4f92d4b7 100644 --- a/api/resolvers/user.js +++ b/api/resolvers/user.js @@ -54,7 +54,8 @@ async function authMethods (user, args, { models, me }) { lightning: !!user.pubkey, email: user.emailVerified && user.email, twitter: oauth.indexOf('twitter') >= 0, - github: oauth.indexOf('github') >= 0 + github: oauth.indexOf('github') >= 0, + slashtags: !!user.slashtagId } } @@ -402,27 +403,25 @@ export default { throw new AuthenticationError('you must be logged in') } + let user if (authType === 'twitter' || authType === 'github') { - const user = await models.user.findUnique({ where: { id: me.id } }) + user = await models.user.findUnique({ where: { id: me.id } }) const account = await models.account.findFirst({ where: { userId: me.id, providerId: authType } }) if (!account) { throw new UserInputError('no such account') } await models.account.delete({ where: { id: account.id } }) - return await authMethods(user, undefined, { models, me }) + } else if (authType === 'lightning') { + user = await models.user.update({ where: { id: me.id }, data: { pubkey: null } }) + } else if (authType === 'slashtags') { + user = await models.user.update({ where: { id: me.id }, data: { slashtagId: null } }) + } else if (authType === 'email') { + user = await models.user.update({ where: { id: me.id }, data: { email: null, emailVerified: null } }) + } else { + throw new UserInputError('no such account') } - if (authType === 'lightning') { - const user = await models.user.update({ where: { id: me.id }, data: { pubkey: null } }) - return await authMethods(user, undefined, { models, me }) - } - - if (authType === 'email') { - const user = await models.user.update({ where: { id: me.id }, data: { email: null, emailVerified: null } }) - return await authMethods(user, undefined, { models, me }) - } - - throw new UserInputError('no such account') + return await authMethods(user, undefined, { models, me }) }, linkUnverifiedEmail: async (parent, { email }, { models, me }) => { if (!me) { diff --git a/api/slashtags/index.js b/api/slashtags/index.js new file mode 100644 index 00000000..a7cf58d7 --- /dev/null +++ b/api/slashtags/index.js @@ -0,0 +1,61 @@ +import models from '../models' +import SDK, { SlashURL } from '@synonymdev/slashtags-sdk' +import { Server } from '@synonymdev/slashtags-auth' + +const HOUR = 1000 * 60 * 60 + +async function createProfile (slashtag) { + const publicDrive = slashtag.drivestore.get() + await publicDrive.ready() + const exists = await publicDrive.get('/profile.json') + if (!exists) { + await publicDrive.put('/profile.json', Buffer.from(JSON.stringify({ + name: 'Stacker News', + image: 'data:image/jpeg;base64,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', + bio: "It's like Hacker News but we pay you Bitcoin" + }))) + } +} + +const slashtags = global.slashtags || (() => { + console.log('initing slashtags') + const sdk = new SDK({ primaryKey: Buffer.from(process.env.SLASHTAGS_SECRET, 'hex') }) + + // Get the default slashtag + const slashtag = sdk.slashtag() + + createProfile(slashtag) + + const server = new Server(slashtag, { + onauthz: async (token, remote) => { + const user = SlashURL.format(remote) + console.log('Got session', token, 'from:', user) + + const auth = await models.lnAuth.findUnique({ where: { k1: token } }) + if (!auth || auth.pubkey || auth.createdAt < Date.now() - HOUR) { + console.log('Got invalid session', token, 'from:', user) + return { status: 'error', message: 'token expired' } + } + + console.log('Got valid session', token, 'from:', user) + await models.lnAuth.update({ where: { k1: token }, data: { pubkey: SlashURL.parse(user).id } }) + return { status: 'ok' } + }, + onmagiclink: () => { + return { + url: 'https://stacker.news', + validUntil: Number(new Date()) + 15 * 60 * 60 + } + } + }) + + slashtag.listen() + + return server +})() + +if (process.env.NODE_ENV === 'development') global.slashtags = slashtags + +export default slashtags + +// server.formatURL(token) is what the user scans! diff --git a/api/ssrApollo.js b/api/ssrApollo.js index 92f50701..b40e4832 100644 --- a/api/ssrApollo.js +++ b/api/ssrApollo.js @@ -5,6 +5,7 @@ import { getSession } from 'next-auth/client' import resolvers from './resolvers' import typeDefs from './typeDefs' import models from './models' +import slashtags from './slashtags' import { print } from 'graphql' import lnd from './lnd' import search from './search' @@ -26,7 +27,8 @@ export default async function getSSRApolloClient (req, me = null) { ? session.user : me, lnd, - search + search, + slashtags } }), cache: new InMemoryCache() diff --git a/api/typeDefs/lnurl.js b/api/typeDefs/lnurl.js index 90e14193..9ef3d9d9 100644 --- a/api/typeDefs/lnurl.js +++ b/api/typeDefs/lnurl.js @@ -17,6 +17,7 @@ export default gql` k1: String! pubkey: String encodedUrl: String! + slashtagUrl: String! } type LnWith { diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js index ddd7229e..e0604234 100644 --- a/api/typeDefs/user.js +++ b/api/typeDefs/user.js @@ -32,9 +32,10 @@ export default gql` type AuthMethods { lightning: Boolean! - email: String - twitter: Boolean! + slashtags: Boolean! github: Boolean! + twitter: Boolean! + email: String } type User { diff --git a/components/invoice.js b/components/invoice.js index 677f83da..5e398714 100644 --- a/components/invoice.js +++ b/components/invoice.js @@ -1,4 +1,4 @@ -import LnQR from './lnqr' +import Qr from './qr' export function Invoice ({ invoice }) { let variant = 'default' @@ -14,5 +14,5 @@ export function Invoice ({ invoice }) { status = 'expired' } - return + return } diff --git a/components/item-full.js b/components/item-full.js index 54974249..4ab0d60f 100644 --- a/components/item-full.js +++ b/components/item-full.js @@ -73,7 +73,6 @@ function ItemEmbed ({ item }) { const youtube = item.url?.match(/(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)(?[_0-9a-z-]+)((?:\?|&)(?:t|start)=(?\d+))?/i) if (youtube?.groups?.id) { - console.log(youtube?.groups?.start) return (
+ ) } @@ -84,7 +84,15 @@ function LightningExplainer ({ text, children }) { ) } -export function LightningAuth ({ text, callbackUrl }) { +export function LightningAuthWithExplainer ({ text, callbackUrl }) { + return ( + + + + ) +} + +export function LightningAuth ({ callbackUrl }) { // query for challenge const [createAuth, { data, error }] = useMutation(gql` mutation createAuth { @@ -100,9 +108,24 @@ export function LightningAuth ({ text, callbackUrl }) { if (error) return
error
- return ( - - {data ? : } - - ) + return data ? : +} + +export function SlashtagsAuth ({ callbackUrl }) { + // query for challenge + const [createAuth, { data, error }] = useMutation(gql` + mutation createAuth { + createAuth { + k1 + slashtagUrl + } + }`) + + useEffect(() => { + createAuth() + }, []) + + if (error) return
error
+ + return data ? : } diff --git a/components/login-button.js b/components/login-button.js index 88a77cc4..c3e48952 100644 --- a/components/login-button.js +++ b/components/login-button.js @@ -1,7 +1,9 @@ import GithubIcon from '../svgs/github-fill.svg' import TwitterIcon from '../svgs/twitter-fill.svg' import LightningIcon from '../svgs/bolt.svg' +import SlashtagsIcon from '../svgs/slashtags.svg' import { Button } from 'react-bootstrap' + export default function LoginButton ({ text, type, className, onClick }) { let Icon, variant switch (type) { @@ -17,6 +19,10 @@ export default function LoginButton ({ text, type, className, onClick }) { Icon = LightningIcon variant = 'primary' break + case 'slashtags': + Icon = SlashtagsIcon + variant = 'grey-medium' + break } const name = type.charAt(0).toUpperCase() + type.substr(1).toLowerCase() @@ -25,7 +31,7 @@ export default function LoginButton ({ text, type, className, onClick }) { diff --git a/components/login.js b/components/login.js index 24443888..7ec4ab7f 100644 --- a/components/login.js +++ b/components/login.js @@ -1,15 +1,12 @@ import { signIn } from 'next-auth/client' -import Button from 'react-bootstrap/Button' import styles from './login.module.css' -import GithubIcon from '../svgs/github-fill.svg' -import TwitterIcon from '../svgs/twitter-fill.svg' -import LightningIcon from '../svgs/bolt.svg' import { Form, Input, SubmitButton } from '../components/form' import * as Yup from 'yup' import { useState } from 'react' import Alert from 'react-bootstrap/Alert' import { useRouter } from 'next/router' -import { LightningAuth } from './lightning-auth' +import { LightningAuthWithExplainer, SlashtagsAuth } from './lightning-auth' +import LoginButton from './login-button' export const EmailSchema = Yup.object({ email: Yup.string().email('email is no good').required('required') @@ -48,7 +45,7 @@ export default function Login ({ providers, callbackUrl, error, text, Header, Fo Callback: 'Try signing with a different account.', OAuthAccountNotLinked: 'To confirm your identity, sign in with the same account you used originally.', EmailSignin: 'Check your email address.', - CredentialsSignin: 'Lightning auth failed.', + CredentialsSignin: 'Auth failed', default: 'Unable to sign in.' } @@ -56,7 +53,11 @@ export default function Login ({ providers, callbackUrl, error, text, Header, Fo const router = useRouter() if (router.query.type === 'lightning') { - return + return + } + + if (router.query.type === 'slashtags') { + return } return ( @@ -69,44 +70,41 @@ export default function Login ({ providers, callbackUrl, error, text, Header, Fo dismissible >{errorMessage} } - {providers && Object.values(providers).map(provider => { - if (provider.name === 'Email' || provider.name === 'Lightning') { - return null + switch (provider.name) { + case 'Email': + return ( +
+
or
+ +
+ ) + case 'Lightning': + case 'Slashtags': + return ( + router.push({ + pathname: router.pathname, + query: { ...router.query, type: provider.name.toLowerCase() } + })} + text={`${text || 'Login'} with`} + /> + ) + default: + return ( + signIn(provider.id, { callbackUrl })} + text={`${text || 'Login'} with`} + /> + ) } - const [variant, Icon] = - provider.name === 'Twitter' - ? ['twitter', TwitterIcon] - : ['dark', GithubIcon] - - return ( - - ) })} -
or
- {Footer &&
}
) diff --git a/components/lnqr.js b/components/qr.js similarity index 86% rename from components/lnqr.js rename to components/qr.js index 84e17093..772f912a 100644 --- a/components/lnqr.js +++ b/components/qr.js @@ -4,8 +4,8 @@ import InvoiceStatus from './invoice-status' import { requestProvider } from 'webln' import { useEffect } from 'react' -export default function LnQR ({ value, webLn, statusVariant, status }) { - const qrValue = 'lightning:' + value.toUpperCase() +export default function Qr ({ asIs, value, webLn, statusVariant, status }) { + const qrValue = asIs ? value : 'lightning:' + value.toUpperCase() useEffect(() => { async function effect () { @@ -36,7 +36,7 @@ export default function LnQR ({ value, webLn, statusVariant, status }) { ) } -export function LnQRSkeleton ({ status }) { +export function QrSkeleton ({ status }) { return ( <>
diff --git a/fragments/users.js b/fragments/users.js index 5eb55934..a69c4354 100644 --- a/fragments/users.js +++ b/fragments/users.js @@ -52,9 +52,10 @@ export const SETTINGS_FIELDS = gql` greeterMode authMethods { lightning - email - twitter + slashtags github + twitter + email } }` diff --git a/package-lock.json b/package-lock.json index 7eefa8de..95a8b0d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1100,6 +1100,97 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@hyperswarm/dht": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.3.tgz", + "integrity": "sha512-sxzlVNLUHZV62dOZSPEaN5I2pwgwcwtcbVas+G6bE+tnEAdRf9qjNjGSgbTNk0ZqfX8Ai64W567zXH9vtTB4XQ==", + "requires": { + "@hyperswarm/secret-stream": "^6.0.0", + "b4a": "^1.3.1", + "bogon": "^1.0.0", + "compact-encoding": "^2.4.1", + "compact-encoding-net": "^1.0.1", + "debugging-stream": "^2.0.0", + "dht-rpc": "^6.6.1", + "events": "^3.3.0", + "hypercore-crypto": "^3.3.0", + "noise-curve-ed": "^2.0.0", + "noise-handshake": "^3.0.0", + "record-cache": "^1.1.1", + "safety-catch": "^1.0.1", + "sodium-universal": "^4.0.0", + "xache": "^1.1.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, + "@hyperswarm/dht-relay": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@hyperswarm/dht-relay/-/dht-relay-0.3.0.tgz", + "integrity": "sha512-HOg8B+WNdI0/l6LCDdXhau7BmMhd0Eq//EvmlMvR1MlwJ7T8YCDaXm1EeqCnOSvTf7/DP90O8Jd23yXd3B9OiQ==", + "requires": { + "@hyperswarm/dht": "^6.0.1", + "@hyperswarm/secret-stream": "^6.0.0", + "b4a": "^1.1.4", + "compact-encoding": "^2.6.1", + "compact-encoding-net": "^1.0.1", + "events": "^3.3.0", + "protomux": "^3.1.1", + "safety-catch": "^1.0.1", + "sodium-universal": "^3.0.4", + "streamx": "^2.11.3", + "timeout-refresh": "^2.0.1" + } + }, + "@hyperswarm/secret-stream": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.1.2.tgz", + "integrity": "sha512-oem+ZEG+wOU1K47qGi51pKyqG1N3F+zz42xmReHeGZVR84y+K+6VQIXCON4EozYad8HEGCixpupt8yH8W4sMxg==", + "requires": { + "b4a": "^1.1.0", + "hypercore-crypto": "^3.3.1", + "noise-curve-ed": "^2.0.1", + "noise-handshake": "^3.0.2", + "sodium-secretstream": "^1.1.0", + "sodium-universal": "^4.0.0", + "streamx": "^2.13.0", + "timeout-refresh": "^2.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, "@josephg/resolvable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz", @@ -1611,6 +1702,81 @@ "tslib": "^2.4.0" } }, + "@synonymdev/slashdrive": { + "version": "1.0.0-alpha.20", + "resolved": "https://registry.npmjs.org/@synonymdev/slashdrive/-/slashdrive-1.0.0-alpha.20.tgz", + "integrity": "sha512-6i+/g8y45OY374gHLQSMNbLEwCL/rzlXODXLpZ8j8UFV7x/NB2blrdRoD4sladLjny30oLg2EiZzKOyjK0iIrg==", + "requires": { + "b4a": "^1.6.0", + "corestore": "^6.2.1", + "hyperbee": "^2.0.1", + "hyperdrive": "^11.0.0-alpha.5", + "safety-catch": "^1.0.2" + } + }, + "@synonymdev/slashtag": { + "version": "1.0.0-alpha.24", + "resolved": "https://registry.npmjs.org/@synonymdev/slashtag/-/slashtag-1.0.0-alpha.24.tgz", + "integrity": "sha512-Edd++LhRElfdIy18wlB7iKip/Rc2i4ph09p5Un3pYyG05IDLWNu3TxcwQ+DIF2+n3QcJc39jBtl7j1eFx+A5mA==", + "requires": { + "@hyperswarm/dht": "^6.2.1", + "@synonymdev/slashdrive": "^1.0.0-alpha.20", + "@synonymdev/slashtags-url": "^1.0.0-alpha.1", + "corestore": "^6.2.1", + "random-access-memory": "^5.0.1", + "turbo-hash-map": "^1.0.3" + } + }, + "@synonymdev/slashtags-auth": { + "version": "1.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/@synonymdev/slashtags-auth/-/slashtags-auth-1.0.0-alpha.5.tgz", + "integrity": "sha512-GsRTwp65csVYU/PqnQ/fsj3uz+8Z+GGFGIphXxMxY7Wsm5Y5kfv3xVxW18uExIAHa9bv8AlpNcpXmivnoE3+hw==", + "requires": { + "@synonymdev/slashtags-rpc": "^1.0.0-alpha.2", + "@synonymdev/slashtags-url": "^1.0.0-alpha.1", + "compact-encoding": "^2.11.0", + "compact-encoding-struct": "^1.3.0" + } + }, + "@synonymdev/slashtags-rpc": { + "version": "1.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/@synonymdev/slashtags-rpc/-/slashtags-rpc-1.0.0-alpha.2.tgz", + "integrity": "sha512-pngaKkjznWFmV+emF+JI033l7Vr7mBvTnWynU1Mvjlps+PXZCL/bPJVC2TDPvGhugUTxUD6Bv+Tt0WL0xJuajw==", + "requires": { + "b4a": "^1.6.0", + "protomux-rpc": "^1.3.0" + } + }, + "@synonymdev/slashtags-sdk": { + "version": "1.0.0-alpha.36", + "resolved": "https://registry.npmjs.org/@synonymdev/slashtags-sdk/-/slashtags-sdk-1.0.0-alpha.36.tgz", + "integrity": "sha512-7G6cLINKjaJ/28n7zj8F7RFkusGkIJ3XzUWZtIopomjwTvLYdYrFyFjwL/mIyiuNtK/9OeLNp1NIVw7KpX+ULQ==", + "requires": { + "@hyperswarm/dht": "^6.2.1", + "@hyperswarm/dht-relay": "^0.3.0", + "@synonymdev/slashtag": "^1.0.0-alpha.24", + "@synonymdev/slashtags-url": "^1.0.0-alpha.0", + "b4a": "^1.6.0", + "corestore": "^6.2.1", + "graceful-goodbye": "^1.1.0", + "hypercore-crypto": "^3.3.0", + "hyperdrive": "^11.0.0-alpha.3", + "hyperswarm": "^4.3.5", + "random-access-memory": "^5.0.1", + "sodium-universal": "^3.1.0", + "turbo-hash-map": "^1.0.3", + "ws": "^8.8.1" + } + }, + "@synonymdev/slashtags-url": { + "version": "1.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/@synonymdev/slashtags-url/-/slashtags-url-1.0.0-alpha.2.tgz", + "integrity": "sha512-1dqGL4pi49CKjcUjctz1McWR+kRlmfK54QE8hZ+XWTic1zmW9G4dO70ktBZX7iYOT3b80BrQ56ncmeR4YzPn0A==", + "requires": { + "b4a": "^1.6.0", + "z32": "^1.0.0" + } + }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -2334,6 +2500,11 @@ } } }, + "b4a": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.1.tgz", + "integrity": "sha512-AsKjNhz72yxteo/0EtQEiwkMUgk/tGmycXlbG4g3Ard2/ULtNLUykGOkeK0egmN27h0xMAhb76jYccW+XTBExA==" + }, "babel-plugin-inline-react-svg": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/babel-plugin-inline-react-svg/-/babel-plugin-inline-react-svg-2.0.1.tgz", @@ -2409,11 +2580,24 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, + "big-sparse-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz", + "integrity": "sha512-6RjV/3mSZORlMdpUaQ6rUSpG637cZm0//E54YYGtQg1c1O+AbZP8UTdJ/TchsDZcTVLmyWZcseBfp2HBeXUXOQ==" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, + "binary-stream-equals": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/binary-stream-equals/-/binary-stream-equals-1.0.0.tgz", + "integrity": "sha512-xiUT5LGfD8JiLhbXiG+ByOnbgb9f2ssRLfZDQMl3nZdf89EotQZGZuMkDN8J3n46emabE7RnJ1q0r7Hv3INExw==", + "requires": { + "b4a": "^1.3.1" + } + }, "bip174": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.0.tgz", @@ -2447,6 +2631,14 @@ "wif": "^2.0.1" } }, + "bits-to-bytes": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bits-to-bytes/-/bits-to-bytes-1.3.0.tgz", + "integrity": "sha512-OJoHTpFXS9bXHBCekGTByf3MqM8CGblBDIduKQeeVVeiU9dDWywSSirXIBYGgg3d1zbVuvnMa1vD4r6PA0kOKg==", + "requires": { + "b4a": "^1.5.0" + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -2457,6 +2649,24 @@ "readable-stream": "^3.4.0" } }, + "blake2b": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.4.tgz", + "integrity": "sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==", + "requires": { + "blake2b-wasm": "^2.4.0", + "nanoassert": "^2.0.0" + } + }, + "blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, "bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -2539,6 +2749,15 @@ } } }, + "bogon": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bogon/-/bogon-1.1.0.tgz", + "integrity": "sha512-a6SnToksXHuUlgeMvI/txWmTcKz7c7iBa8f0HbXL4toN1Uza/CTQ4F7n9jSDX49TCpxv3KUP100q4sZfwLyLiw==", + "requires": { + "compact-encoding": "^2.11.0", + "compact-encoding-net": "^1.2.0" + } + }, "bolt07": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/bolt07/-/bolt07-1.8.2.tgz", @@ -2775,6 +2994,14 @@ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" }, + "chacha20-universal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chacha20-universal/-/chacha20-universal-1.0.4.tgz", + "integrity": "sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==", + "requires": { + "nanoassert": "^2.0.0" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -3065,6 +3292,14 @@ "mimic-response": "^1.0.0" } }, + "codecs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/codecs/-/codecs-3.0.0.tgz", + "integrity": "sha512-tYnev/H2/q+dedb6/sDDvJLwzD2GqYIe8d7fKnyM2KxUKJ3xf/D7xG0nO/4WCT1yU1HQTvTq1o43QSQGmHcEmA==", + "requires": { + "b4a": "^1.1.1" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3096,6 +3331,35 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" }, + "compact-encoding": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.11.0.tgz", + "integrity": "sha512-CRfTuyy9Tg7EwxNKvIq3yFIr2JnJLyVr9Yj234VsDCL59hdXcZH3TdzY/2kwbAqVogIoRBJjnNKCEnXbxTIEeg==", + "requires": { + "b4a": "^1.3.0" + } + }, + "compact-encoding-bitfield": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/compact-encoding-bitfield/-/compact-encoding-bitfield-1.0.0.tgz", + "integrity": "sha512-3nMVKUg+PF72UHfainmCL8uKvyWfxsjqOtUY+HiMPGLPCTjnwzoKfFAMo1Ad7nwTPdjBqtGK5b3BOFTFW4EBTg==", + "requires": { + "compact-encoding": "^2.4.1" + } + }, + "compact-encoding-net": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/compact-encoding-net/-/compact-encoding-net-1.2.0.tgz", + "integrity": "sha512-LVXpNpF7PGQeHRVVLGgYWzuVoYAaDZvKUsUxRioGfkotzvOh4AzoQF1HBH3zMNaSnx7gJXuUr3hkjnijaH/Eng==", + "requires": { + "compact-encoding": "^2.4.1" + } + }, + "compact-encoding-struct": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/compact-encoding-struct/-/compact-encoding-struct-1.3.0.tgz", + "integrity": "sha512-8wgarWCGjtTQlpLu7ebVeeW0hEterei/D8MoIASBiZIUKV2RtzEaViAK+EMemOOOaHQFbp6yRH/k4Q2I94Qpxg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3164,6 +3428,37 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "corestore": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/corestore/-/corestore-6.4.1.tgz", + "integrity": "sha512-YLqS9Fmr79jY3YWkKf6OLtZH2OkaUzb3oJZeeQhKVR90IeyOHRlKGv7v2aMve+1OWX6HWO9V08IBOK/VMciC7w==", + "requires": { + "b4a": "^1.3.1", + "hypercore": "^10.5.3", + "hypercore-crypto": "^3.2.1", + "safety-catch": "^1.0.1", + "sodium-universal": "^4.0.0", + "xache": "^1.1.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -3185,6 +3480,14 @@ "yaml": "^1.10.0" } }, + "crc-universal": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/crc-universal/-/crc-universal-1.0.2.tgz", + "integrity": "sha512-RrQ/8bT3WKNsGQuHWV3wf3Y0SUJTa8GADrkrQ1gsDljJLs8h/ENJRFUkL3z1TRWas80gv3Kdo6z1IPYyVJ/sxQ==", + "requires": { + "node-gyp-build": "^4.5.0" + } + }, "create-error-class": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", @@ -3381,6 +3684,14 @@ "ms": "2.1.2" } }, + "debugging-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/debugging-stream/-/debugging-stream-2.0.0.tgz", + "integrity": "sha512-xwfl6wB/3xc553uwtGnSa94jFxnGOc02C0WU2Nmzwr80gzeqn1FX4VcbvoKIhe8L/lPq4BTQttAbrTN94uN8rA==", + "requires": { + "streamx": "^2.12.4" + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -3477,6 +3788,42 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1056733.tgz", "integrity": "sha512-CmTu6SQx2g3TbZzDCAV58+LTxVdKplS7xip0g5oDXpZ+isr0rv5dDP8ToyVRywzPHkCCPKgKgScEcwz4uPWDIA==" }, + "dht-rpc": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/dht-rpc/-/dht-rpc-6.6.2.tgz", + "integrity": "sha512-tOG4cEwere/Vi5y8zJb1D55ApPFRMyHwgVLmjPeROQhYc0/L2ZYw/h4u3XqGYI0i+vweBN2ZEJ99vk9iBsxd3A==", + "requires": { + "b4a": "^1.3.1", + "compact-encoding": "^2.1.0", + "compact-encoding-net": "^1.0.1", + "events": "^3.3.0", + "fast-fifo": "^1.0.0", + "kademlia-routing-table": "^1.0.0", + "nat-sampler": "^1.0.1", + "sodium-universal": "^4.0.0", + "streamx": "^2.10.3", + "time-ordered-set": "^1.0.2", + "udx-native": "^1.2.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -4322,6 +4669,11 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -4433,6 +4785,11 @@ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz", "integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==" }, + "fast-fifo": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", + "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==" + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4569,6 +4926,11 @@ "rimraf": "^3.0.2" } }, + "flat-tree": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.9.0.tgz", + "integrity": "sha512-WRu5/q9fcdL9f7L6Ahq8fR153e5Zr5aU6plPHupN6JDWuvEJbMjrEQprge3/I7ytndHC6/GUNg5Rg8XEisuv5w==" + }, "flatted": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", @@ -4642,6 +5004,17 @@ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, + "fs-native-extensions": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fs-native-extensions/-/fs-native-extensions-1.2.0.tgz", + "integrity": "sha512-SIHH84fx7NLGfvRDkaLrfAnsCljwEAjCLy+CfR0r27wcrhed0xpqzP3o8kVCADlX3316BgiUGVx+yuI5EhgV5w==", + "optional": true, + "requires": { + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.2.3", + "uv-errors": "^1.0.1" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4827,6 +5200,11 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, + "graceful-goodbye": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/graceful-goodbye/-/graceful-goodbye-1.2.0.tgz", + "integrity": "sha512-o+H6xuufdpN3Qt2sXi5HLxIoW07cE/0zNccrmDajOyNnlVHHeDOp5Uvt3uZYTov/sSphcd0aZW5Y5GdvFpfKWg==" + }, "graphql": { "version": "15.8.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", @@ -5143,6 +5521,125 @@ "normalize-url": "^7.0.0" } }, + "hyperbee": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hyperbee/-/hyperbee-2.3.0.tgz", + "integrity": "sha512-DOUpOcz9W3XtECWu9bTHqQwYf7ls9/kY28xJnn8gOPbCmI2pHHzkvIL/1PUgDldvVN+8aRyW24b6w50GQAuoBQ==", + "requires": { + "b4a": "^1.6.0", + "codecs": "^3.0.0", + "mutexify": "^1.4.0", + "protocol-buffers-encodings": "^1.2.0", + "safety-catch": "^1.0.2", + "streamx": "^2.12.4" + } + }, + "hyperblobs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hyperblobs/-/hyperblobs-2.0.1.tgz", + "integrity": "sha512-Vy4Ak1vyC5IRzrzfOfLWZdzwP6nnT6tzf3WNMuU/s2/FLGMsIjwrQznCCEefjcfZOAxygfSk+21ItdYQG1lA2A==", + "requires": { + "b4a": "^1.6.1", + "mutexify": "^1.4.0", + "streamx": "^2.12.4" + } + }, + "hypercore": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-10.5.4.tgz", + "integrity": "sha512-63Qj2OMDzjYkq3pHsqVjqrDI/mfYJu8V9VGGj7Ib9J1zvkDUW8TgqobuZZ0r12MLGDeG/Opu4BccbLU3+sqUeg==", + "requires": { + "@hyperswarm/secret-stream": "^6.0.0", + "b4a": "^1.1.0", + "big-sparse-array": "^1.0.3", + "compact-encoding": "^2.11.0", + "crc-universal": "^1.0.2", + "events": "^3.3.0", + "flat-tree": "^1.9.0", + "hypercore-crypto": "^3.2.1", + "is-options": "^1.0.1", + "protomux": "^3.4.0", + "quickbit-universal": "^2.0.3", + "random-access-file": "^4.0.0", + "random-array-iterator": "^1.0.0", + "safety-catch": "^1.0.1", + "sodium-universal": "^4.0.0", + "streamx": "^2.12.4", + "xache": "^1.1.0", + "z32": "^1.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, + "hypercore-crypto": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/hypercore-crypto/-/hypercore-crypto-3.3.1.tgz", + "integrity": "sha512-Fo0ZBMDW3P7HFh58AQdxsVop0Xh0Bper4Pyl5Dpc+tvGos6je2ufJpeepaHaI0mNkKq4we1ikd47kTnx2XJd/w==", + "requires": { + "b4a": "^1.1.0", + "compact-encoding": "^2.5.1", + "sodium-universal": "^4.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, + "hyperdrive": { + "version": "11.0.0-alpha.10", + "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.0.0-alpha.10.tgz", + "integrity": "sha512-Lzn8Pf/93OM+wsGL++l0ShH7BLa/qcmuPNDcA1z2gYMIR7tiwc/dIwM8jNUhDbAZ9l0FL3xaNASeGxJxxpuRAw==", + "requires": { + "hyperbee": "^2.1.1", + "hyperblobs": "^2.0.0", + "is-options": "^1.0.2", + "mirror-drive": "^1.2.0", + "streamx": "^2.12.4", + "unix-path-resolve": "^1.0.2" + } + }, + "hyperswarm": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/hyperswarm/-/hyperswarm-4.3.6.tgz", + "integrity": "sha512-thohjQjRkuI0sybTzedpJ1mPIXJ9RvcW78TteV38CjcEv5OGk6FXfX7XkKmz/aS2NHLXHIaSqOnMOvD4gSbXIA==", + "requires": { + "@hyperswarm/dht": "^6.0.1", + "b4a": "^1.3.1", + "events": "^3.3.0", + "safety-catch": "^1.0.2", + "shuffled-priority-queue": "^2.1.0" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5404,6 +5901,14 @@ "has-tostringtag": "^1.0.0" } }, + "is-options": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz", + "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==", + "requires": { + "b4a": "^1.1.1" + } + }, "is-plain-obj": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", @@ -5629,6 +6134,11 @@ "safe-buffer": "^5.0.1" } }, + "kademlia-routing-table": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kademlia-routing-table/-/kademlia-routing-table-1.0.1.tgz", + "integrity": "sha512-dKk19sC3/+kWhBIvOKCthxVV+JH0NrswSBq4sA4eOkkPMqQM1rRuOWte1WSKXeP8r9Nx4NuiH2gny3lMddJTpw==" + }, "keyv": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", @@ -6715,6 +7225,15 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" }, + "mirror-drive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/mirror-drive/-/mirror-drive-1.2.1.tgz", + "integrity": "sha512-1Y6vj25cVXIxzkiN9HRPOLunk/KnWAFG+EDHtjMBt/ydaD9UKUsqb0p/ly1ht/vFtDTvWEW5lPoIll6hzvMu3g==", + "requires": { + "binary-stream-equals": "^1.0.0", + "same-data": "^1.0.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -6775,6 +7294,14 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "mutexify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz", + "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==", + "requires": { + "queue-tick": "^1.0.0" + } + }, "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -6785,6 +7312,11 @@ "thenify-all": "^1.0.0" } }, + "nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==" + }, "nanoclone": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", @@ -6800,6 +7332,16 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, + "napi-macros": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz", + "integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==" + }, + "nat-sampler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nat-sampler/-/nat-sampler-1.0.1.tgz", + "integrity": "sha512-yQvyNN7xbqR8crTKk3U8gRgpcV1Az+vfCEijiHu9oHHsnIl8n3x+yXNHl42M6L3czGynAVoOT9TqBfS87gDdcw==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6936,6 +7478,62 @@ "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==" }, + "noise-curve-ed": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/noise-curve-ed/-/noise-curve-ed-2.0.1.tgz", + "integrity": "sha512-8HMZ40Wmarg8RQjVemLrjB49JSL6eGeOD+tlzaQW5/p+hNPfHFEMC3UZZ57zUqUprMuz6GN+gsPExpz2DWL+iA==", + "requires": { + "b4a": "^1.1.0", + "nanoassert": "^2.0.0", + "sodium-universal": "^4.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, + "noise-handshake": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/noise-handshake/-/noise-handshake-3.0.2.tgz", + "integrity": "sha512-4RQ9/6R/GLKA3DPcLDeo954ZBZezHBNpc4YnhyisZ9DPiTRnc81aGdCbH3J9pHllDfj82/f9wKHRRsU7C6pNEg==", + "requires": { + "b4a": "^1.1.0", + "nanoassert": "^2.0.0", + "sodium-universal": "^4.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -7734,6 +8332,38 @@ } } }, + "protocol-buffers-encodings": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-encodings/-/protocol-buffers-encodings-1.2.0.tgz", + "integrity": "sha512-daeNPuKh1NlLD1uDfbLpD+xyUTc07nEtfHwmBZmt/vH0B7VOM+JOCOpDcx9ZRpqHjAiIkGqyTDi+wfGSl17R9w==", + "requires": { + "b4a": "^1.6.0", + "signed-varint": "^2.0.1", + "varint": "5.0.0" + } + }, + "protomux": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/protomux/-/protomux-3.4.1.tgz", + "integrity": "sha512-V8MDCiDGqxM4/hGOewmezbCX7HZfcYGtpdO0MK6pEhBLSknENuqqE98OEWyQuwDalfHULVO8ml7LSwTB5g5Z6g==", + "requires": { + "b4a": "^1.3.1", + "compact-encoding": "^2.5.1", + "queue-tick": "^1.0.0", + "safety-catch": "^1.0.1" + } + }, + "protomux-rpc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/protomux-rpc/-/protomux-rpc-1.3.0.tgz", + "integrity": "sha512-G+zCpEujLsW+lQ75YXVdPfXKzxnP5F7IceVyz2B1ypWdH4NDf2n2ObkoUjdUrEMWgn+3fjXdY7ehkXLac+mNPQ==", + "requires": { + "bits-to-bytes": "^1.0.0", + "compact-encoding": "^2.6.1", + "compact-encoding-bitfield": "^1.0.0", + "protomux": "^3.2.1" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -7851,11 +8481,70 @@ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" }, + "quickbit-universal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/quickbit-universal/-/quickbit-universal-2.0.3.tgz", + "integrity": "sha512-cdyTFj+fa7iGHMNM/gMXJscTiRZt6yIhRx8fYIFT+xaxXPB3dmSy1mY9BkDf21ONqb6PZMggm5E1Huj+72+bjQ==", + "requires": { + "b4a": "^1.6.0", + "node-gyp-build": "^4.5.0", + "simdle-universal": "^1.1.0" + } + }, + "random-access-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.0.0.tgz", + "integrity": "sha512-9nk4xujIoF1bGVxd6XiM/3cnJevNYLAjv9nPmJXbCn/3fxXBr9jb9IodIDJvtiTKFwVzlwGzGGqM+zVbRw6Yaw==", + "requires": { + "fs-native-extensions": "^1.1.0", + "random-access-storage": "^3.0.0" + } + }, + "random-access-memory": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/random-access-memory/-/random-access-memory-5.0.1.tgz", + "integrity": "sha512-cvbc93Y85ULzHTZeMK5eVwaVFK65DWibV/wUUFR82hDGUEZ5kZD+hx1wlJnDc4gl3dWF4B5JUNjMFEewY6w6Uw==", + "requires": { + "b4a": "^1.6.0", + "is-options": "^1.0.2", + "random-access-storage": "^2.2.1" + }, + "dependencies": { + "random-access-storage": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-2.3.0.tgz", + "integrity": "sha512-+sGRoANV5/g+JuHXNmML7F+fm7zM2MkXOOmBDCSM2C5ov35fSyQYCQ3My/hxe1jkmSp6pyAeGW3jA2iC0rfZ4g==", + "requires": { + "events": "^3.3.0", + "queue-tick": "^1.0.0" + } + } + } + }, + "random-access-storage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-3.0.0.tgz", + "integrity": "sha512-f9KeHUMhrqj0hE2d4HbUXk/Cd5vElaVzdA0PuqPTlnxsG3dDvwQaMg8POT5tWK6UxJ80zAONZpHgLPMnnff1RA==", + "requires": { + "events": "^3.3.0", + "queue-tick": "^1.0.0" + } + }, + "random-array-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-array-iterator/-/random-array-iterator-1.0.0.tgz", + "integrity": "sha512-u7xCM93XqKEvPTP6xZp2ehttcAemKnh73oKNf1FvzuVCfpt6dILDt1Kxl1LeBjm2iNIeR49VGFhy4Iz3yOun+Q==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -8207,6 +8896,14 @@ "decimal.js-light": "^2.4.1" } }, + "record-cache": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz", + "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==", + "requires": { + "b4a": "^1.3.1" + } + }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", @@ -8471,6 +9168,16 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "safety-catch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.2.tgz", + "integrity": "sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==" + }, + "same-data": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/same-data/-/same-data-1.0.0.tgz", + "integrity": "sha512-Eqn7N2yV+aKMlUHTRqUwYG1Iv0cJqjlvLKj/GoP5PozJn361QaOYX14+v87r7NqQUZC22noP/LfLrSQiPwAygw==" + }, "sass": { "version": "1.56.0", "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.0.tgz", @@ -8614,6 +9321,42 @@ "safe-buffer": "^5.0.1" } }, + "sha256-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha256-universal/-/sha256-universal-1.2.1.tgz", + "integrity": "sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==", + "requires": { + "b4a": "^1.0.1", + "sha256-wasm": "^2.2.1" + } + }, + "sha256-wasm": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/sha256-wasm/-/sha256-wasm-2.2.2.tgz", + "integrity": "sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "sha512-universal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sha512-universal/-/sha512-universal-1.2.1.tgz", + "integrity": "sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==", + "requires": { + "b4a": "^1.0.1", + "sha512-wasm": "^2.3.1" + } + }, + "sha512-wasm": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/sha512-wasm/-/sha512-wasm-2.3.4.tgz", + "integrity": "sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==", + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8629,6 +9372,14 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shuffled-priority-queue": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/shuffled-priority-queue/-/shuffled-priority-queue-2.1.0.tgz", + "integrity": "sha512-xhdh7fHyMsr0m/w2kDfRJuBFRS96b9l8ZPNWGaQ+PMvnUnZ/Eh+gJJ9NsHBd7P9k0399WYlCLzsy18EaMfyadA==", + "requires": { + "unordered-set": "^2.0.1" + } + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -8644,6 +9395,31 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "signed-varint": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/signed-varint/-/signed-varint-2.0.1.tgz", + "integrity": "sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw==", + "requires": { + "varint": "~5.0.0" + } + }, + "simdle-universal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simdle-universal/-/simdle-universal-1.1.0.tgz", + "integrity": "sha512-ZH+N1FHGksLWcNgpuaVaX2pI86Zzu58Y5S1mNXd2HuMId75eRsrtpAmCG1RZJXclViUiACVsLA3LD3TQVpha5Q==", + "requires": { + "b4a": "^1.6.0", + "node-gyp-build": "^4.2.3" + } + }, + "siphash24": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/siphash24/-/siphash24-1.3.1.tgz", + "integrity": "sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==", + "requires": { + "nanoassert": "^2.0.0" + } + }, "sister": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sister/-/sister-3.0.2.tgz", @@ -8691,6 +9467,82 @@ } } }, + "sodium-javascript": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/sodium-javascript/-/sodium-javascript-0.8.0.tgz", + "integrity": "sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "xsalsa20": "^1.0.0" + } + }, + "sodium-native": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.0.tgz", + "integrity": "sha512-U5nZ0sFHtPYJncNBS5SkmBnpSDeVpWuzo//07meNVO4p0K8ybcLuQxDX4ByCeVdT/9OLGa1ayvr1pB5iMBbh0g==", + "requires": { + "node-gyp-build": "^4.3.0" + } + }, + "sodium-secretstream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/sodium-secretstream/-/sodium-secretstream-1.1.0.tgz", + "integrity": "sha512-Qg7D2xomELDjDCWAmE4izk1aecG/il8pQIGmSWFaKgah/V58BVWG/PuSZF6vseTpcqnetIFGaOWzmPNzyTD50A==", + "requires": { + "b4a": "^1.1.1", + "sodium-universal": "^4.0.0" + }, + "dependencies": { + "sodium-universal": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", + "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^4.0.0", + "xsalsa20": "^1.0.0" + } + } + } + }, + "sodium-universal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-3.1.0.tgz", + "integrity": "sha512-N2gxk68Kg2qZLSJ4h0NffEhp4BjgWHCHXVlDi1aG1hA3y+ZeWEmHqnpml8Hy47QzfL1xLy5nwr9LcsWAg2Ep0A==", + "requires": { + "blake2b": "^2.1.1", + "chacha20-universal": "^1.0.4", + "nanoassert": "^2.0.0", + "resolve": "^1.17.0", + "sha256-universal": "^1.1.0", + "sha512-universal": "^1.1.0", + "siphash24": "^1.0.1", + "sodium-javascript": "~0.8.0", + "sodium-native": "^3.2.0", + "xsalsa20": "^1.0.0" + }, + "dependencies": { + "sodium-native": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", + "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", + "requires": { + "node-gyp-build": "^4.3.0" + } + } + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -8987,6 +9839,15 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" }, + "streamx": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", + "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9250,11 +10111,21 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "time-ordered-set": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/time-ordered-set/-/time-ordered-set-1.0.2.tgz", + "integrity": "sha512-vGO99JkxvgX+u+LtOKQEpYf31Kj3i/GNwVstfnh4dyINakMgeZCpew1e3Aj+06hEslhtHEd52g7m5IV+o1K8Mw==" + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==" }, + "timeout-refresh": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-2.0.1.tgz", + "integrity": "sha512-SVqEcMZBsZF9mA78rjzCrYrUs37LMJk3ShZ851ygZYW1cMeIjs9mL57KO6Iv5mmjSQnOe/29/VAfGXo+oRCiVw==" + }, "tiny-secp256k1": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.1.tgz", @@ -9398,6 +10269,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, + "turbo-hash-map": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/turbo-hash-map/-/turbo-hash-map-1.0.3.tgz", + "integrity": "sha512-r7/5Q48HTqbPEZsXC1AR5hUeMn/RfB6o0rokQfLVeikEMjGOzICBuMj6sZSV9bfpHxXGB3cA0xHmWHlYiy1XTw==", + "requires": { + "b4a": "^1.3.1" + } + }, "tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", @@ -9557,6 +10436,18 @@ } } }, + "udx-native": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.5.3.tgz", + "integrity": "sha512-xoMrEYR5Hahsvx04w06WSc52Sq0Xe2KQtbucyixhIlg/paWN+PXN1J3Ca6h/67K9fo1kB+j8C3fAik/Jv5Q1Mg==", + "requires": { + "b4a": "^1.5.0", + "events": "^3.3.0", + "napi-macros": "^2.0.0", + "node-gyp-build": "^4.4.0", + "streamx": "^2.12.0" + } + }, "uint8array-tools": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.7.tgz", @@ -9690,6 +10581,16 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" }, + "unix-path-resolve": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unix-path-resolve/-/unix-path-resolve-1.0.2.tgz", + "integrity": "sha512-kG4g5nobBBaMnH2XbrS4sLUXEpx4nY2J3C6KAlAUcnahG2HChxSPVKWYrqEq76iTo+cyMkLUjqxGaQR2tz097Q==" + }, + "unordered-set": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unordered-set/-/unordered-set-2.0.1.tgz", + "integrity": "sha512-eUmNTPzdx+q/WvOHW0bgGYLWvWHNT3PTKEQLg0MAQhc0AHASHVHoP/9YytYd4RBVariqno/mEUhVZN98CmD7bg==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -9949,6 +10850,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "uv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uv-errors/-/uv-errors-1.0.1.tgz", + "integrity": "sha512-7aN1LGdPZPfpaoECdV2QvnZhCyRR3TFdBC4cHqoqEUAGuhGjouCssfBqum3jZkOlNK8Iq9mj+CwL6Ml1XrPH+Q==", + "optional": true + }, "uvu": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.3.tgz", @@ -9980,6 +10887,11 @@ "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", "integrity": "sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg==" }, + "varint": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", + "integrity": "sha512-gC13b/bWrqQoKY2EmROCZ+AR0jitc6DnDGaQ6Ls9QpKmuSgJB1eQ7H3KETtQm7qSdMWMKCmsshyCmUwMLh3OAA==" + }, "varuint-bitcoin": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", @@ -10160,6 +11072,11 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==" }, + "xache": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xache/-/xache-1.1.0.tgz", + "integrity": "sha512-RQGZDHLy/uCvnIrAvaorZH/e6Dfrtxj16iVlGjkj4KD2/G/dNXNqhk5IdSucv5nSSnDK00y8Y/2csyRdHveJ+Q==" + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -10180,6 +11097,11 @@ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==" }, + "xsalsa20": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xsalsa20/-/xsalsa20-1.2.0.tgz", + "integrity": "sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==" + }, "xss": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz", @@ -10304,6 +11226,14 @@ } } }, + "z32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/z32/-/z32-1.0.0.tgz", + "integrity": "sha512-p3DhBJckAZj5XwYMJYeLlkgJJ+aEyCoOjTpK17I/MofVs70eR+WQPXQpk1LEmMweB2JbUx0naFXPPI2EGaVX6w==", + "requires": { + "b4a": "^1.5.3" + } + }, "zen-observable": { "version": "0.8.15", "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", diff --git a/package.json b/package.json index 47735eed..f3883637 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "@lexical/react": "^0.7.5", "@opensearch-project/opensearch": "^1.1.0", "@prisma/client": "^2.30.3", + "@synonymdev/slashtags-auth": "^1.0.0-alpha.5", + "@synonymdev/slashtags-sdk": "^1.0.0-alpha.36", "apollo-server-micro": "^3.11.1", "async-retry": "^1.3.1", "aws-sdk": "^2.1248.0", diff --git a/pages/api/auth/[...nextauth].js b/pages/api/auth/[...nextauth].js index 792ebefb..32d75288 100644 --- a/pages/api/auth/[...nextauth].js +++ b/pages/api/auth/[...nextauth].js @@ -62,7 +62,8 @@ export default (req, res) => NextAuth(req, res, { }, providers: [ Providers.Credentials({ - // The name to display on the sign in form (e.g. 'Sign in with...') + id: 'lightning', + // The name to display on the sign in form (e.g. 'Sign in with...') name: 'Lightning', // The credentials is used to generate a suitable form on the sign in page. // You can specify whatever fields you are expecting to be submitted. @@ -75,6 +76,7 @@ export default (req, res) => NextAuth(req, res, { const { k1, pubkey } = credentials try { const lnauth = await prisma.lnAuth.findUnique({ where: { k1 } }) + await prisma.lnAuth.delete({ where: { k1 } }) if (lnauth.pubkey === pubkey) { let user = await prisma.user.findUnique({ where: { pubkey } }) const session = await getSession({ req }) @@ -89,7 +91,45 @@ export default (req, res) => NextAuth(req, res, { throw new Error('account not linked') } - await prisma.lnAuth.delete({ where: { k1 } }) + return user + } + } catch (error) { + console.log(error) + } + + return null + } + }), + Providers.Credentials({ + id: 'slashtags', + // The name to display on the sign in form (e.g. 'Sign in with...') + name: 'Slashtags', + // The credentials is used to generate a suitable form on the sign in page. + // You can specify whatever fields you are expecting to be submitted. + // e.g. domain, username, password, 2FA token, etc. + credentials: { + pubkey: { label: 'publickey', type: 'text' }, + k1: { label: 'k1', type: 'text' } + }, + async authorize (credentials, req) { + const { k1, pubkey } = credentials + try { + const lnauth = await prisma.lnAuth.findUnique({ where: { k1 } }) + await prisma.lnAuth.delete({ where: { k1 } }) + if (lnauth.pubkey === pubkey) { + let user = await prisma.user.findUnique({ where: { slashtagId: pubkey } }) + const session = await getSession({ req }) + if (!user) { + // if we are logged in, update rather than create + if (session?.user) { + user = await prisma.user.update({ where: { id: session.user.id }, data: { slashtagId: pubkey } }) + } else { + user = await prisma.user.create({ data: { name: pubkey.slice(0, 10), slashtagId: pubkey } }) + } + } else if (session && session.user?.id !== user.id) { + throw new Error('account not linked') + } + return user } } catch (error) { diff --git a/pages/api/graphql.js b/pages/api/graphql.js index 1134826c..ba81516d 100644 --- a/pages/api/graphql.js +++ b/pages/api/graphql.js @@ -5,6 +5,7 @@ import lnd from '../../api/lnd' import typeDefs from '../../api/typeDefs' import { getSession } from 'next-auth/client' import search from '../../api/search' +import slashtags from '../../api/slashtags' const apolloServer = new ApolloServer({ typeDefs, @@ -40,7 +41,8 @@ const apolloServer = new ApolloServer({ me: session ? session.user : null, - search + search, + slashtags } } }) diff --git a/pages/api/lnauth.js b/pages/api/lnauth.js index bbabb66e..b158242f 100644 --- a/pages/api/lnauth.js +++ b/pages/api/lnauth.js @@ -4,6 +4,8 @@ import secp256k1 from 'secp256k1' import models from '../../api/models' +const HOUR = 1000 * 60 * 60 + export default async ({ query }, res) => { try { const sig = Buffer.from(query.sig, 'hex') @@ -11,6 +13,11 @@ export default async ({ query }, res) => { const key = Buffer.from(query.key, 'hex') const signature = secp256k1.signatureImport(sig) if (secp256k1.ecdsaVerify(signature, k1, key)) { + const auth = await models.lnAuth.findUnique({ where: { k1: query.k1 } }) + if (!auth || auth.pubkey || auth.createdAt < Date.now() - HOUR) { + return res.status(400).json({ status: 'ERROR', reason: 'token expired' }) + } + await models.lnAuth.update({ where: { k1: query.k1 }, data: { pubkey: query.key } }) return res.status(200).json({ status: 'OK' }) } diff --git a/pages/invoices/[id].js b/pages/invoices/[id].js index 5a6812e8..df503270 100644 --- a/pages/invoices/[id].js +++ b/pages/invoices/[id].js @@ -1,6 +1,6 @@ import { useQuery } from '@apollo/client' import { Invoice } from '../../components/invoice' -import { LnQRSkeleton } from '../../components/lnqr' +import { QrSkeleton } from '../../components/qr' import LayoutCenter from '../../components/layout-center' import { useRouter } from 'next/router' import { INVOICE } from '../../fragments/wallet' @@ -24,7 +24,7 @@ function LoadInvoice () { return
error
} if (!data || loading) { - return + return } return diff --git a/pages/settings.js b/pages/settings.js index aceb1c25..b752eaab 100644 --- a/pages/settings.js +++ b/pages/settings.js @@ -8,7 +8,7 @@ import { getGetServerSideProps } from '../api/ssrApollo' import LoginButton from '../components/login-button' import { signIn } from 'next-auth/client' import ModalButton from '../components/modal-button' -import { LightningAuth } from '../components/lightning-auth' +import { LightningAuth, SlashtagsAuth } from '../components/lightning-auth' import { SETTINGS, SET_SETTINGS } from '../fragments/users' import { useRouter } from 'next/router' import Info from '../components/info' @@ -300,14 +300,11 @@ function AuthMethods ({ methods }) { ) const [obstacle, setObstacle] = useState() + const providers = Object.keys(methods).filter(k => k !== '__typename') + const unlink = async type => { // if there's only one auth method left - let links = 0 - links += methods.lightning ? 1 : 0 - links += methods.email ? 1 : 0 - links += methods.twitter ? 1 : 0 - links += methods.github ? 1 : 0 - + const links = providers.reduce((t, p) => t + (methods[p] ? 1 : 0), 0) if (links === 1) { setObstacle(type) } else { @@ -349,63 +346,78 @@ function AuthMethods ({ methods }) {
auth methods
- {methods.lightning - ? { - await unlink('lightning') - } + {providers && providers.map(provider => { + switch (provider) { + case 'email': + return methods.email + ? ( +
+ + +
+ ) + :
+ case 'lightning': + return methods.lightning + ? { + await unlink('lightning') + } + } + /> + : ( + }> +
+ +
+
) + case 'slashtags': + return methods.slashtags + ? { + await unlink('slashtags') + } + } + /> + : ( + }> +
+ +
+
) + default: + return ( + { + if (methods[provider]) { + await unlink(provider) + } else { + signIn(provider) + } + }} + text={methods[provider] ? 'Unlink' : 'Link'} + /> + ) } - /> - : ( - }> -
- -
-
)} - { - if (methods.twitter) { - await unlink('twitter') - } else { - signIn('twitter') - } - } - } - /> - { - if (methods.github) { - await unlink('github') - } else { - signIn('github') - } - } - } - /> - {methods.email - ? ( -
- - -
- ) - :
} + })} ) } diff --git a/pages/wallet.js b/pages/wallet.js index ad3e5cbb..deaa2285 100644 --- a/pages/wallet.js +++ b/pages/wallet.js @@ -4,7 +4,7 @@ import Link from 'next/link' import Button from 'react-bootstrap/Button' import * as Yup from 'yup' import { gql, useMutation, useQuery } from '@apollo/client' -import LnQR, { LnQRSkeleton } from '../components/lnqr' +import Qr, { QrSkeleton } from '../components/qr' import LayoutCenter from '../components/layout-center' import InputGroup from 'react-bootstrap/InputGroup' import { WithdrawlSkeleton } from './withdrawals/[id]' @@ -95,7 +95,7 @@ export function FundForm () { }, []) if (called && !error) { - return + return } return ( @@ -226,7 +226,7 @@ function LnQRWith ({ k1, encodedUrl }) { router.push(`/withdrawals/${data.lnWith.withdrawalId}`) } - return + return } export function LnWithdrawal () { @@ -246,7 +246,7 @@ export function LnWithdrawal () { if (error) return
error
if (!data) { - return + return } return diff --git a/prisma/migrations/20230117185647_slashtags/migration.sql b/prisma/migrations/20230117185647_slashtags/migration.sql new file mode 100644 index 00000000..bc4f4539 --- /dev/null +++ b/prisma/migrations/20230117185647_slashtags/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - A unique constraint covering the columns `[slashtagId]` on the table `users` will be added. If there are existing duplicate values, this will fail. + +*/ +-- AlterTable +ALTER TABLE "users" ADD COLUMN "slashtagId" TEXT; + +-- CreateIndex +CREATE UNIQUE INDEX "users.slashtagId_unique" ON "users"("slashtagId"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 327230d3..e540b980 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -37,6 +37,7 @@ model User { checkedNotesAt DateTime? fiatCurrency String @default("USD") pubkey String? @unique + slashtagId String? @unique trust Float @default(0) upvoteTrust Float @default(0) lastSeenAt DateTime? diff --git a/styles/globals.scss b/styles/globals.scss index e3905d35..1afdda61 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -206,6 +206,10 @@ div[contenteditable]:disabled, fill: #212529; } +.btn-grey-medium svg { + fill: #212529; +} + .fresh { background-color: var(--theme-clickToContextColor); border-radius: .4rem; diff --git a/svgs/slashtags.svg b/svgs/slashtags.svg new file mode 100644 index 00000000..97a30926 --- /dev/null +++ b/svgs/slashtags.svg @@ -0,0 +1,4 @@ + + + +