mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-26 11:37:40 +02:00
add youtube, twitter, and invoice embeds
This commit is contained in:
@@ -13,5 +13,11 @@
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
|
||||
<script
|
||||
async
|
||||
src="https://platform.twitter.com/widgets.js"
|
||||
charset="utf-8"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -17,6 +17,7 @@
|
||||
"framer-motion": "^7.10.3",
|
||||
"idb": "^7.1.1",
|
||||
"identicon.js": "^2.3.3",
|
||||
"light-bolt11-decoder": "^2.1.0",
|
||||
"moment": "^2.29.4",
|
||||
"noble-secp256k1": "^1.2.14",
|
||||
"react": "^18.2.0",
|
||||
@@ -28,10 +29,13 @@
|
||||
"react-singleton-hook": "^4.0.1",
|
||||
"react-use": "^17.4.0",
|
||||
"rehype-external-links": "^2.0.1",
|
||||
"rehype-truncate": "^1.2.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-images": "^3.1.0",
|
||||
"remark-linkify-regex": "^1.2.1",
|
||||
"remark-unwrap-images": "^3.0.1",
|
||||
"rxjs": "^7.8.0"
|
||||
"rxjs": "^7.8.0",
|
||||
"webln": "^0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.26.0",
|
||||
|
38
src/components/invoice-button.tsx
Normal file
38
src/components/invoice-button.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useState } from "react";
|
||||
import { Button } from "@chakra-ui/react";
|
||||
import { requestProvider } from "webln";
|
||||
import { getReadableAmount, parsePaymentRequest } from "../helpers/bolt11";
|
||||
|
||||
export type InvoiceButtonProps = {
|
||||
paymentRequest: string;
|
||||
};
|
||||
export const InvoiceButton = ({ paymentRequest }: InvoiceButtonProps) => {
|
||||
const invoice = parsePaymentRequest(paymentRequest);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const handleClick = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const provider = await requestProvider();
|
||||
await provider.enable();
|
||||
const response = await provider.sendPayment(paymentRequest);
|
||||
if (response.preimage) {
|
||||
console.log("Paid");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to pay invoice");
|
||||
console.log(e);
|
||||
}
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
colorScheme="yellow"
|
||||
variant="outline"
|
||||
onClick={handleClick}
|
||||
isLoading={loading}
|
||||
>
|
||||
⚡ Invoice for {invoice.amount ? getReadableAmount(invoice.amount) : "♾️"}
|
||||
</Button>
|
||||
);
|
||||
};
|
@@ -23,9 +23,9 @@ const MobileLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
return (
|
||||
<Flex direction="column" height="100%">
|
||||
<Box flexGrow={1} overflow="auto">
|
||||
<Flex flexGrow={1} direction="column" overflow="hidden">
|
||||
{children}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex flexShrink={0} gap="2" padding="2">
|
||||
<IconButton
|
||||
icon={<img src={homeIcon} />}
|
||||
@@ -77,9 +77,9 @@ const DesktopLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
<Button onClick={() => navigate("/settings")}>Settings</Button>
|
||||
<ConnectedRelays />
|
||||
</VStack>
|
||||
<Box flexGrow={1} overflow="hidden">
|
||||
<Flex flexGrow={1} direction="column" overflow="hidden">
|
||||
<ErrorBoundary>{children}</ErrorBoundary>
|
||||
</Box>
|
||||
</Flex>
|
||||
<VStack width="15rem" pt="2" alignItems="stretch" flexShrink={0}>
|
||||
<Button onClick={() => navigate("/")}>Manage Follows</Button>
|
||||
</VStack>
|
||||
|
@@ -1,32 +1,102 @@
|
||||
import { Image, Link, LinkProps } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
import {
|
||||
AspectRatio,
|
||||
Image,
|
||||
ImageProps,
|
||||
Link,
|
||||
LinkProps,
|
||||
} from "@chakra-ui/react";
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkImages from "remark-images";
|
||||
import remarkUnwrapImages from "remark-unwrap-images";
|
||||
import rehypeExternalLinks from "rehype-external-links";
|
||||
// @ts-ignore
|
||||
// import rehypeTruncate from "rehype-truncate";
|
||||
// @ts-ignore
|
||||
import linkifyRegex from "remark-linkify-regex";
|
||||
import { InvoiceButton } from "./invoice-button";
|
||||
import { TweetEmbed } from "./tweet-embed";
|
||||
|
||||
const lightningInvoiceRegExp = /(lightning:)?LNBC[A-Za-z0-9]+/i;
|
||||
|
||||
// copied from https://stackoverflow.com/a/37704433
|
||||
const youtubeVideoLink =
|
||||
/^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube(-nocookie)?\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/i;
|
||||
|
||||
const twitterLink =
|
||||
/https?:\/\/twitter\.com\/(?:\#!\/)?(\w+)\/status(es)?\/(\d+)/i;
|
||||
|
||||
const CustomLink = (props: LinkProps) => <Link color="blue.500" {...props} />;
|
||||
const CustomImage = (props: ImageProps) => (
|
||||
<AspectRatio ratio={16 / 10} maxWidth="30rem">
|
||||
<Image {...props} />
|
||||
</AspectRatio>
|
||||
);
|
||||
|
||||
const HandleLinkTypes = (props: LinkProps) => {
|
||||
let href = props.href;
|
||||
// @ts-ignore
|
||||
if (href === "javascript:void(0)") href = String(props.children[0]);
|
||||
|
||||
if (href) {
|
||||
if (lightningInvoiceRegExp.test(href)) {
|
||||
return <InvoiceButton paymentRequest={href.replace(/lightning:/i, "")} />;
|
||||
}
|
||||
if (youtubeVideoLink.test(href)) {
|
||||
const parts = youtubeVideoLink.exec(href);
|
||||
|
||||
return parts ? (
|
||||
<AspectRatio ratio={16 / 10} maxWidth="30rem">
|
||||
<iframe
|
||||
src={`https://www.youtube.com/embed/${parts[6]}`}
|
||||
title="YouTube video player"
|
||||
frameBorder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</AspectRatio>
|
||||
) : (
|
||||
<CustomLink {...props} />
|
||||
);
|
||||
}
|
||||
if (twitterLink.test(href)) {
|
||||
return <TweetEmbed href={href} conversation={false} />;
|
||||
}
|
||||
}
|
||||
return <CustomLink {...props} />;
|
||||
};
|
||||
|
||||
const components = {
|
||||
img: Image,
|
||||
a: CustomLink,
|
||||
img: CustomImage,
|
||||
a: HandleLinkTypes,
|
||||
};
|
||||
|
||||
export type PostContentsProps = {
|
||||
content: string;
|
||||
maxChars?: number;
|
||||
};
|
||||
|
||||
export const PostContents = React.memo(({ content }: PostContentsProps) => {
|
||||
const fixedLines = content.replace(/(?<! )\n/g, " \n");
|
||||
export const PostContents = React.memo(
|
||||
({ content, maxChars }: PostContentsProps) => {
|
||||
const fixedLines = content.replace(/(?<! )\n/g, " \n");
|
||||
|
||||
return (
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[remarkImages, remarkUnwrapImages, remarkGfm]}
|
||||
rehypePlugins={[[rehypeExternalLinks, { target: "_blank" }]]}
|
||||
components={components}
|
||||
>
|
||||
{fixedLines}
|
||||
</ReactMarkdown>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<ReactMarkdown
|
||||
remarkPlugins={[
|
||||
remarkImages,
|
||||
remarkUnwrapImages,
|
||||
remarkGfm,
|
||||
linkifyRegex(lightningInvoiceRegExp),
|
||||
]}
|
||||
rehypePlugins={[
|
||||
[rehypeExternalLinks, { target: "_blank" }],
|
||||
// [rehypeTruncate, { maxChars, disable: !maxChars }],
|
||||
]}
|
||||
components={components}
|
||||
>
|
||||
{fixedLines}
|
||||
</ReactMarkdown>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useRef } from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -70,8 +70,8 @@ export const Post = React.memo(({ event }: PostProps) => {
|
||||
</CardHeader>
|
||||
<CardBody pt="2" pb="0" pr="0" pl="0">
|
||||
<VStack alignItems="flex-start" justifyContent="stretch">
|
||||
<Box maxHeight="20rem" overflow="hidden" width="100%">
|
||||
<PostContents content={event.content}/>
|
||||
<Box overflow="hidden" width="100%">
|
||||
<PostContents content={event.content} maxChars={300} />
|
||||
</Box>
|
||||
{isLong && (
|
||||
<>
|
||||
|
27
src/components/tweet-embed.tsx
Normal file
27
src/components/tweet-embed.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export type TweetEmbedProps = {
|
||||
href: string;
|
||||
conversation?: boolean;
|
||||
};
|
||||
|
||||
export const TweetEmbed = ({ href, conversation }: TweetEmbedProps) => {
|
||||
const ref = useRef<HTMLQuoteElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
// @ts-ignore
|
||||
window.twttr.widgets.load();
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<blockquote
|
||||
className="twitter-tweet"
|
||||
ref={ref}
|
||||
data-conversation={conversation ? undefined : "none"}
|
||||
>
|
||||
<a href={href}></a>
|
||||
</blockquote>
|
||||
);
|
||||
};
|
38
src/helpers/bolt11.ts
Normal file
38
src/helpers/bolt11.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
decode,
|
||||
Section,
|
||||
AmountSection,
|
||||
DescriptionSection,
|
||||
} from "light-bolt11-decoder";
|
||||
|
||||
export type ParsedInvoice = {
|
||||
paymentRequest: string;
|
||||
description: string;
|
||||
amount?: number;
|
||||
};
|
||||
|
||||
function isDescription(section: Section): section is DescriptionSection {
|
||||
return section.name === "description";
|
||||
}
|
||||
function isAmount(section: Section): section is AmountSection {
|
||||
return section.name === "amount";
|
||||
}
|
||||
|
||||
export function parsePaymentRequest(paymentRequest: string): ParsedInvoice {
|
||||
const decoded = decode(paymentRequest);
|
||||
|
||||
return {
|
||||
paymentRequest: decoded.paymentRequest,
|
||||
description: decoded.sections.find(isDescription)?.value ?? "",
|
||||
amount: decoded.sections.find(isAmount)?.value,
|
||||
};
|
||||
}
|
||||
|
||||
export function getReadableAmount(amount: number) {
|
||||
const amountInSats = amount / 1000;
|
||||
if (amountInSats > 1000000) {
|
||||
return `${amountInSats / 1000000}M sats`;
|
||||
} else if (amountInSats > 1000) {
|
||||
return `${amountInSats / 1000}K sats`;
|
||||
} else return `${amountInSats} sats`;
|
||||
}
|
@@ -1,10 +1,10 @@
|
||||
import React from "react";
|
||||
import { ChakraProvider } from "@chakra-ui/react";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { BrowserRouter, HashRouter } from "react-router-dom";
|
||||
import theme from "../theme";
|
||||
|
||||
export const Providers = ({ children }: { children: React.ReactNode }) => (
|
||||
<ChakraProvider theme={theme}>
|
||||
<BrowserRouter>{children}</BrowserRouter>
|
||||
<HashRouter>{children}</HashRouter>
|
||||
</ChakraProvider>
|
||||
);
|
||||
|
@@ -1,28 +1,4 @@
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
nostr?: {
|
||||
enabled: boolean;
|
||||
getPublicKey: () => Promise<string> | string;
|
||||
signEvent: (event: NostrEvent) => Promise<NostrEvent> | NostrEvent;
|
||||
getRelays: () =>
|
||||
| Record<string, { read: boolean; write: boolean }>
|
||||
| string[];
|
||||
nip04?: {
|
||||
encrypt: (
|
||||
pubkey: string,
|
||||
plaintext: string
|
||||
) => Promise<string> | string;
|
||||
decrypt: (
|
||||
pubkey: string,
|
||||
ciphertext: string
|
||||
) => Promise<string> | string;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class IdentityService {
|
||||
setup = new BehaviorSubject(false);
|
||||
|
151
src/types/light-bolt11-decoder.d.ts
vendored
Normal file
151
src/types/light-bolt11-decoder.d.ts
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
declare module "light-bolt11-decoder" {
|
||||
// types for https://www.npmjs.com/package/light-bolt11-decoder
|
||||
export type LightningNetworkSection = {
|
||||
name: "lightning_network";
|
||||
letters: string;
|
||||
};
|
||||
export type CoinNetworkSection = {
|
||||
name: "coin_network";
|
||||
letters: string;
|
||||
};
|
||||
export type AmountSection = {
|
||||
name: "amount";
|
||||
letters: string;
|
||||
value: number;
|
||||
};
|
||||
export type SeparatorSection = {
|
||||
name: "separator";
|
||||
letters: string;
|
||||
};
|
||||
export type TimestampSection = {
|
||||
name: "timestamp";
|
||||
letters: string;
|
||||
value: number;
|
||||
};
|
||||
export type PaymentHashSection = {
|
||||
name: "payment_hash";
|
||||
tag: "p";
|
||||
letters: string;
|
||||
value: string;
|
||||
};
|
||||
export type DescriptionSection = {
|
||||
name: "description";
|
||||
tag: "d";
|
||||
letters: string;
|
||||
value: string;
|
||||
};
|
||||
export type PaymentSecretSection = {
|
||||
name: "payment_secret";
|
||||
tag: "s";
|
||||
letters: string;
|
||||
value: string;
|
||||
};
|
||||
export type ExpirySection = {
|
||||
name: "expiry";
|
||||
tag: "x";
|
||||
letters: string;
|
||||
value: number;
|
||||
};
|
||||
export type MinFinalCltvExpiry = {
|
||||
name: "min_final_cltv_expiry";
|
||||
tag: "c";
|
||||
letters: string;
|
||||
value: number;
|
||||
};
|
||||
export type FeatureBitsSection = {
|
||||
name: "feature_bits";
|
||||
tag: "9";
|
||||
letters: string;
|
||||
value: {
|
||||
word_length: number;
|
||||
option_data_loss_protect: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
initial_routing_sync: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
option_upfront_shutdown_script: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
gossip_queries: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
var_onion_optin: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
gossip_queries_ex: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
option_static_remotekey: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
payment_secret: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
basic_mpp: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
option_support_large_channel: {
|
||||
required: boolean;
|
||||
supported: boolean;
|
||||
};
|
||||
extra_bits: {
|
||||
start_bit: number;
|
||||
bits: number[];
|
||||
has_required: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
export type RouteHintSection = {
|
||||
name: "route_hint";
|
||||
tag: "r";
|
||||
letters: string;
|
||||
value: {
|
||||
pubkey: string;
|
||||
short_channel_id: string;
|
||||
fee_base_msat: number;
|
||||
fee_proportional_millionths: number;
|
||||
cltv_expiry_delta: number;
|
||||
}[];
|
||||
};
|
||||
export type SignatureSection = {
|
||||
name: "signature";
|
||||
letters: string;
|
||||
value: string;
|
||||
};
|
||||
export type ChecksumSection = {
|
||||
name: "checksum";
|
||||
letters: string;
|
||||
};
|
||||
|
||||
export type Section =
|
||||
| LightningNetworkSection
|
||||
| CoinNetworkSection
|
||||
| AmountSection
|
||||
| SeparatorSection
|
||||
| TimestampSection
|
||||
| PaymentHashSection
|
||||
| DescriptionSection
|
||||
| PaymentSecretSection
|
||||
| ExpirySection
|
||||
| FeatureBitsSection
|
||||
| RouteHintSection
|
||||
| SignatureSection
|
||||
| ChecksumSection;
|
||||
|
||||
export type ParsedInvoice = {
|
||||
paymentRequest: string;
|
||||
sections: Section[];
|
||||
expiry: number;
|
||||
};
|
||||
export function decode(paymentRequest: string): ParsedInvoice;
|
||||
}
|
24
src/types/nostr-extensions.d.ts
vendored
Normal file
24
src/types/nostr-extensions.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
import { NostrEvent } from "./nostr-event";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
nostr?: {
|
||||
enabled: boolean;
|
||||
getPublicKey: () => Promise<string> | string;
|
||||
signEvent: (event: NostrEvent) => Promise<NostrEvent> | NostrEvent;
|
||||
getRelays: () =>
|
||||
| Record<string, { read: boolean; write: boolean }>
|
||||
| string[];
|
||||
nip04?: {
|
||||
encrypt: (
|
||||
pubkey: string,
|
||||
plaintext: string
|
||||
) => Promise<string> | string;
|
||||
decrypt: (
|
||||
pubkey: string,
|
||||
ciphertext: string
|
||||
) => Promise<string> | string;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ export const UserPostsTab = ({ pubkey }: { pubkey: string }) => {
|
||||
return <SkeletonText />;
|
||||
}
|
||||
|
||||
if (timeline.length > 20) timeline.length = 20;
|
||||
if (timeline.length > 30) timeline.length = 30;
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="2" pr="2" pl="2">
|
||||
|
@@ -31,7 +31,7 @@ export const UserRepliesTab = ({ pubkey }: { pubkey: string }) => {
|
||||
return <SkeletonText />;
|
||||
}
|
||||
|
||||
if (timeline.length > 20) timeline.length = 20;
|
||||
if (timeline.length > 30) timeline.length = 30;
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="2" pr="2" pl="2">
|
||||
|
99
yarn.lock
99
yarn.lock
@@ -2441,6 +2441,13 @@
|
||||
magic-string "^0.25.0"
|
||||
string.prototype.matchall "^4.0.6"
|
||||
|
||||
"@types/chrome@^0.0.74":
|
||||
version "0.0.74"
|
||||
resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.74.tgz#f69827c48fcf7fecc90c96089807661749a5a5e3"
|
||||
integrity sha512-hzosS5CkQcIKCgxcsV2AzbJ36KNxG/Db2YEN/erEu7Boprg+KpMDLBQqKFmSo+JkQMGqRcicUyqCowJpuT+C6A==
|
||||
dependencies:
|
||||
"@types/filesystem" "*"
|
||||
|
||||
"@types/debug@^4.0.0":
|
||||
version "4.1.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
|
||||
@@ -2458,6 +2465,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2"
|
||||
integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
|
||||
|
||||
"@types/filesystem@*":
|
||||
version "0.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.32.tgz#307df7cc084a2293c3c1a31151b178063e0a8edf"
|
||||
integrity sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==
|
||||
dependencies:
|
||||
"@types/filewriter" "*"
|
||||
|
||||
"@types/filewriter@*":
|
||||
version "0.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.29.tgz#a48795ecadf957f6c0d10e0c34af86c098fa5bee"
|
||||
integrity sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==
|
||||
|
||||
"@types/hast@^2.0.0":
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
|
||||
@@ -2731,11 +2750,21 @@ balanced-match@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
bech32-buffer@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bech32-buffer/-/bech32-buffer-0.2.1.tgz#8106f2f51bcb2ba1d9fb7718905c3042c5be2fcd"
|
||||
integrity sha512-fCG1TyZuCN48Sdw97p/IR39fvqpFlWDVpG7qnuU1Uc3+Xtc/0uqAp8U7bMW/bGuVF5CcNVIXwxQsWwUr6un6FQ==
|
||||
|
||||
bech32@^1.1.2:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
|
||||
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
|
||||
|
||||
better-path-resolve@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d"
|
||||
@@ -2743,6 +2772,11 @@ better-path-resolve@1.0.0:
|
||||
dependencies:
|
||||
is-windows "^1.0.0"
|
||||
|
||||
bn.js@^4.11.8:
|
||||
version "4.12.0"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
@@ -2787,6 +2821,14 @@ buffer-from@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
builtin-modules@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
||||
@@ -3641,6 +3683,11 @@ identicon.js@^2.3.3:
|
||||
resolved "https://registry.yarnpkg.com/identicon.js/-/identicon.js-2.3.3.tgz#c505b8d60ecc6ea13bbd991a33964c44c1ad60a1"
|
||||
integrity sha512-/qgOkXKZ7YbeCYbawJ9uQQ3XJ3uBg9VDpvHjabCAPp6aRMhjLaFAxG90+1TxzrhKaj6AYpVGrx6UXQfQA41UEA==
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
ignore@^5.2.0:
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
|
||||
@@ -3982,6 +4029,15 @@ leven@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
||||
integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
|
||||
|
||||
light-bolt11-decoder@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/light-bolt11-decoder/-/light-bolt11-decoder-2.1.0.tgz#46b122790ae0eb415841227eba770eae7303ecf5"
|
||||
integrity sha512-/AaSWTldx3aaFD7DgMVbX77MVEgLEPI0Zyx4Fjg23u3WpEoc536vz5LTXBU8oXAcrEcyDyn5GpBi2pEYuL351Q==
|
||||
dependencies:
|
||||
bech32 "^1.1.2"
|
||||
bn.js "^4.11.8"
|
||||
buffer "^6.0.3"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
@@ -5108,6 +5164,11 @@ rehype-external-links@^2.0.1:
|
||||
unified "^10.0.0"
|
||||
unist-util-visit "^4.0.0"
|
||||
|
||||
rehype-truncate@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/rehype-truncate/-/rehype-truncate-1.2.2.tgz#fbb75bad4ad13d89d7dab2cf88c205fe48a4aa27"
|
||||
integrity sha512-zj2FxxC3rm8bg6loesMdS/+BuGpp89mu+12VsJrBzN5kKgOxKwtawscQXElyt2BnxU2pG3hkoyb3Euc3Q7F38A==
|
||||
|
||||
remark-gfm@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-3.0.1.tgz#0b180f095e3036545e9dddac0e8df3fa5cfee54f"
|
||||
@@ -5129,6 +5190,15 @@ remark-images@^3.1.0:
|
||||
unist-util-is "^5.0.0"
|
||||
unist-util-visit-parents "^5.0.0"
|
||||
|
||||
remark-linkify-regex@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-linkify-regex/-/remark-linkify-regex-1.2.1.tgz#5121ad7f8297a7d75e56df4d87c808052d325fc8"
|
||||
integrity sha512-aKZAFcZWzrw64m1eTKfVgiZ9iKhZ5vxeOVoACjCd9ahPpKpdnAz++z0qVaR7h0z5nryrvUrTQvIyFieHkdEfCA==
|
||||
dependencies:
|
||||
unicode-word-regex "^1.0.1"
|
||||
unist-util-flatmap "1.0.x"
|
||||
unist-util-visit-parents "2.0.x"
|
||||
|
||||
remark-parse@^10.0.0:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775"
|
||||
@@ -5752,6 +5822,11 @@ unicode-property-aliases-ecmascript@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
|
||||
integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
|
||||
|
||||
unicode-word-regex@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/unicode-word-regex/-/unicode-word-regex-1.1.0.tgz#cdd6910e4e413606e704e139079bcab2b91040e3"
|
||||
integrity sha512-2HlIXyag8yi0+AsB1Rx88gSuzw4hS/PgrcTbzkqIW/RBdi2VSp1rRr55RS+HszErwlSRAoA9jhM6L/x+xtu41w==
|
||||
|
||||
unified@^10.0.0:
|
||||
version "10.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
|
||||
@@ -5779,11 +5854,21 @@ unist-builder@^3.0.0:
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
|
||||
unist-util-flatmap@1.0.x:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-flatmap/-/unist-util-flatmap-1.0.0.tgz#f914ed6b36ff040afce938d848f379f88b94b448"
|
||||
integrity sha512-IG32jcKJlhARCYT2LsYPJWdoXYkzz3ESAdl1aa2hn9Auh+cgUmU6wgkII4yCc/1GgeWibRdELdCZh/p3QKQ1dQ==
|
||||
|
||||
unist-util-generated@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113"
|
||||
integrity sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==
|
||||
|
||||
unist-util-is@^2.1.2:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.3.tgz#459182db31f4742fceaea88d429693cbf0043d20"
|
||||
integrity sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==
|
||||
|
||||
unist-util-is@^5.0.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236"
|
||||
@@ -5803,6 +5888,13 @@ unist-util-stringify-position@^3.0.0:
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
|
||||
unist-util-visit-parents@2.0.x:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217"
|
||||
integrity sha512-6B0UTiMfdWql4cQ03gDTCSns+64Zkfo2OCbK31Ov0uMizEz+CJeAp0cgZVb5Fhmcd7Bct2iRNywejT0orpbqUA==
|
||||
dependencies:
|
||||
unist-util-is "^2.1.2"
|
||||
|
||||
unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.1.tgz#868f353e6fce6bf8fa875b251b0f4fec3be709bb"
|
||||
@@ -5938,6 +6030,13 @@ webidl-conversions@^4.0.2:
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
|
||||
|
||||
webln@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/webln/-/webln-0.3.2.tgz#bbadf52916666b6059e3661ef5ab73a76b7cd0f4"
|
||||
integrity sha512-YYT83aOCLup2AmqvJdKtdeBTaZpjC6/JDMe8o6x1kbTYWwiwrtWHyO//PAsPixF3jwFsAkj5DmiceB6w/QSe7Q==
|
||||
dependencies:
|
||||
"@types/chrome" "^0.0.74"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
|
Reference in New Issue
Block a user