diff --git a/src/index.html b/src/index.html index c859ad4..dd902f6 100644 --- a/src/index.html +++ b/src/index.html @@ -6612,6 +6612,39 @@ premium: { state: 'locked', envelope, addressCoord }, }; } + // Private (visibility) sources carry a NIP-44/04-wrapped + // envelope addressed to specific recipients. The viewer can + // see the source iff their pubkey is in envelope.recipients + // โ the source author is always self-addressed, so they + // always succeed. decryptProjectEnvelope throws when the + // viewer isn't in the recipients list (or has no signing + // extension); we catch and surface as locked. + if (typeof isEncryptedEnvelope === 'function' && isEncryptedEnvelope(parsed)) { + if (typeof decryptProjectEnvelope === 'function') { + try { + const decrypted = await decryptProjectEnvelope(parsed); + if (decrypted) { + return { + payload: decrypted, + sourceEvent: ev, + contentBytes: ev.content.length, + private: { state: 'unlocked' }, + }; + } + } catch (err) { + // Fall through to the locked branch โ the most common + // path is "not in recipients" but we also land here if + // the user isn't signed in or the extension can't + // decrypt for any other reason. + } + } + return { + payload: null, + sourceEvent: ev, + contentBytes: ev.content.length, + private: { state: 'locked' }, + }; + } return { payload: parsed, sourceEvent: ev, contentBytes: ev.content.length }; } @@ -11058,6 +11091,19 @@ } }; + // Locked-private paint helper. No unlock CTA โ access to a + // private design is granted at the source's publish time + // (the author adds the viewer to envelope.recipients), not + // via a buyer-side action. The host just shows that the + // layer exists but isn't readable from this account. + const renderLockedPrivate = () => { + fitWrap.innerHTML = ''; + const wrap = document.createElement('div'); + wrap.style.cssText = 'position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#1f2937;color:#e5e7eb;padding:8px;text-align:center;gap:4px;font-size:.74rem;line-height:1.3'; + wrap.innerHTML = '