diff options
| author | Adam Soltys <[email protected]> | 2026-03-01 14:30:39 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-01 14:30:39 -0800 |
| commit | f3d2029a61138d69437c1815a41fa6db3fd6198a (patch) | |
| tree | 149ed8baa69561d4d82436388049189fa411ea23 /src | |
| parent | 0eb128fdd59cd550beda23549a47df75442d997f (diff) | |
| download | coinos-ui-f3d2029a61138d69437c1815a41fa6db3fd6198a.tar.gz coinos-ui-f3d2029a61138d69437c1815a41fa6db3fd6198a.zip | |
dm test
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/nip07.ts | 29 | ||||
| -rw-r--r-- | src/lib/nip17.ts | 10 | ||||
| -rw-r--r-- | src/locales/en.json | 3 | ||||
| -rw-r--r-- | src/routes/(app)/dm/+page.svelte | 19 |
4 files changed, 51 insertions, 10 deletions
diff --git a/src/lib/nip07.ts b/src/lib/nip07.ts index ee31ee58..ce1cddaf 100644 --- a/src/lib/nip07.ts +++ b/src/lib/nip07.ts @@ -1,11 +1,34 @@ import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js"; -import { finalizeEvent } from "nostr-tools/pure"; +import { finalizeEvent, getPublicKey } from "nostr-tools/pure"; import * as libnip44 from "$lib/nip44"; import { u } from "$lib/nip44"; import { eventToSign, signer } from "$lib/store"; import { get } from "svelte/store"; +// Try to load sk from localStorage nsec and populate the signer store. +const tryNsecFromStorage = async (): Promise<Uint8Array | null> => { + const nsec = localStorage.getItem("nsec"); + if (!nsec) return null; + + try { + const { nip19 } = await import("nostr-tools"); + const { type, data } = nip19.decode(nsec); + if (type !== "nsec" || !(data instanceof Uint8Array)) return null; + + const sk = data; + const pk = getPublicKey(sk); + signer.set({ + method: "nsec", + params: { sk: bytesToHex(sk), pk }, + ready: true, + }); + return sk; + } catch { + return null; + } +}; + // Ensures we have access to a secret key, triggering the signer modal if needed. // Returns the sk as Uint8Array, or null if using NIP-07 extension. export const ensureSigner = async (userPubkey: string): Promise<Uint8Array | null> => { @@ -27,6 +50,10 @@ export const ensureSigner = async (userPubkey: string): Promise<Uint8Array | nul return hexToBytes(currentSigner.params.sk); } + // Try to load from localStorage nsec before triggering the modal + const skFromStorage = await tryNsecFromStorage(); + if (skFromStorage) return skFromStorage; + // Clear invalid signer state before triggering modal if ( currentSigner?.ready && diff --git a/src/lib/nip17.ts b/src/lib/nip17.ts index 97191a18..29a14549 100644 --- a/src/lib/nip17.ts +++ b/src/lib/nip17.ts @@ -3,12 +3,10 @@ import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js"; import { finalizeEvent, getEventHash, generateSecretKey, getPublicKey } from "nostr-tools/pure"; import { SimplePool } from "nostr-tools/pool"; import { Relay } from "nostr-tools/relay"; -import { unwrapEvent } from "nostr-tools/nip17"; - import { ensureSigner } from "$lib/nip07"; import { relaysSupporting } from "$lib/nip11"; import { expired, expiration } from "$lib/nip40"; -import { encrypt, u } from "$lib/nip44"; +import { encrypt, decrypt as nip44Decrypt, u } from "$lib/nip44"; const TWO_DAYS = 2 * 24 * 60 * 60; const randomTimestamp = () => Math.floor(Date.now() / 1000 - Math.random() * TWO_DAYS); @@ -156,7 +154,11 @@ export const decrypt = async (wrapped: any, user: any): Promise<any> => { if (sk === null) { return decryptNIP17MessageNIP07(wrapped); } else { - return unwrapEvent(wrapped, sk); + const skHex = bytesToHex(sk); + const sealedText = nip44Decrypt(wrapped.content, u.getConversationKey(skHex, wrapped.pubkey)); + const sealed = JSON.parse(sealedText); + const rumourText = nip44Decrypt(sealed.content, u.getConversationKey(skHex, sealed.pubkey)); + return JSON.parse(rumourText); } }; diff --git a/src/locales/en.json b/src/locales/en.json index d4feb73e..4249412a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -205,7 +205,8 @@ "relaysNotFound": "Could not find [R]'s DM relays.", "noRelaysSet": "WARNING: You haven't set any preferred relays. You won't be able to receive any messages or see the messages you've sent.", "nostrSettingsLink": "Go to your Nostr settings to set your relays.", - "anonymous": "Anonymous" + "anonymous": "Anonymous", + "sendFailed": "Failed to send message. The relay may be unavailable." }, "error": { "header": "Error", diff --git a/src/routes/(app)/dm/+page.svelte b/src/routes/(app)/dm/+page.svelte index 1f1df536..b7026f94 100644 --- a/src/routes/(app)/dm/+page.svelte +++ b/src/routes/(app)/dm/+page.svelte @@ -283,11 +283,19 @@ return expiration <= Date.now() / 1000 + 2 * 86400; }; + let sendError = $state(""); + const sendMessage = async (message: string) => { - const expiry = expiryEnabled ? expiryDays : undefined; - await libnip17.send(message, user, selectedChat, expiry); - text = ""; - updateEvents(); + sendError = ""; + try { + const expiry = expiryEnabled ? expiryDays : undefined; + await libnip17.send(message, user, selectedChat, expiry); + text = ""; + updateEvents(); + } catch (e: any) { + console.error("Failed to send message:", e); + sendError = $t("dm.sendFailed"); + } }; (() => libnip17.getPreferredRelays(data.user.pubkey).then((relays) => { @@ -459,6 +467,9 @@ : $t("dm.relaysNotFound").replace("[R]", name(selectedChat))} onclick={async () => sendMessage(text)} /> + {#if sendError} + <p class="warning"><em>{sendError}</em></p> + {/if} {/if} {#if !(muted && muted.has(selectedChat.pubkey))} |
