diff --git a/package.json b/package.json index 41e32315..d22befa3 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@tauri-apps/plugin-clipboard-manager": "github:tauri-apps/tauri-plugin-clipboard-manager#v2", "@tauri-apps/plugin-dialog": "github:tauri-apps/tauri-plugin-dialog#v2", "@tauri-apps/plugin-fs": "github:tauri-apps/tauri-plugin-fs#v2", - "@tauri-apps/plugin-http": "github:tauri-apps/tauri-plugin-http#v2", "@tauri-apps/plugin-notification": "github:tauri-apps/tauri-plugin-notification#v2", "@tauri-apps/plugin-os": "github:tauri-apps/tauri-plugin-os#v2", "@tauri-apps/plugin-process": "github:tauri-apps/tauri-plugin-process#v2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3faabcda..8a3c6c20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -55,9 +55,6 @@ dependencies: '@tauri-apps/plugin-fs': specifier: github:tauri-apps/tauri-plugin-fs#v2 version: github.com/tauri-apps/tauri-plugin-fs/c90fd8bcad3be92f34a0642d67ab1a6ad9f73dee - '@tauri-apps/plugin-http': - specifier: github:tauri-apps/tauri-plugin-http#v2 - version: github.com/tauri-apps/tauri-plugin-http/50bc7956907eef54a20255b62ea57ff4c2e8585a '@tauri-apps/plugin-notification': specifier: github:tauri-apps/tauri-plugin-notification#v2 version: github.com/tauri-apps/tauri-plugin-notification/66c0779854575ec7860eadcd98673c39627e81a6 @@ -7159,14 +7156,6 @@ packages: '@tauri-apps/api': 2.0.0-alpha.6 dev: false - github.com/tauri-apps/tauri-plugin-http/50bc7956907eef54a20255b62ea57ff4c2e8585a: - resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-http/tar.gz/50bc7956907eef54a20255b62ea57ff4c2e8585a} - name: '@tauri-apps/plugin-http' - version: 2.0.0-alpha.1 - dependencies: - '@tauri-apps/api': 2.0.0-alpha.6 - dev: false - github.com/tauri-apps/tauri-plugin-notification/66c0779854575ec7860eadcd98673c39627e81a6: resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-notification/tar.gz/66c0779854575ec7860eadcd98673c39627e81a6} name: '@tauri-apps/plugin-notification' diff --git a/src/app/auth/components/user.tsx b/src/app/auth/components/user.tsx index fa580f7f..66175688 100644 --- a/src/app/auth/components/user.tsx +++ b/src/app/auth/components/user.tsx @@ -27,7 +27,7 @@ export function User({ pubkey, fallback }: { pubkey: string; fallback?: string } />

- {user?.name || user?.display_name || user?.nip05} + {user?.name || user?.display_name}

{displayNpub(pubkey, 16)} diff --git a/src/app/auth/components/userRelay.tsx b/src/app/auth/components/userRelay.tsx index 68a61fa0..83bc4b15 100644 --- a/src/app/auth/components/userRelay.tsx +++ b/src/app/auth/components/userRelay.tsx @@ -28,7 +28,7 @@ export function UserRelay({ pubkey }: { pubkey: string }) { className="h-5 w-5 shrink-0 rounded object-cover" /> - {user?.name || user?.display_name || user?.nip05 || displayNpub(pubkey, 16)} + {user?.name || user?.display_name || displayNpub(pubkey, 16)}
diff --git a/src/app/chats/components/item.tsx b/src/app/chats/components/item.tsx index 7a2ca27c..90d1f782 100644 --- a/src/app/chats/components/item.tsx +++ b/src/app/chats/components/item.tsx @@ -38,7 +38,7 @@ export function ChatsListItem({ pubkey }: { pubkey: string }) { />
- {user?.nip05 || user?.name || user?.display_name || displayNpub(pubkey, 16)} + {user?.name || user?.display_name || displayNpub(pubkey, 16)}
diff --git a/src/app/chats/components/sidebar.tsx b/src/app/chats/components/sidebar.tsx index 1323a448..437e8820 100644 --- a/src/app/chats/components/sidebar.tsx +++ b/src/app/chats/components/sidebar.tsx @@ -1,6 +1,7 @@ import { Link } from 'react-router-dom'; import { Image } from '@shared/image'; +import { NIP05 } from '@shared/nip05'; import { useProfile } from '@utils/hooks/useProfile'; import { displayNpub } from '@utils/shortenKey'; @@ -23,9 +24,17 @@ export function ChatSidebar({ pubkey }: { pubkey: string }) {

{user?.display_name || user?.name}

-
- {user?.nip05 || displayNpub(pubkey, 16)} -
+ {user?.nip05 ? ( + + ) : ( + + {displayNpub(pubkey, 16)} + + )}

{user?.bio || user?.about}

diff --git a/src/app/notifications/components/user.tsx b/src/app/notifications/components/user.tsx index 0a52fc50..4400088a 100644 --- a/src/app/notifications/components/user.tsx +++ b/src/app/notifications/components/user.tsx @@ -25,7 +25,7 @@ export function NotiUser({ pubkey }: { pubkey: string }) { className="h-11 w-11 shrink-0 rounded-lg object-cover" /> - {user?.nip05 || user?.name || user?.display_name || displayNpub(pubkey, 16)} + {user?.name || user?.display_name || displayNpub(pubkey, 16)}
); diff --git a/src/app/users/components/profile.tsx b/src/app/users/components/profile.tsx index b8dba41e..07a0a68e 100644 --- a/src/app/users/components/profile.tsx +++ b/src/app/users/components/profile.tsx @@ -7,10 +7,11 @@ import { UserStats } from '@app/users/components/stats'; import { useStorage } from '@libs/storage/provider'; import { Image } from '@shared/image'; +import { NIP05 } from '@shared/nip05'; import { useNostr } from '@utils/hooks/useNostr'; import { useProfile } from '@utils/hooks/useProfile'; -import { shortenKey } from '@utils/shortenKey'; +import { displayNpub } from '@utils/shortenKey'; export function UserProfile({ pubkey }: { pubkey: string }) { const { db } = useStorage(); @@ -68,13 +69,21 @@ export function UserProfile({ pubkey }: { pubkey: string }) { />
-
+
{user.display_name || user.displayName || user.name || 'No name'}
- - {user.nip05 || user.username || shortenKey(pubkey)} - + {user.nip05 ? ( + + ) : ( + + {displayNpub(pubkey, 16)} + + )}
{user.about || user.bio ? ( diff --git a/src/shared/accounts/active.tsx b/src/shared/accounts/active.tsx index 74cf4e89..4414d973 100644 --- a/src/shared/accounts/active.tsx +++ b/src/shared/accounts/active.tsx @@ -67,7 +67,7 @@ export function ActiveAccount() { />

- {user?.name || user?.display_name || user?.nip05} + {user?.name || user?.display_name}

{displayNpub(db.account.pubkey, 16)} diff --git a/src/shared/composer/user.tsx b/src/shared/composer/user.tsx index 2dccbfed..772a8714 100644 --- a/src/shared/composer/user.tsx +++ b/src/shared/composer/user.tsx @@ -1,6 +1,7 @@ import { Image } from '@shared/image'; import { useProfile } from '@utils/hooks/useProfile'; +import { displayNpub } from '@utils/shortenKey'; export function ComposerUser({ pubkey }: { pubkey: string }) { const { user } = useProfile(pubkey); @@ -13,9 +14,7 @@ export function ComposerUser({ pubkey }: { pubkey: string }) { className="h-10 w-10 shrink-0 rounded-lg" />
- {user?.nip05 || user?.name || ( -
- )} + {user?.name || user?.display_name || displayNpub(pubkey, 16)}
); diff --git a/src/shared/icons/index.ts b/src/shared/icons/index.ts index b295e50b..38ae9cb3 100644 --- a/src/shared/icons/index.ts +++ b/src/shared/icons/index.ts @@ -56,3 +56,4 @@ export * from './expand'; export * from './focus'; export * from './chevronUp'; export * from './secure'; +export * from './verified'; diff --git a/src/shared/icons/verified.tsx b/src/shared/icons/verified.tsx new file mode 100644 index 00000000..6e33fd9c --- /dev/null +++ b/src/shared/icons/verified.tsx @@ -0,0 +1,21 @@ +import { SVGProps } from 'react'; + +export function VerifiedIcon(props: JSX.IntrinsicAttributes & SVGProps) { + return ( + + + + ); +} diff --git a/src/shared/nip05.tsx b/src/shared/nip05.tsx new file mode 100644 index 00000000..1753badf --- /dev/null +++ b/src/shared/nip05.tsx @@ -0,0 +1,73 @@ +import { useQuery } from '@tanstack/react-query'; +import { twMerge } from 'tailwind-merge'; + +import { UnverifiedIcon, VerifiedIcon } from '@shared/icons'; + +interface NIP05 { + names: { + [key: string]: string; + }; +} + +export function NIP05({ + pubkey, + nip05, + className, +}: { + pubkey: string; + nip05: string; + className?: string; +}) { + const { status, data } = useQuery( + [nip05], + async () => { + try { + const username = nip05.split('@')[0]; + const service = nip05.split('@')[1]; + // #TODO: use tauri native fetch to avoid CORS + const verifyURL = `https://${service}/.well-known/nostr.json?name=${username}`; + + const res = await fetch(verifyURL, { + method: 'GET', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + }, + }); + + if (!res.ok) throw new Error(`Failed to fetch NIP-05 service: ${nip05}`); + + const data: NIP05 = await res.json(); + + if (data.names) { + if (data.names.username !== pubkey) return false; + return true; + } + } catch (e) { + throw new Error(`Failed to verify NIP-05, error: ${e}`); + } + }, + { + refetchOnMount: false, + refetchOnReconnect: false, + refetchOnWindowFocus: false, + staleTime: Infinity, + } + ); + + if (status === 'loading') { +
; + } + + return ( +
+

{nip05}

+
+ {data === true ? ( + + ) : ( + + )} +
+
+ ); +} diff --git a/src/shared/notes/mentions/user.tsx b/src/shared/notes/mentions/user.tsx index 24876e04..3a5142b3 100644 --- a/src/shared/notes/mentions/user.tsx +++ b/src/shared/notes/mentions/user.tsx @@ -17,17 +17,13 @@ export function MentionUser({ pubkey }: { pubkey: string }) { onClick={() => setWidget(db, { kind: WidgetKinds.local.user, - title: user?.nip05 || user?.name || user?.display_name, + title: user?.name || user?.display_name, content: pubkey, }) } className="break-words text-fuchsia-400 hover:text-fuchsia-500" > - {user?.nip05 || - user?.name || - user?.display_name || - user?.username || - displayNpub(pubkey, 16)} + {user?.name || user?.display_name || user?.username || displayNpub(pubkey, 16)} ); } diff --git a/src/shared/notes/replies/form.tsx b/src/shared/notes/replies/form.tsx index 47184638..35089c01 100644 --- a/src/shared/notes/replies/form.tsx +++ b/src/shared/notes/replies/form.tsx @@ -52,7 +52,7 @@ export function NoteReplyForm({ id, pubkey }: { id: string; pubkey: string }) {

Reply as

- {user?.nip05 || user?.name || displayNpub(pubkey, 16)} + {user?.name || displayNpub(pubkey, 16)}

diff --git a/src/shared/notes/users/repost.tsx b/src/shared/notes/users/repost.tsx index df158ed2..bad40363 100644 --- a/src/shared/notes/users/repost.tsx +++ b/src/shared/notes/users/repost.tsx @@ -19,7 +19,7 @@ export function RepostUser({ pubkey }: { pubkey: string }) { />
- {user?.nip05 || user?.name || user?.display_name || shortenKey(pubkey)} + {user?.name || user?.display_name || shortenKey(pubkey)}
reposted
diff --git a/src/shared/user.tsx b/src/shared/user.tsx index f365e3d7..a07f54b0 100644 --- a/src/shared/user.tsx +++ b/src/shared/user.tsx @@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'; import { twMerge } from 'tailwind-merge'; import { Image } from '@shared/image'; +import { NIP05 } from '@shared/nip05'; import { formatCreatedAt } from '@utils/createdAt'; import { useProfile } from '@utils/hooks/useProfile'; @@ -79,7 +80,7 @@ export function User({ size === 'small' ? 'max-w-[10rem]' : 'max-w-[15rem]' )} > - {user?.nip05 || user?.name || user?.display_name || displayNpub(pubkey, 16)} + {user?.display_name || user?.name || displayNpub(pubkey, 16)} ยท {createdAt} @@ -87,7 +88,7 @@ export function User({
@@ -101,9 +102,17 @@ export function User({
{user?.display_name || user?.name || user?.username}
- - {user?.nip05 || displayNpub(pubkey, 16)} - + {user?.nip05 ? ( + + ) : ( + + {displayNpub(pubkey, 16)} + + )}

diff --git a/src/shared/userProfile.tsx b/src/shared/userProfile.tsx index bd304540..7212bba0 100644 --- a/src/shared/userProfile.tsx +++ b/src/shared/userProfile.tsx @@ -6,6 +6,7 @@ import { UserStats } from '@app/users/components/stats'; import { useStorage } from '@libs/storage/provider'; import { Image } from '@shared/image'; +import { NIP05 } from '@shared/nip05'; import { useNostr } from '@utils/hooks/useNostr'; import { useProfile } from '@utils/hooks/useProfile'; @@ -58,9 +59,17 @@ export function UserProfile({ pubkey }: { pubkey: string }) {

{user?.displayName || user?.name || 'No name'}
- - {user?.nip05 || displayNpub(pubkey, 16)} - + {user?.nip05 ? ( + + ) : ( + + {displayNpub(pubkey, 16)} + + )}