diff --git a/packages/app/src/Element/NostrLink.tsx b/packages/app/src/Element/NostrLink.tsx
index 1b140782..bf78a541 100644
--- a/packages/app/src/Element/NostrLink.tsx
+++ b/packages/app/src/Element/NostrLink.tsx
@@ -2,10 +2,8 @@ import { Link } from "react-router-dom";
import { EventKind, NostrPrefix } from "@snort/nostr";
import Mention from "Element/Mention";
-import NostrFileHeader from "Element/NostrFileHeader";
import { parseNostrLink } from "Util";
import NoteQuote from "Element/NoteQuote";
-import ZapstrEmbed from "Element/ZapstrEmbed";
export default function NostrLink({ link, depth }: { link: string; depth?: number }) {
const nav = parseNostrLink(link);
@@ -13,13 +11,6 @@ export default function NostrLink({ link, depth }: { link: string; depth?: numbe
if (nav?.type === NostrPrefix.PublicKey || nav?.type === NostrPrefix.Profile) {
return ;
} else if (nav?.type === NostrPrefix.Note || nav?.type === NostrPrefix.Event || nav?.type === NostrPrefix.Address) {
- if (nav.kind === EventKind.FileHeader) {
- return ;
- }
- if (nav.kind === 31337) {
- return ;
- }
-
if ((depth ?? 0) > 0) {
const evLink = nav.encode();
return (
diff --git a/packages/app/src/Element/Note.tsx b/packages/app/src/Element/Note.tsx
index 42cfd4cb..889f453c 100644
--- a/packages/app/src/Element/Note.tsx
+++ b/packages/app/src/Element/Note.tsx
@@ -30,6 +30,7 @@ import { EventExt } from "System/EventExt";
import useLogin from "Hooks/useLogin";
import { setBookmarked, setPinned } from "Login";
import { NostrFileElement } from "Element/NostrFileHeader";
+import ZapstrEmbed from "Element/ZapstrEmbed";
import messages from "./messages";
@@ -78,7 +79,9 @@ export default function Note(props: NoteProps) {
if (ev.kind === EventKind.FileHeader) {
return ;
}
-
+ if (ev.kind === 31337) {
+ return ;
+ }
const navigate = useNavigate();
const [showReactions, setShowReactions] = useState(false);
const deletions = useMemo(() => getReactions(related, ev.id, EventKind.Deletion), [related]);
diff --git a/packages/app/src/Element/NoteCreator.tsx b/packages/app/src/Element/NoteCreator.tsx
index fd65f20c..b1e5f59d 100644
--- a/packages/app/src/Element/NoteCreator.tsx
+++ b/packages/app/src/Element/NoteCreator.tsx
@@ -142,7 +142,7 @@ export function NoteCreator() {
if (file) {
const rx = await uploader.upload(file, file.name);
if (rx.header) {
- const link = `nostr:${encodeTLV(rx.header.id, NostrPrefix.Event, undefined, rx.header.kind)}`;
+ const link = `nostr:${encodeTLV(NostrPrefix.Event, rx.header.id, undefined, rx.header.kind)}`;
dispatch(setNote(`${note ? `${note}\n` : ""}${link}`));
dispatch(setOtherEvents([...otherEvents, rx.header]));
} else if (rx.url) {
diff --git a/packages/app/src/Element/NoteFooter.tsx b/packages/app/src/Element/NoteFooter.tsx
index 50cdc9bb..a9f523c4 100644
--- a/packages/app/src/Element/NoteFooter.tsx
+++ b/packages/app/src/Element/NoteFooter.tsx
@@ -264,7 +264,7 @@ export default function NoteFooter(props: NoteFooterProps) {
}
async function share() {
- const link = encodeTLV(ev.id, NostrPrefix.Event, ev.relays);
+ const link = encodeTLV(NostrPrefix.Event, ev.id, ev.relays);
const url = `${window.location.protocol}//${window.location.host}/e/${link}`;
if ("share" in window.navigator) {
await window.navigator.share({
@@ -300,7 +300,7 @@ export default function NoteFooter(props: NoteFooterProps) {
}
async function copyId() {
- const link = encodeTLV(ev.id, NostrPrefix.Event, ev.relays);
+ const link = encodeTLV(NostrPrefix.Event, ev.id, ev.relays);
await navigator.clipboard.writeText(link);
}
diff --git a/packages/app/src/Element/WriteDm.tsx b/packages/app/src/Element/WriteDm.tsx
index 5efc2118..eb9a25ea 100644
--- a/packages/app/src/Element/WriteDm.tsx
+++ b/packages/app/src/Element/WriteDm.tsx
@@ -35,7 +35,7 @@ export default function WriteDm({ chatPubKey }: { chatPubKey: string }) {
if (file) {
const rx = await uploader.upload(file, file.name);
if (rx.header) {
- const link = `nostr:${encodeTLV(rx.header.id, NostrPrefix.Event, undefined, rx.header.kind)}`;
+ const link = `nostr:${encodeTLV(NostrPrefix.Event, rx.header.id, undefined, rx.header.kind)}`;
setMsg(`${msg ? `${msg}\n` : ""}${link}`);
setOtherEvents([...otherEvents, rx.header]);
} else if (rx.url) {
diff --git a/packages/app/src/Element/ZapstrEmbed.tsx b/packages/app/src/Element/ZapstrEmbed.tsx
index 99bde748..b8cb0e0c 100644
--- a/packages/app/src/Element/ZapstrEmbed.tsx
+++ b/packages/app/src/Element/ZapstrEmbed.tsx
@@ -1,25 +1,27 @@
import "./ZapstrEmbed.css";
import { Link } from "react-router-dom";
+import { encodeTLV, NostrPrefix, RawEvent } from "@snort/nostr";
-import useEventFeed from "Feed/EventFeed";
-import Spinner from "Icons/Spinner";
-import { NostrLink } from "Util";
import { ProxyImg } from "Element/ProxyImg";
import ProfileImage from "Element/ProfileImage";
import { FormattedMessage } from "react-intl";
-export default function ZapstrEmbed({ link }: { link: NostrLink }) {
- const ev = useEventFeed(link);
+export default function ZapstrEmbed({ ev }: { ev: RawEvent }) {
+ const media = ev.tags.find(a => a[0] === "media");
+ const cover = ev.tags.find(a => a[0] === "cover");
+ const subject = ev.tags.find(a => a[0] === "subject");
+ const refPersons = ev.tags.filter(a => a[0] === "p");
- if (!ev.data) return ;
-
- const media = ev.data.tags.find(a => a[0] === "media");
- const cover = ev.data.tags.find(a => a[0] === "cover");
- const subject = ev.data.tags.find(a => a[0] === "subject");
- const refPersons = ev.data.tags.filter(a => a[0] === "p");
+ const link = encodeTLV(
+ NostrPrefix.Address,
+ ev.tags.find(a => a[0] === "d")?.[1] ?? "",
+ undefined,
+ ev.kind,
+ ev.pubkey
+ );
return (
<>
-
+
@@ -33,7 +35,7 @@ export default function ZapstrEmbed({ link }: { link: NostrLink }) {
-
+
diff --git a/packages/app/src/Pages/ProfilePage.tsx b/packages/app/src/Pages/ProfilePage.tsx
index efebae61..5ed1c59f 100644
--- a/packages/app/src/Pages/ProfilePage.tsx
+++ b/packages/app/src/Pages/ProfilePage.tsx
@@ -296,7 +296,7 @@ export default function ProfilePage() {
function renderIcons() {
if (!id) return;
- const link = encodeTLV(id, NostrPrefix.Profile);
+ const link = encodeTLV(NostrPrefix.Profile, id);
return (
setShowProfileQr(true)}>
diff --git a/packages/app/src/Pages/settings/Keys.tsx b/packages/app/src/Pages/settings/Keys.tsx
index 1fafd927..e5220cf1 100644
--- a/packages/app/src/Pages/settings/Keys.tsx
+++ b/packages/app/src/Pages/settings/Keys.tsx
@@ -15,7 +15,7 @@ export default function ExportKeys() {
-
+
{privateKey && (
<>
diff --git a/packages/app/src/Util.ts b/packages/app/src/Util.ts
index 19b70110..d8d2eab4 100644
--- a/packages/app/src/Util.ts
+++ b/packages/app/src/Util.ts
@@ -91,7 +91,7 @@ export function bech32ToText(str: string) {
*/
export function eventLink(hex: u256, relays?: Array | string) {
const encoded = relays
- ? encodeTLV(hex, NostrPrefix.Event, Array.isArray(relays) ? relays : [relays])
+ ? encodeTLV(NostrPrefix.Event, hex, Array.isArray(relays) ? relays : [relays])
: hexToBech32(NostrPrefix.Note, hex);
return `/e/${encoded}`;
}
@@ -101,7 +101,7 @@ export function eventLink(hex: u256, relays?: Array | string) {
*/
export function profileLink(hex: HexKey, relays?: Array | string) {
const encoded = relays
- ? encodeTLV(hex, NostrPrefix.Profile, Array.isArray(relays) ? relays : [relays])
+ ? encodeTLV(NostrPrefix.Event, hex, Array.isArray(relays) ? relays : [relays])
: hexToBech32(NostrPrefix.PublicKey, hex);
return `/p/${encoded}`;
}
@@ -119,7 +119,7 @@ export function hexToBech32(hrp: string, hex?: string) {
const buf = secp.utils.hexToBytes(hex);
return bech32.encode(hrp, bech32.toWords(buf));
} else {
- return encodeTLV(hex, hrp as NostrPrefix);
+ return encodeTLV(hrp as NostrPrefix, hex);
}
} catch (e) {
console.warn("Invalid hex", hex, e);
diff --git a/packages/nostr/src/legacy/Links.ts b/packages/nostr/src/legacy/Links.ts
index c21763ae..70071328 100644
--- a/packages/nostr/src/legacy/Links.ts
+++ b/packages/nostr/src/legacy/Links.ts
@@ -27,13 +27,9 @@ export interface TLVEntry {
value: string | HexKey | number;
}
-export function encodeTLV(hex: string, prefix: NostrPrefix, relays?: string[], kind?: number) {
- if (typeof hex !== "string" || hex.length === 0 || hex.length % 2 !== 0) {
- return "";
- }
-
+export function encodeTLV(prefix: NostrPrefix, id: string, relays?: string[], kind?: number, author?: string) {
const enc = new TextEncoder();
- const buf = secp.utils.hexToBytes(hex);
+ const buf = prefix === NostrPrefix.Address ? enc.encode(id) : secp.utils.hexToBytes(id);
const tl0 = [0, buf.length, ...buf];
const tl1 =
@@ -43,9 +39,11 @@ export function encodeTLV(hex: string, prefix: NostrPrefix, relays?: string[], k
return [1, data.length, ...data];
})
.flat() ?? [];
+
+ const tl2 = author ? [2, 32, ...secp.utils.hexToBytes(author)] : [];
const tl3 = kind ? [3, 4, ...new Uint8Array(new Uint32Array([kind]).buffer).reverse()] : []
- return bech32.encode(prefix, bech32.toWords([...tl0, ...tl1, ...tl3]), 1_000);
+ return bech32.encode(prefix, bech32.toWords([...tl0, ...tl1, ...tl2, ...tl3]), 1_000);
}
export function decodeTLV(str: string) {