diff --git a/src/components/icons.tsx b/src/components/icons.tsx
index cc1ea77ce..da48825da 100644
--- a/src/components/icons.tsx
+++ b/src/components/icons.tsx
@@ -99,7 +99,13 @@ export const LinkItem = createIcon({
});
export const LightningIcon = createIcon({
- displayName: "lightning",
+ displayName: "lightning-icon",
d: "M13 10h7l-9 13v-9H4l9-13z",
defaultProps,
});
+
+export const RelayIcon = createIcon({
+ displayName: "relay-icon",
+ d: "M11 14v-3h2v3h5a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-6a1 1 0 0 1 1-1h5zM2.51 8.837C3.835 4.864 7.584 2 12 2s8.166 2.864 9.49 6.837l-1.898.632a8.003 8.003 0 0 0-15.184 0l-1.897-.632zm3.796 1.265a6.003 6.003 0 0 1 11.388 0l-1.898.633a4.002 4.002 0 0 0-7.592 0l-1.898-.633z",
+ defaultProps,
+});
diff --git a/src/components/note/index.tsx b/src/components/note/index.tsx
index f3b553e84..4728db9d8 100644
--- a/src/components/note/index.tsx
+++ b/src/components/note/index.tsx
@@ -31,6 +31,7 @@ import identity from "../../services/identity";
import { useUserContacts } from "../../hooks/use-user-contacts";
import { ArrowDownSIcon } from "../icons";
import { UserTipButton } from "../user-tip-button";
+import { NoteRelays } from "./note-relays";
export type NoteProps = {
event: NostrEvent;
@@ -62,6 +63,7 @@ export const Note = React.memo(({ event }: NoteProps) => {
+
diff --git a/src/components/note/note-relays.tsx b/src/components/note/note-relays.tsx
new file mode 100644
index 000000000..6863ffca6
--- /dev/null
+++ b/src/components/note/note-relays.tsx
@@ -0,0 +1,57 @@
+import {
+ Button,
+ IconButton,
+ IconButtonProps,
+ Popover,
+ PopoverArrow,
+ PopoverBody,
+ PopoverContent,
+ PopoverTrigger,
+ Text,
+} from "@chakra-ui/react";
+import { useCallback, useState } from "react";
+import { NostrRequest } from "../../classes/nostr-request";
+import useSubject from "../../hooks/use-subject";
+import { getEventRelays } from "../../services/event-relays";
+import settings from "../../services/settings";
+import { NostrEvent } from "../../types/nostr-event";
+import { RelayIcon } from "../icons";
+
+export type NoteRelaysProps = Omit & {
+ event: NostrEvent;
+};
+
+export const NoteRelays = ({ event, ...props }: NoteRelaysProps) => {
+ const relays = useSubject(getEventRelays(event.id));
+
+ const [loading, setLoading] = useState(false);
+ const queryRelays = useCallback(() => {
+ setLoading(true);
+ const request = new NostrRequest(settings.relays.value);
+ request.start({ ids: [event.id] });
+ request.onEvent.subscribe({
+ complete() {
+ setLoading(false);
+ },
+ });
+ }, []);
+
+ return (
+
+
+ } {...props} aria-label="Note Relays" />
+
+
+
+
+ {relays.map((url) => (
+ {url}
+ ))}
+
+
+
+
+ );
+};
diff --git a/src/services/event-relays.ts b/src/services/event-relays.ts
new file mode 100644
index 000000000..002431714
--- /dev/null
+++ b/src/services/event-relays.ts
@@ -0,0 +1,23 @@
+import { BehaviorSubject } from "rxjs";
+import { relayPool } from "./relays";
+
+const eventRelays = new Map>();
+
+export function getEventRelays(id: string) {
+ let relays = eventRelays.get(id);
+ if (!relays) {
+ relays = new BehaviorSubject([]);
+ eventRelays.set(id, relays);
+ }
+ return relays;
+}
+
+relayPool.onRelayCreated.subscribe((relay) => {
+ relay.onEvent.subscribe(({ body: event }) => {
+ const relays = getEventRelays(event.id);
+
+ if (!relays.value.includes(relay.url)) {
+ relays.next(relays.value.concat(relay.url));
+ }
+ });
+});