From 88650fb1665600d5f3b580c3bc44926e6df01784 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Mon, 20 Oct 2025 10:40:40 -0700 Subject: [PATCH] Add setting for auto unwrapping --- packages/app/src/session.ts | 55 +++++++++++++++++++++--------------- packages/signer/src/nip59.ts | 4 +-- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/packages/app/src/session.ts b/packages/app/src/session.ts index 0b6a124..aa1e795 100644 --- a/packages/app/src/session.ts +++ b/packages/app/src/session.ts @@ -1,14 +1,7 @@ import {derived, writable} from "svelte/store" import {cached, randomId, append, omit, equals, assoc} from "@welshman/lib" import {withGetter} from "@welshman/store" -import { - Wallet, - WRAP, - isHashedEvent, - getPubkeyTagValues, - HashedEvent, - SignedEvent, -} from "@welshman/util" +import {Wallet, WRAP, getPubkeyTagValues, HashedEvent, SignedEvent} from "@welshman/util" import { Nip59, WrappedSigner, @@ -284,39 +277,55 @@ export const nip44EncryptToSelf = (payload: string) => { return $signer.nip44.encrypt($pubkey!, payload) } +// Gift wrap utilities + export const wrapManager = new WrapManager({relay, tracker}) -export const unwrapAndStore = async (wrap: SignedEvent) => { - if (wrap.kind !== WRAP) throw new Error("Tried to unwrap an invalid event") +export const shouldUnwrap = withGetter(writable(false)) - // First, check index and repository +export const failedUnwraps = new Set() + +export const unwrapAndStore = async (wrap: SignedEvent) => { + if (wrap.kind !== WRAP) { + throw new Error("Tried to unwrap an invalid event") + } + + if (!shouldUnwrap.get()) { + throw new Error("Discarding wrapped event because `shouldUnwrap` is not enabled") + } + + // Check to see if we already tried to unwrap but failed + if (failedUnwraps.has(wrap.id)) { + return + } + + // Check index and repository const cached = wrapManager.getRumor(wrap.id) if (cached) { return cached } - let rumor: HashedEvent | undefined - let recipient: string | undefined + let result: {rumor: HashedEvent; recipient: string} | undefined // Next, try to decrypt as the recipient - for (const pubkey of getPubkeyTagValues(wrap.tags)) { - const signer = getSignerFromPubkey(pubkey) + for (const recipient of getPubkeyTagValues(wrap.tags)) { + const signer = getSignerFromPubkey(recipient) if (signer) { try { - rumor = await Nip59.fromSigner(signer).unwrap(wrap) - recipient = pubkey - break + const rumor = await Nip59.fromSigner(signer).unwrap(wrap) + + result = {rumor, recipient} } catch (e) { - // pass + failedUnwraps.add(wrap.id) } } } - if (rumor && recipient && isHashedEvent(rumor)) { - wrapManager.add({wrap, rumor, recipient}) - } + if (result) { + wrapManager.add({wrap, ...result}) - return rumor + return result.rumor + } } diff --git a/packages/signer/src/nip59.ts b/packages/signer/src/nip59.ts index 42078b9..8c16117 100644 --- a/packages/signer/src/nip59.ts +++ b/packages/signer/src/nip59.ts @@ -49,7 +49,7 @@ export const wrap = async ( return wrap } -export const unwrap = async (signer: ISigner, wrap: SignedEvent) => { +export const unwrap = async (signer: ISigner, wrap: SignedEvent): Promise => { // Avoid decrypting the same event multiple times if (seen.has(wrap.id)) { const rumorOrError = seen.get(wrap.id) @@ -57,7 +57,7 @@ export const unwrap = async (signer: ISigner, wrap: SignedEvent) => { if (rumorOrError instanceof Error) { throw rumorOrError } else { - return rumorOrError + return rumorOrError! } }