diff --git a/web/package-lock.json b/web/package-lock.json index d36e6896..c20f7833 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@emoji-mart/data": "^1.2.1", "@floating-ui/dom": "^1.7.6", + "@noble/hashes": "^2.2.0", "@rust-nostr/nostr-sdk": "^0.44.0", "@tabler/icons-svelte": "^3.41.1", "@tabler/icons-webfont": "^3.41.1", @@ -1806,12 +1807,12 @@ } }, "node_modules/@noble/hashes": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.1.tgz", - "integrity": "sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 20.19.0" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -8402,6 +8403,18 @@ } } }, + "node_modules/rx-nostr-crypto/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/rx-nostr-crypto/node_modules/nostr-typedef": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/nostr-typedef/-/nostr-typedef-0.9.0.tgz", diff --git a/web/package.json b/web/package.json index cc9e701e..a49b188f 100644 --- a/web/package.json +++ b/web/package.json @@ -51,6 +51,7 @@ "dependencies": { "@emoji-mart/data": "^1.2.1", "@floating-ui/dom": "^1.7.6", + "@noble/hashes": "^2.2.0", "@rust-nostr/nostr-sdk": "^0.44.0", "@tabler/icons-svelte": "^3.41.1", "@tabler/icons-webfont": "^3.41.1", diff --git a/web/src/lib/Nip05.ts b/web/src/lib/Nip05.ts new file mode 100644 index 00000000..fbb151c3 --- /dev/null +++ b/web/src/lib/Nip05.ts @@ -0,0 +1,26 @@ +/** + * Thin wrapper around `nostr-tools` NIP-05 lookups that routes + * Namecoin `.bit` identifiers to the chain resolver instead of HTTPS. + * + * All existing call sites use the same `{ pubkey, relays? }` shape, so + * the wrapper returns the same `ProfilePointer | null` contract. When + * the identifier is not a `.bit`-style name, the call falls through + * to `nip05.queryProfile` from `nostr-tools` unchanged. + */ +import { nip05 } from 'nostr-tools'; +import type { ProfilePointer } from 'nostr-tools/nip19'; +import { isDotBitIdentifier, queryProfile as queryNamecoin } from './namecoin'; + +/** + * Resolve a NIP-05 identifier. `.bit` (Namecoin) identifiers are + * resolved over the Namecoin chain; everything else falls through to + * nostr-tools. + */ +export async function queryProfile(identifier: string): Promise { + if (isDotBitIdentifier(identifier)) { + const result = await queryNamecoin(identifier); + if (!result) return null; + return { pubkey: result.pubkey, relays: result.relays ?? [] }; + } + return nip05.queryProfile(identifier); +} diff --git a/web/src/lib/components/NostrAddress.svelte b/web/src/lib/components/NostrAddress.svelte index 8b64ec8a..a87fddc4 100644 --- a/web/src/lib/components/NostrAddress.svelte +++ b/web/src/lib/components/NostrAddress.svelte @@ -1,6 +1,6 @@