mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-17 13:21:44 +01:00
make things go faster
This commit is contained in:
parent
723668b0fc
commit
ad3fbd8673
@ -85,7 +85,7 @@
|
||||
"light-bolt11-decoder": "^3.2.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"match-sorter": "^8.0.0",
|
||||
"nanoid": "^5.0.9",
|
||||
"nanoid": "^5.1.0",
|
||||
"ngeohash": "^0.6.3",
|
||||
"nostr-idb": "^2.2.0",
|
||||
"nostr-signer-capacitor-plugin": "^0.0.3",
|
||||
|
96
pnpm-lock.yaml
generated
96
pnpm-lock.yaml
generated
@ -104,25 +104,25 @@ importers:
|
||||
version: 0.7.2
|
||||
applesauce-accounts:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-content:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-core:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-factory:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-loaders:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-react:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(react-dom@19.0.0(react@19.0.0))(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(react-dom@19.0.0(react@19.0.0))(typescript@5.7.3)
|
||||
applesauce-signers:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
version: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
bech32:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
@ -211,8 +211,8 @@ importers:
|
||||
specifier: ^8.0.0
|
||||
version: 8.0.0
|
||||
nanoid:
|
||||
specifier: ^5.0.9
|
||||
version: 5.0.9
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0
|
||||
ngeohash:
|
||||
specifier: ^0.6.3
|
||||
version: 0.6.3
|
||||
@ -2189,26 +2189,26 @@ packages:
|
||||
engines: {node: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
applesauce-accounts@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-kYjSmWeRo/sy8VW6FZiOYo7A8mIzVVLrJRTUoJfC9oASWmDG+Z5k4K6ECRwniFM0XQaootFyhUQH4AzBsI60rw==}
|
||||
applesauce-accounts@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-v5isJLkBdqOqmcDA7aGh8mx5Umrmo07+2WVMJMnwEBCy6gGy7HHWYZtxzoL/k2Cq6m+wnYE9X6aroq6fdFCQIA==}
|
||||
|
||||
applesauce-content@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-Zm34S6ls8YLNLLn+sLTxMANzuTHucZz7yt50QsJyo8ns75DYoX4SrwWbAltzKWUAPyB68och5gy6WsEZANjf3Q==}
|
||||
applesauce-content@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-1V2vhqBPFDPOJRpz9XC2/Xno4D0tHxHic9VcspxUO/rtuYvwTSAIdSNje39admpd3r++3z6/W4WLy8KFcxYmaA==}
|
||||
|
||||
applesauce-core@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-kyNj6If4oNREHaH+moIf4+l7WHw6dqMqeFoY7AwPA2rSnIFMEFojrXZkW7pPVmk3zI4S50ptEHPSaQTPQiBjdw==}
|
||||
applesauce-core@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-VjHgDbF3UQhLQhfTVZwWgSys2WQ0WpeGouRIYC38X8C7NSU7utoQ3iYwnQbqHnHee6QeO4SOI23miF0CxdUigA==}
|
||||
|
||||
applesauce-factory@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-LpMgHWuTVLfSK7izsx5ZhUCnLSqF31BbflfRWgv5LpHxhOvgc5XFMsY76yrn1lFomNIATkxg8KkjdOCAvxNaCw==}
|
||||
applesauce-factory@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-s0AuA1JmO7RZAfDxMcwmmhsazpwPfdGkHlsj2YYRGQo7maQBINCqJeo3pattuWSiuuW8FX1FH7DpfIFgaaHVzA==}
|
||||
|
||||
applesauce-loaders@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-mFh6kk9zWHlz+fN++cwco2ftBBWXuxZn/uGBM3EfD9lWFrPvs8CVfVYfDmwiRVNqF4/qL2ce9tJsB0w+2aVEOQ==}
|
||||
applesauce-loaders@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-3+yXYXmdwJn1BQY5mpkp2ikdUW8BhqAxA6kdyrd7qymfIA2lTasSKk0lbBhhX5vidJWXRX1dpeP7BmlTAF1IGg==}
|
||||
|
||||
applesauce-react@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-O6xg+i04YNi2xH4K/dCapsdhMsXzbf0gMkGrq/K4TkAVfkYhBBYtj+vCySkPfJvcnp6LyGU5CC/3sFOlSiF+YQ==}
|
||||
applesauce-react@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-HxDmEub+OkK33nVRvpuHKt4vIId9mB4AmXPabzCzWsLL0ZqaeP6xE4k7RB4YmJdLLbcLIres7u7Tu6bS2UNqHQ==}
|
||||
|
||||
applesauce-signers@0.0.0-next-20250214174945:
|
||||
resolution: {integrity: sha512-qqJ1tCLEq9GPJ644ONeK7v/cD91RS887wPSwnItJlf5VJjOTGY/BEfSXNtpXaoXrSPiJ7SM1wBN0IPCuPB8s1g==}
|
||||
applesauce-signers@0.0.0-next-20250215041231:
|
||||
resolution: {integrity: sha512-uzljOtXb17DxI409WulLE2bX8yktwghxBYZOlzmr9Kfe3iGJFCA0SQxtAoK/APrBCEd9fx5XAUTD6VWmisIy7A==}
|
||||
|
||||
arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
@ -4329,8 +4329,8 @@ packages:
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
nanoid@5.0.9:
|
||||
resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==}
|
||||
nanoid@5.1.0:
|
||||
resolution: {integrity: sha512-zDAl/llz8Ue/EblwSYwdxGBYfj46IM1dhjVi8dyp9LQffoIGxJEAHj2oeZ4uNcgycSRcQ83CnfcZqEJzVDLcDw==}
|
||||
engines: {node: ^18 || >=20}
|
||||
hasBin: true
|
||||
|
||||
@ -8421,24 +8421,24 @@ snapshots:
|
||||
dependencies:
|
||||
entities: 2.2.0
|
||||
|
||||
applesauce-accounts@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-accounts@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.1
|
||||
applesauce-signers: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
nanoid: 5.0.9
|
||||
applesauce-signers: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
nanoid: 5.1.0
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
rxjs: 7.8.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-content@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-content@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@cashu/cashu-ts': 2.0.0-rc1
|
||||
'@types/hast': 3.0.4
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/unist': 3.0.3
|
||||
applesauce-core: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
mdast-util-find-and-replace: 3.0.2
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
remark: 15.0.1
|
||||
@ -8449,34 +8449,34 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-core@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-core@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@scure/base': 1.2.4
|
||||
debug: 4.4.0
|
||||
fast-deep-equal: 3.1.3
|
||||
hash-sum: 2.0.0
|
||||
light-bolt11-decoder: 3.2.0
|
||||
nanoid: 5.0.9
|
||||
nanoid: 5.1.0
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
rxjs: 7.8.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-factory@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-factory@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
applesauce-content: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
nanoid: 5.0.9
|
||||
applesauce-content: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
nanoid: 5.1.0
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-loaders@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-loaders@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
applesauce-core: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
nanoid: 5.0.9
|
||||
applesauce-core: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
nanoid: 5.1.0
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
rx-nostr: 3.5.0
|
||||
rxjs: 7.8.1
|
||||
@ -8484,12 +8484,12 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-react@0.0.0-next-20250214174945(react-dom@19.0.0(react@19.0.0))(typescript@5.7.3):
|
||||
applesauce-react@0.0.0-next-20250215041231(react-dom@19.0.0(react@19.0.0))(typescript@5.7.3):
|
||||
dependencies:
|
||||
applesauce-accounts: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-content: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-factory: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-accounts: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-content: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
applesauce-factory: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
observable-hooks: 4.2.4(react-dom@19.0.0(react@19.0.0))(react@18.3.1)(rxjs@7.8.1)
|
||||
react: 18.3.1
|
||||
@ -8499,14 +8499,14 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-signers@0.0.0-next-20250214174945(typescript@5.7.3):
|
||||
applesauce-signers@0.0.0-next-20250215041231(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.1
|
||||
'@noble/secp256k1': 1.7.1
|
||||
'@scure/base': 1.2.4
|
||||
applesauce-core: 0.0.0-next-20250214174945(typescript@5.7.3)
|
||||
applesauce-core: 0.0.0-next-20250215041231(typescript@5.7.3)
|
||||
debug: 4.4.0
|
||||
nanoid: 5.0.9
|
||||
nanoid: 5.1.0
|
||||
nostr-tools: 2.10.4(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@ -10998,7 +10998,7 @@ snapshots:
|
||||
|
||||
nanoid@3.3.8: {}
|
||||
|
||||
nanoid@5.0.9: {}
|
||||
nanoid@5.1.0: {}
|
||||
|
||||
napi-build-utils@2.0.0: {}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import dayjs from "dayjs";
|
||||
import { kinds } from "nostr-tools";
|
||||
import { getObservableValue } from "applesauce-core/observable";
|
||||
import { getInboxes, getInvoice, getOutboxes, safeRelayUrls } from "applesauce-core/helpers";
|
||||
import { getInboxes, getInvoice, getOutboxes, mergeRelaySets } from "applesauce-core/helpers";
|
||||
import { getZapSplits } from "applesauce-core/helpers/zap";
|
||||
|
||||
import { DraftNostrEvent, NostrEvent, isDTag } from "../../types/nostr-event";
|
||||
@ -89,7 +89,7 @@ export async function getPayRequestForPubkey(
|
||||
content: comment ?? "",
|
||||
tags: [
|
||||
["p", pubkey],
|
||||
["relays", ...unique(safeRelayUrls([...userInbox, ...eventRelays, ...outbox, ...additional]))],
|
||||
["relays", ...mergeRelaySets(userInbox, eventRelays, outbox, additional)],
|
||||
["amount", String(amount)],
|
||||
],
|
||||
};
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { Flex, Text } from "@chakra-ui/react";
|
||||
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import UserAvatar from "../../user/user-avatar";
|
||||
import UserLink from "../../user/user-link";
|
||||
import RelayCard from "../../../views/relays/components/relay-card";
|
||||
import { safeRelayUrl } from "../../../helpers/relay";
|
||||
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
|
||||
|
||||
export default function RelayRecommendation({ event }: { event: NostrEvent }) {
|
||||
const safeUrl = safeRelayUrl(event.content);
|
||||
const ref = useEventIntersectionRef(event);
|
||||
|
||||
return (
|
||||
<Flex gap="2" direction="column" ref={ref}>
|
||||
<Flex gap="2">
|
||||
<UserAvatar pubkey={event.pubkey} size="xs" alignItems="center" />
|
||||
<UserLink pubkey={event.pubkey} />
|
||||
<Text>Recommended relay:</Text>
|
||||
</Flex>
|
||||
{safeUrl ? <RelayCard url={safeUrl} /> : event.content}
|
||||
</Flex>
|
||||
);
|
||||
}
|
@ -5,7 +5,6 @@ import { Box, Spinner } from "@chakra-ui/react";
|
||||
import { ErrorBoundary } from "../../error-boundary";
|
||||
import ReplyNote from "./reply-note";
|
||||
import ShareEvent from "./share-event";
|
||||
import RelayRecommendation from "./relay-recommendation";
|
||||
import { isReply } from "../../../helpers/nostr/event";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { FLARE_VIDEO_KIND } from "../../../helpers/nostr/video";
|
||||
@ -36,9 +35,6 @@ function TimelineItem({ event, visible, minHeight }: { event: NostrEvent; visibl
|
||||
case kinds.LiveEvent:
|
||||
content = <StreamNote stream={event} />;
|
||||
break;
|
||||
case kinds.RecommendRelay:
|
||||
content = <RelayRecommendation event={event} />;
|
||||
break;
|
||||
case kinds.BadgeAward:
|
||||
content = <BadgeAwardCard award={event} />;
|
||||
break;
|
||||
|
29
src/const.ts
29
src/const.ts
@ -1,18 +1,23 @@
|
||||
import { safeRelayUrls } from "applesauce-core/helpers";
|
||||
import { EventFactoryClient } from "applesauce-factory";
|
||||
import { isSafeRelayURL } from "applesauce-core/helpers/relays";
|
||||
import { normalizeURL } from "applesauce-core/helpers";
|
||||
import { kinds } from "nostr-tools";
|
||||
|
||||
export const DEFAULT_SEARCH_RELAYS = safeRelayUrls([
|
||||
function normalizeRelayURLs(relays: string[]) {
|
||||
return relays.filter(isSafeRelayURL).map(normalizeURL);
|
||||
}
|
||||
|
||||
export const DEFAULT_SEARCH_RELAYS = normalizeRelayURLs([
|
||||
"wss://relay.nostr.band",
|
||||
"wss://search.nos.today",
|
||||
"wss://relay.noswhere.com",
|
||||
"wss://filter.nostr.wine",
|
||||
]);
|
||||
export const WIKI_RELAYS = safeRelayUrls(["wss://relay.wikifreedia.xyz/"]);
|
||||
export const COMMON_CONTACT_RELAYS = safeRelayUrls(["wss://purplepag.es/"]);
|
||||
export const WIKI_RELAYS = normalizeRelayURLs(["wss://relay.wikifreedia.xyz/"]);
|
||||
export const COMMON_CONTACT_RELAYS = normalizeRelayURLs(["wss://purplepag.es/"]);
|
||||
|
||||
export const DEFAULT_SIGNAL_RELAYS = safeRelayUrls(["wss://nostrue.com/", "wss://relay.damus.io"]);
|
||||
export const DEFAULT_NOSTR_CONNECT_RELAYS = safeRelayUrls(["wss://relay.nsec.app/"]);
|
||||
export const DEFAULT_SIGNAL_RELAYS = normalizeRelayURLs(["wss://nostrue.com/", "wss://relay.damus.io"]);
|
||||
export const DEFAULT_NOSTR_CONNECT_RELAYS = normalizeRelayURLs(["wss://relay.nsec.app/"]);
|
||||
|
||||
export const DEFAULT_ICE_SERVERS: RTCIceServer[] = [
|
||||
{
|
||||
@ -33,7 +38,7 @@ export const DEFAULT_ICE_SERVERS: RTCIceServer[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const RECOMMENDED_READ_RELAYS = safeRelayUrls([
|
||||
export const RECOMMENDED_READ_RELAYS = normalizeRelayURLs([
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nostr.wine/",
|
||||
"wss://relay.snort.social/",
|
||||
@ -41,12 +46,20 @@ export const RECOMMENDED_READ_RELAYS = safeRelayUrls([
|
||||
"wss://purplerelay.com/",
|
||||
"wss://nostr.land/",
|
||||
]);
|
||||
export const RECOMMENDED_WRITE_RELAYS = safeRelayUrls([
|
||||
export const RECOMMENDED_WRITE_RELAYS = normalizeRelayURLs([
|
||||
"wss://relay.damus.io/",
|
||||
"wss://nos.lol/",
|
||||
"wss://purplerelay.com/",
|
||||
]);
|
||||
|
||||
export const JAPANESE_RELAYS = normalizeRelayURLs([
|
||||
"wss://r.kojira.io",
|
||||
"wss://nrelay-jp.c-stellar.net",
|
||||
"wss://nostr.fediverse.jp",
|
||||
"wss://nostr.holybea.com",
|
||||
"wss://relay-jp.nostr.wirednet.jp",
|
||||
]);
|
||||
|
||||
export const NOSTR_CONNECT_PERMISSIONS = [
|
||||
"get_public_key",
|
||||
"nip04_encrypt",
|
||||
|
@ -1,21 +1,24 @@
|
||||
import { safeRelayUrls } from "applesauce-core/helpers";
|
||||
import { normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
export async function getRelaysFromExt() {
|
||||
if (!window.nostr) throw new Error("Missing extension");
|
||||
const read = new Set<string>();
|
||||
const write = new Set<string>();
|
||||
const extRelays = (await window.nostr.getRelays?.()) ?? [];
|
||||
const extRelays = (await window.nostr.getRelays?.()) ?? ([] as string[]);
|
||||
if (Array.isArray(extRelays)) {
|
||||
const safeUrls = safeRelayUrls(extRelays);
|
||||
for (const url of safeUrls) {
|
||||
for (const url of extRelays) {
|
||||
read.add(url);
|
||||
write.add(url);
|
||||
}
|
||||
} else {
|
||||
const readUrls = safeRelayUrls(Object.keys(extRelays).filter((url) => extRelays[url].read));
|
||||
const readUrls = Object.keys(extRelays)
|
||||
.filter((url) => extRelays[url].read)
|
||||
.map(normalizeURL);
|
||||
for (const url of readUrls) read.add(url);
|
||||
|
||||
const writeUrls = safeRelayUrls(Object.keys(extRelays).filter((url) => extRelays[url].write));
|
||||
const writeUrls = Object.keys(extRelays)
|
||||
.filter((url) => extRelays[url].write)
|
||||
.map(normalizeURL);
|
||||
for (const url of writeUrls) write.add(url);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { getPubkeyFromDecodeResult, isHexKey } from "applesauce-core/helpers";
|
||||
|
||||
import { safeRelayUrls } from "./relay";
|
||||
import { isSafeRelayURL } from "applesauce-core/helpers/relays";
|
||||
|
||||
export function safeDecode(str: string) {
|
||||
try {
|
||||
const result = nip19.decode(str);
|
||||
if ((result.type === "nevent" || result.type === "nprofile" || result.type === "naddr") && result.data.relays)
|
||||
result.data.relays = safeRelayUrls(result.data.relays);
|
||||
result.data.relays = result.data.relays.filter(isSafeRelayURL);
|
||||
return result;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import dayjs from "dayjs";
|
||||
import { EventTemplate, NostrEvent, kinds } from "nostr-tools";
|
||||
import { isAddressPointerInList, isEventPointerInList, isProfilePointerInList } from "applesauce-core/helpers/lists";
|
||||
import { mergeRelaySets } from "applesauce-core/helpers";
|
||||
|
||||
import { PTag, isDTag, isPTag, isRTag } from "../../types/nostr-event";
|
||||
import { getEventCoordinate, replaceOrAddSimpleTag } from "./event";
|
||||
import { safeRelayUrls } from "../relay";
|
||||
|
||||
export const USER_GROUPS_LIST_KIND = 10009;
|
||||
|
||||
@ -100,9 +100,9 @@ export function getReferencesFromList(event: NostrEvent | EventTemplate) {
|
||||
}
|
||||
|
||||
/** @deprecated this should be moved to applesauce-core if its still needed */
|
||||
export function getRelaysFromList(event: NostrEvent | EventTemplate) {
|
||||
if (event.kind === kinds.RelayList) return safeRelayUrls(event.tags.filter(isRTag).map((t) => t[1]));
|
||||
else return safeRelayUrls(event.tags.filter((t) => t[0] === "relay" && t[1]).map((t) => t[1]) as string[]);
|
||||
export function getRelaysFromList(event: NostrEvent | EventTemplate): string[] {
|
||||
if (event.kind === kinds.RelayList) return mergeRelaySets(event.tags.filter(isRTag).map((t) => t[1]));
|
||||
else return mergeRelaySets(event.tags.filter((t) => t[0] === "relay" && t[1]).map((t) => t[1]));
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
|
@ -1,16 +1,20 @@
|
||||
import { kinds } from "nostr-tools";
|
||||
import { DraftNostrEvent, NostrEvent, RTag, Tag, isRTag } from "../../types/nostr-event";
|
||||
import { safeRelayUrl } from "../relay";
|
||||
import { cloneEvent } from "./event";
|
||||
import { RelayMode } from "../../services/app-relays";
|
||||
import { isSafeRelayURL } from "../../../../applesauce/packages/core/dist/helpers/relays";
|
||||
import { normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
/** fixes or removes any bad r tags */
|
||||
/**
|
||||
* fixes or removes any bad r tags
|
||||
* @deprecated
|
||||
*/
|
||||
export function cleanRTags(tags: Tag[]) {
|
||||
const newTags: Tag[] = [];
|
||||
for (const tag of tags) {
|
||||
if (tag[0] === "r") {
|
||||
if (!tag[1]) continue;
|
||||
const url = safeRelayUrl(tag[1]);
|
||||
if (!tag[1] || !isSafeRelayURL(tag[1])) continue;
|
||||
const url = normalizeURL(tag[1]);
|
||||
if (url) newTags.push(tag[2] ? ["r", url, tag[2]] : ["r", url]);
|
||||
} else newTags.push(tag);
|
||||
}
|
||||
@ -34,10 +38,6 @@ export function createRelayTag(url: string, mode: RelayMode) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getRelaysFromMailbox(list: NostrEvent | DraftNostrEvent): { url: string; mode: RelayMode }[] {
|
||||
return cleanRTags(list.tags).filter(isRTag).map(parseRTag);
|
||||
}
|
||||
|
||||
export function addRelayModeToMailbox(list: NostrEvent | undefined, relay: string, mode: RelayMode): DraftNostrEvent {
|
||||
const draft = cloneEvent(kinds.RelayList, list);
|
||||
draft.tags = cleanRTags(draft.tags);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getEventPointerFromETag, getTagValue, safeRelayUrl } from "applesauce-core/helpers";
|
||||
import { getEventPointerFromETag, getTagValue, isSafeRelayURL, normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
import { NostrEvent, isPTag } from "../../types/nostr-event";
|
||||
import dayjs from "dayjs";
|
||||
@ -46,7 +46,9 @@ export function getStreamRelays(stream: NostrEvent) {
|
||||
if (tag[0] === "relays") {
|
||||
found = true;
|
||||
for (let i = 1; i < tag.length; i++) {
|
||||
const relay = safeRelayUrl(tag[i]);
|
||||
if (!isSafeRelayURL(tag[i])) continue;
|
||||
|
||||
const relay = normalizeURL(tag[i]);
|
||||
if (relay && !relays.includes(relay)) relays.push(relay);
|
||||
}
|
||||
}
|
||||
|
@ -9,52 +9,6 @@ export function getRelayVariations(relay: string) {
|
||||
} else return [relay, relay + "/"];
|
||||
}
|
||||
|
||||
export function validateRelayURL(relay: string | URL) {
|
||||
if (typeof relay === "string" && relay.includes(",ws")) throw new Error("Can not have multiple relays in one string");
|
||||
const url = typeof relay === "string" ? new URL(relay) : relay;
|
||||
if (url.protocol !== "wss:" && url.protocol !== "ws:") throw new Error("Incorrect protocol");
|
||||
return url;
|
||||
}
|
||||
export function isValidRelayURL(relay: string | URL) {
|
||||
try {
|
||||
validateRelayURL(relay);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function normalizeRelayURL(relayUrl: string) {
|
||||
const url = validateRelayURL(relayUrl);
|
||||
url.pathname = url.pathname.replace(/\/+/g, "/");
|
||||
if ((url.port === "80" && url.protocol === "ws:") || (url.port === "443" && url.protocol === "wss:")) url.port = "";
|
||||
url.searchParams.sort();
|
||||
url.hash = "";
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export function safeNormalizeRelayURL(relayUrl: string) {
|
||||
try {
|
||||
return normalizeRelayURL(relayUrl);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move these to helpers/relay
|
||||
export function safeRelayUrl(relayUrl: string | URL) {
|
||||
try {
|
||||
return validateRelayURL(relayUrl).toString();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
export function safeRelayUrls(urls: Iterable<string>): string[] {
|
||||
return Array.from(urls).map(safeRelayUrl).filter(Boolean) as string[];
|
||||
}
|
||||
|
||||
export function splitNostrFilterByPubkeys(
|
||||
filter: Filter | Filter[],
|
||||
relayPubkeyMap: Record<string, string[]>,
|
||||
@ -134,16 +88,3 @@ const connectionStateSortOrder: ConnectionState[] = [
|
||||
export function getConnectionStateSort(state: ConnectionState) {
|
||||
return connectionStateSortOrder.indexOf(state);
|
||||
}
|
||||
|
||||
/** @deprecated use mergeRelaySets from applesauce-core */
|
||||
export function mergeRelaySets(...sources: (Iterable<string> | undefined)[]) {
|
||||
const set = new Set<string>();
|
||||
for (const src of sources) {
|
||||
if (!src) continue;
|
||||
for (const url of src) {
|
||||
const safe = safeRelayUrl(url);
|
||||
if (safe) set.add(safe);
|
||||
}
|
||||
}
|
||||
return Array.from(set);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useContext } from "react";
|
||||
import { unique } from "../../helpers/array";
|
||||
import { safeRelayUrls } from "../../helpers/relay";
|
||||
import { mergeRelaySets } from "applesauce-core/helpers";
|
||||
|
||||
export const RelayContext = React.createContext<string[]>([]);
|
||||
|
||||
@ -18,7 +18,7 @@ export function AdditionalRelayProvider({
|
||||
extend?: boolean;
|
||||
}) {
|
||||
const parentRelays = useAdditionalRelayContext();
|
||||
const safeUrls = safeRelayUrls(extend ? [...parentRelays, ...relays] : relays);
|
||||
const safeUrls = extend ? mergeRelaySets(parentRelays, relays) : relays;
|
||||
|
||||
return <RelayContext.Provider value={unique(safeUrls)}>{children}</RelayContext.Provider>;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Query } from "applesauce-core";
|
||||
import { safeRelayUrl } from "applesauce-core/helpers";
|
||||
import { isSafeRelayURL } from "applesauce-core/helpers";
|
||||
import { map } from "rxjs/operators";
|
||||
|
||||
type TrustedMints = {
|
||||
@ -27,9 +27,8 @@ export default function TrustedMintsQuery(pubkey: string): Query<TrustedMints |
|
||||
break;
|
||||
|
||||
case "relay":
|
||||
if (tag[1]) {
|
||||
const safe = safeRelayUrl(tag[1]);
|
||||
if (safe) mints.push(safe);
|
||||
if (tag[1] && isSafeRelayURL(tag[1])) {
|
||||
mints.push(tag[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { BehaviorSubject, distinctUntilChanged, Observable, pairwise } from "rxjs";
|
||||
import { CacheRelay, openDB } from "nostr-idb";
|
||||
import { AbstractRelay } from "nostr-tools/abstract-relay";
|
||||
import { fakeVerifyEvent, isFromCache } from "applesauce-core/helpers";
|
||||
import { fakeVerifyEvent, isFromCache, isSafeRelayURL } from "applesauce-core/helpers";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { logger } from "../helpers/debug";
|
||||
import { safeRelayUrl } from "../helpers/relay";
|
||||
import WasmRelay from "./wasm-relay";
|
||||
import MemoryRelay from "../classes/memory-relay";
|
||||
import localSettings from "./local-settings";
|
||||
@ -50,8 +49,8 @@ async function createRelay(url: string) {
|
||||
return new WasmRelay();
|
||||
} else if (url.startsWith("nostr-idb://")) {
|
||||
return createInternalRelay();
|
||||
} else if (safeRelayUrl(url)) {
|
||||
return new AbstractRelay(safeRelayUrl(url)!, { verifyEvent: fakeVerifyEvent });
|
||||
} else if (isSafeRelayURL(url)) {
|
||||
return new AbstractRelay(url, { verifyEvent: fakeVerifyEvent });
|
||||
}
|
||||
} else if (window.CACHE_RELAY_ENABLED) {
|
||||
const protocol = location.protocol === "https:" ? "wss:" : "ws:";
|
||||
|
@ -6,8 +6,20 @@ import {
|
||||
Mutes,
|
||||
processTags,
|
||||
} from "applesauce-core/helpers";
|
||||
import { combineLatest, filter, map, mergeMap, Observable, share, tap } from "rxjs";
|
||||
import {
|
||||
combineLatest,
|
||||
filter,
|
||||
map,
|
||||
Observable,
|
||||
ReplaySubject,
|
||||
share,
|
||||
switchMap,
|
||||
tap,
|
||||
throttleTime,
|
||||
timer,
|
||||
} from "rxjs";
|
||||
import { TimelineQuery, UserMuteQuery } from "applesauce-core/queries";
|
||||
import { getContentPointers } from "applesauce-factory/helpers";
|
||||
import { kinds, nip18, nip25, NostrEvent } from "nostr-tools";
|
||||
|
||||
import localSettings from "./local-settings";
|
||||
@ -17,7 +29,6 @@ import { TORRENT_COMMENT_KIND } from "../helpers/nostr/torrents";
|
||||
import accounts from "./accounts";
|
||||
import { getThreadReferences, isReply, isRepost } from "../helpers/nostr/event";
|
||||
import { getPubkeysMentionedInContent } from "../helpers/nostr/post";
|
||||
import { getContentPointers } from "applesauce-factory/helpers";
|
||||
|
||||
export const NotificationTypeSymbol = Symbol("notificationType");
|
||||
|
||||
@ -145,7 +156,7 @@ async function handleShare(event: NostrEvent) {
|
||||
}
|
||||
|
||||
const notifications$: Observable<CategorizedEvent[]> = combineLatest([accounts.active$]).pipe(
|
||||
mergeMap(([account]) => {
|
||||
switchMap(([account]) => {
|
||||
if (!account) return [];
|
||||
|
||||
const timeline$ = queryStore
|
||||
@ -164,7 +175,11 @@ const notifications$: Observable<CategorizedEvent[]> = combineLatest([accounts.a
|
||||
],
|
||||
})
|
||||
.pipe(
|
||||
filter(t => t!== undefined),
|
||||
// filter out undefined
|
||||
filter((t) => t !== undefined),
|
||||
// update timeline at 30fps
|
||||
throttleTime(1000 / 30),
|
||||
// trigger logs of extra events
|
||||
tap((timeline) => {
|
||||
// handle loading dependencies of each event
|
||||
for (const event of timeline) {
|
||||
@ -179,13 +194,17 @@ const notifications$: Observable<CategorizedEvent[]> = combineLatest([accounts.a
|
||||
}
|
||||
}
|
||||
}),
|
||||
// categorize events
|
||||
map((timeline) => timeline.map((e) => categorizeEvent(e, account.pubkey))),
|
||||
);
|
||||
|
||||
const mute$ = queryStore.createQuery(UserMuteQuery, account.pubkey);
|
||||
|
||||
return combineLatest([timeline$, mute$]).pipe(
|
||||
// filter events out by mutes
|
||||
map(([timeline, mutes]) => filterEvents(timeline, account.pubkey, mutes)),
|
||||
// keep the observable hot for 5 minutes after its unsubscribed
|
||||
share({ connector: () => new ReplaySubject(1), resetOnComplete: () => timer(5 * 60_000) }),
|
||||
);
|
||||
}),
|
||||
share(),
|
||||
|
@ -12,7 +12,6 @@ import {
|
||||
FlexProps,
|
||||
Heading,
|
||||
IconButton,
|
||||
Spacer,
|
||||
Text,
|
||||
} from "@chakra-ui/react";
|
||||
import { useContext } from "react";
|
||||
@ -24,13 +23,11 @@ import { getTagValue } from "../../../../helpers/nostr/event";
|
||||
import DebugEventButton from "../../../../components/debug-modal/debug-event-button";
|
||||
import SupportedNIPs from "../../../relays/components/supported-nips";
|
||||
import RelayNotes from "../../../relays/relay-details/relay-notes";
|
||||
import { safeRelayUrl } from "../../../../helpers/relay";
|
||||
import { ExternalLinkIcon } from "../../../../components/icons";
|
||||
import PeopleListProvider from "../../../../providers/local/people-list-provider";
|
||||
import { getPubkeysFromList } from "../../../../helpers/nostr/lists";
|
||||
import UserAvatarLink from "../../../../components/user/user-avatar-link";
|
||||
import UserName from "../../../../components/user/user-name";
|
||||
import UserDnsIdentity from "../../../../components/user/user-dns-identity";
|
||||
import RelayFavicon from "../../../../components/relay-favicon";
|
||||
|
||||
export default function RelayStatusDetails({ event, ...props }: Omit<FlexProps, "children"> & { event: NostrEvent }) {
|
||||
@ -40,7 +37,7 @@ export default function RelayStatusDetails({ event, ...props }: Omit<FlexProps,
|
||||
const software = getTagValue(event, "s");
|
||||
const version = event.tags.find((t) => t[0] === "l" && t[2] === "nip11.version")?.[1];
|
||||
|
||||
const url = identity ? safeRelayUrl(identity) : undefined;
|
||||
const url = identity;
|
||||
|
||||
// gather labels
|
||||
const misc: Record<string, string[]> = {};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { memo, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||
import { Button, ButtonGroup, Flex, IconButton } from "@chakra-ui/react";
|
||||
import { UNSAFE_DataRouterContext, useLocation, useNavigate } from "react-router-dom";
|
||||
import { mergeRelaySets } from "applesauce-core/helpers";
|
||||
import { NostrEvent, kinds } from "nostr-tools";
|
||||
|
||||
import { ThreadIcon } from "../../components/icons";
|
||||
@ -24,8 +25,6 @@ import useRouterMarker from "../../hooks/use-router-marker";
|
||||
import decryptionCacheService from "../../services/decryption-cache";
|
||||
import UserDnsIdentityIcon from "../../components/user/user-dns-identity-icon";
|
||||
import UserAvatarLink from "../../components/user/user-avatar-link";
|
||||
import ContainedSimpleView from "../../components/layout/presets/contained-simple-view";
|
||||
import { mergeRelaySets } from "../../helpers/relay";
|
||||
import SimpleView from "../../components/layout/presets/simple-view";
|
||||
|
||||
/** This is broken out from DirectMessageChatPage for performance reasons. Don't use outside of file */
|
||||
|
@ -1,106 +0,0 @@
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Code,
|
||||
Flex,
|
||||
FormControl,
|
||||
FormLabel,
|
||||
IconButton,
|
||||
Input,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
ModalProps,
|
||||
Text,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { useDebounce } from "react-use";
|
||||
|
||||
import { useRelayInfo } from "../../../hooks/use-relay-info";
|
||||
import UserAvatar from "../../../components/user/user-avatar";
|
||||
import UserLink from "../../../components/user/user-link";
|
||||
import UserDnsIdentity from "../../../components/user/user-dns-identity";
|
||||
import { CodeIcon } from "../../../components/icons";
|
||||
import { Metadata } from "./relay-card";
|
||||
import { safeRelayUrl } from "../../../helpers/relay";
|
||||
|
||||
function RelayDetails({ url, debug }: { url: string; debug?: boolean }) {
|
||||
const { info } = useRelayInfo(url);
|
||||
|
||||
if (!info) return null;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Metadata name="Name">{info.name}</Metadata>
|
||||
<Metadata name="URL">{url}</Metadata>
|
||||
{info.pubkey && (
|
||||
<Flex gap="2" alignItems="center">
|
||||
<Text fontWeight="bold">Owner: </Text>
|
||||
<UserAvatar pubkey={info.pubkey} size="xs" />
|
||||
<UserLink pubkey={info.pubkey} />
|
||||
<UserDnsIdentity pubkey={info.pubkey} onlyIcon />
|
||||
</Flex>
|
||||
)}
|
||||
<Metadata name="NIPs">{info.supported_nips?.join(", ")}</Metadata>
|
||||
{debug && (
|
||||
<Code whiteSpace="pre" overflow="auto">
|
||||
{JSON.stringify(info, null, 2)}
|
||||
</Code>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AddCustomRelayModal({
|
||||
onSubmit,
|
||||
...props
|
||||
}: { onSubmit: (relay: string) => void } & Omit<ModalProps, "children">) {
|
||||
const [url, setUrl] = useState("");
|
||||
const [safeUrl, setSafeUrl] = useState<string>();
|
||||
const showDebug = useDisclosure();
|
||||
|
||||
useDebounce(() => setSafeUrl(safeRelayUrl(url) ?? undefined), 1000, [url]);
|
||||
|
||||
return (
|
||||
<Modal {...props}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader p="4">Custom Relay</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody px="4" py="0" display="flex" flexDirection="column" gap="2">
|
||||
<FormControl>
|
||||
<FormLabel>Relay URL</FormLabel>
|
||||
<Input
|
||||
type="url"
|
||||
placeholder="wss://relay.example.com"
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
{safeUrl && <RelayDetails url={safeUrl} debug={showDebug.isOpen} />}
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter p="4">
|
||||
<ButtonGroup size="sm">
|
||||
{safeUrl && (
|
||||
<IconButton icon={<CodeIcon />} aria-label="Show JSON" onClick={showDebug.onToggle} variant="ghost" />
|
||||
)}
|
||||
<Button variant="ghost" onClick={props.onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button colorScheme="primary" onClick={() => safeUrl && onSubmit(safeUrl)} isDisabled={!safeUrl}>
|
||||
Add
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
@ -13,6 +13,7 @@ import {
|
||||
Tag,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { isSafeRelayURL, normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
import { useRelayInfo } from "../../../hooks/use-relay-info";
|
||||
import { RelayDebugButton, RelayMetadata } from "../components/relay-card";
|
||||
@ -23,7 +24,6 @@ import RelayNotes from "./relay-notes";
|
||||
import PeopleListProvider from "../../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../../components/people-list-selection/people-list-selection";
|
||||
import RelayFavicon from "../../../components/relay-favicon";
|
||||
import { safeRelayUrl } from "../../../helpers/relay";
|
||||
import RelayUsersTab from "./relay-users";
|
||||
const RelayDetailsTab = lazy(() => import("./relay-details"));
|
||||
|
||||
@ -108,12 +108,11 @@ export default function RelayDetailsView() {
|
||||
const { relay } = useParams<string>();
|
||||
if (!relay) return <>No relay url</>;
|
||||
|
||||
const safeUrl = safeRelayUrl(relay);
|
||||
if (!safeUrl) return <>Bad relay url</>;
|
||||
if (!isSafeRelayURL(relay)) return <>Bad relay url</>;
|
||||
|
||||
return (
|
||||
<PeopleListProvider initList="global">
|
||||
<RelayPage relay={safeUrl} />
|
||||
<RelayPage relay={normalizeURL(relay)} />
|
||||
</PeopleListProvider>
|
||||
);
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import { Button, Code, Flex, Heading, IconButton, Input, Link, Select, Switch, Text } from "@chakra-ui/react";
|
||||
import { Button, Flex, Heading, IconButton, Input, Link, Select, Switch, Text } from "@chakra-ui/react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { safeRelayUrl } from "applesauce-core/helpers";
|
||||
import { useObservable } from "applesauce-react/hooks";
|
||||
|
||||
import useAsyncErrorHandler from "../../../../hooks/use-async-error-handler";
|
||||
import { controlApi$ } from "../../../../services/bakery";
|
||||
import RelayFavicon from "../../../../components/relay-favicon";
|
||||
import { isSafeRelayURL, normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
function BroadcastRelay({ relay }: { relay: string }) {
|
||||
const controlApi = useObservable(controlApi$);
|
||||
@ -44,8 +44,10 @@ function AddRelayForm() {
|
||||
|
||||
const submit = handleSubmit((values) => {
|
||||
if (!config) return;
|
||||
const url = safeRelayUrl(values.url);
|
||||
if (url) controlApi?.setConfigField("gossipBroadcastRelays", [...config.gossipBroadcastRelays, url]);
|
||||
if (!isSafeRelayURL(values.url)) return;
|
||||
|
||||
const url = normalizeURL(values.url);
|
||||
controlApi?.setConfigField("gossipBroadcastRelays", [...config.gossipBroadcastRelays, url]);
|
||||
|
||||
reset();
|
||||
});
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Button, Flex, FlexProps, useToast } from "@chakra-ui/react";
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { safeRelayUrl } from "../../../helpers/relay";
|
||||
import { RelayUrlInput } from "../../../components/relay-url-input";
|
||||
import { isSafeRelayURL } from "../../../../../applesauce/packages/core/dist/helpers/relays";
|
||||
import { normalizeURL } from "applesauce-core/helpers";
|
||||
|
||||
export default function AddRelayForm({
|
||||
onSubmit,
|
||||
@ -21,9 +22,8 @@ export default function AddRelayForm({
|
||||
|
||||
const submit = handleSubmit(async (values) => {
|
||||
try {
|
||||
const url = safeRelayUrl(values.url);
|
||||
if (!url) return;
|
||||
await onSubmit(url);
|
||||
if (!isSafeRelayURL(values.url)) return;
|
||||
await onSubmit(normalizeURL(values.url));
|
||||
reset();
|
||||
} catch (error) {
|
||||
if (error instanceof Error) toast({ status: "error", description: error.message });
|
||||
|
@ -4,7 +4,7 @@ import { WarningIcon } from "@chakra-ui/icons";
|
||||
import { IdentityStatus } from "applesauce-loaders/helpers/dns-identity";
|
||||
import { mergeRelaySets } from "applesauce-core/helpers";
|
||||
|
||||
import { RECOMMENDED_READ_RELAYS, RECOMMENDED_WRITE_RELAYS } from "../../../const";
|
||||
import { JAPANESE_RELAYS, RECOMMENDED_READ_RELAYS, RECOMMENDED_WRITE_RELAYS } from "../../../const";
|
||||
import AddRelayForm from "./add-relay-form";
|
||||
import { useReadRelays, useWriteRelays } from "../../../hooks/use-client-relays";
|
||||
import { useActiveAccount } from "applesauce-react/hooks";
|
||||
@ -12,21 +12,12 @@ import RelayControl from "./relay-control";
|
||||
import { getRelaysFromExt } from "../../../helpers/nip07";
|
||||
import { useUserDNSIdentity } from "../../../hooks/use-user-dns-identity";
|
||||
import useUserContactRelays from "../../../hooks/use-user-contact-relays";
|
||||
import { safeRelayUrls } from "../../../helpers/relay";
|
||||
import HoverLinkOverlay from "../../../components/hover-link-overlay";
|
||||
import SimpleView from "../../../components/layout/presets/simple-view";
|
||||
import localSettings from "../../../services/local-settings";
|
||||
import { addAppRelay, RelayMode } from "../../../services/app-relays";
|
||||
import useUserMailboxes from "../../../hooks/use-user-mailboxes";
|
||||
|
||||
const JAPANESE_RELAYS = safeRelayUrls([
|
||||
"wss://r.kojira.io",
|
||||
"wss://nrelay-jp.c-stellar.net",
|
||||
"wss://nostr.fediverse.jp",
|
||||
"wss://nostr.holybea.com",
|
||||
"wss://relay-jp.nostr.wirednet.jp",
|
||||
]);
|
||||
|
||||
function RelaySetCard({ label, read, write }: { label: string; read: Iterable<string>; write: Iterable<string> }) {
|
||||
const handleClick = useCallback<MouseEventHandler>((e) => {
|
||||
e.preventDefault();
|
||||
|
@ -18,9 +18,10 @@ import {
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { NostrEvent } from "nostr-tools";
|
||||
import { NostrConnectSigner } from "applesauce-signers/signers/nostr-connect-signer";
|
||||
import { parseNIP05Address, ProfileContent, safeParse } from "applesauce-core/helpers";
|
||||
import { mergeRelaySets, parseNIP05Address, ProfileContent, safeParse } from "applesauce-core/helpers";
|
||||
import { useAccountManager } from "applesauce-react/hooks";
|
||||
import { NostrConnectAccount } from "applesauce-accounts/accounts";
|
||||
import { IdentityStatus } from "applesauce-loaders/helpers/dns-identity";
|
||||
|
||||
import { NOSTR_CONNECT_PERMISSIONS } from "../../../const";
|
||||
import useNip05Providers from "../../../hooks/use-nip05-providers";
|
||||
@ -30,9 +31,7 @@ import { MetadataAvatar } from "../../../components/user/user-avatar";
|
||||
import { ErrorBoundary } from "../../../components/error-boundary";
|
||||
import dnsIdentityLoader from "../../../services/dns-identity-loader";
|
||||
import useUserProfile from "../../../hooks/use-user-profile";
|
||||
import { safeRelayUrls } from "../../../helpers/relay";
|
||||
import { createNostrConnectConnection } from "../../../classes/nostr-connect-connection";
|
||||
import { IdentityStatus } from "applesauce-loaders/helpers/dns-identity";
|
||||
|
||||
function ProviderCard({ onClick, provider }: { onClick: () => void; provider: NostrEvent }) {
|
||||
const metadata = JSON.parse(provider.content) as ProfileContent;
|
||||
@ -96,7 +95,7 @@ export default function LoginNostrAddressCreate() {
|
||||
|
||||
if (identity.name !== "_") throw new Error("Provider does not own the domain");
|
||||
if (!identity.hasNip46) throw new Error("Provider does not support NIP-46");
|
||||
const relays = safeRelayUrls(identity.nip46Relays || identity.relays || []);
|
||||
const relays = mergeRelaySets(identity.nip46Relays || identity.relays || []);
|
||||
if (relays.length === 0) throw new Error("Cant find providers relays");
|
||||
|
||||
const signer = new NostrConnectSigner({
|
||||
|
@ -5,13 +5,13 @@ import { NostrConnectSigner } from "applesauce-signers/signers/nostr-connect-sig
|
||||
import { useAccountManager } from "applesauce-react/hooks";
|
||||
import { NostrConnectAccount, ReadonlyAccount } from "applesauce-accounts/accounts";
|
||||
import { Identity, IdentityStatus } from "applesauce-loaders/helpers/dns-identity";
|
||||
import { mergeRelaySets } from "applesauce-core/helpers";
|
||||
import { ReadonlySigner } from "applesauce-signers";
|
||||
import { useDebounce } from "react-use";
|
||||
|
||||
import dnsIdentityLoader from "../../../services/dns-identity-loader";
|
||||
import { CheckIcon } from "../../../components/icons";
|
||||
import { NOSTR_CONNECT_PERMISSIONS } from "../../../const";
|
||||
import { safeRelayUrls } from "../../../helpers/relay";
|
||||
import { getMatchSimpleEmail } from "../../../helpers/regexp";
|
||||
import QRCodeScannerButton from "../../../components/qr-code/qr-code-scanner-button";
|
||||
import { createNostrConnectConnection } from "../../../classes/nostr-connect-connection";
|
||||
@ -46,7 +46,7 @@ export default function LoginNostrAddressView() {
|
||||
try {
|
||||
if (nip05.hasNip46 && nip05.pubkey) {
|
||||
setLoading("Connecting...");
|
||||
const relays = safeRelayUrls(nip05.nip46Relays || nip05.relays || []);
|
||||
const relays = mergeRelaySets(nip05.nip46Relays || nip05.relays || []);
|
||||
const signer = new NostrConnectSigner({
|
||||
pubkey: nip05.pubkey,
|
||||
relays,
|
||||
|
Loading…
x
Reference in New Issue
Block a user