nostr-components 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +58 -46
  2. package/dist/assets/{base-styles-DC0ilu4S.js → base-styles-Dmuzg8I4.js} +3 -3
  3. package/dist/assets/{base-styles-DC0ilu4S.js.map → base-styles-Dmuzg8I4.js.map} +1 -1
  4. package/dist/assets/{copy-delegation-CcagQMIW.js → copy-delegation-xzt-t_do.js} +5 -5
  5. package/dist/assets/{copy-delegation-CcagQMIW.js.map → copy-delegation-xzt-t_do.js.map} +1 -1
  6. package/dist/assets/dark-nostrich-running.gif +0 -0
  7. package/dist/assets/default_dp-NQ3TGrtT.png +0 -0
  8. package/dist/assets/default_dp.png +0 -0
  9. package/dist/assets/default_dp_32.png +0 -0
  10. package/dist/assets/{dialog-component-Dqg0QU9I.js → dialog-component-Da1ZIYh9.js} +7 -2
  11. package/dist/assets/dialog-component-Da1ZIYh9.js.map +1 -0
  12. package/dist/assets/{dialog-likers-D3c7WIMp.js → dialog-likers-Bq6kUbS0.js} +4 -4
  13. package/dist/assets/{dialog-likers-D3c7WIMp.js.map → dialog-likers-Bq6kUbS0.js.map} +1 -1
  14. package/dist/assets/light-nostrich-running.gif +0 -0
  15. package/dist/assets/{nostr-service-m3Hgc5Xx.js → nostr-service-CA0Qx4nJ.js} +3 -3
  16. package/dist/assets/{nostr-service-m3Hgc5Xx.js.map → nostr-service-CA0Qx4nJ.js.map} +1 -1
  17. package/dist/assets/nostr-user-component-r-MUbTL6.js +2 -0
  18. package/dist/assets/nostr-user-component-r-MUbTL6.js.map +1 -0
  19. package/dist/assets/{pure-laCRX9eG.js → pure-DOoUcNQv.js} +2 -2
  20. package/dist/assets/{pure-laCRX9eG.js.map → pure-DOoUcNQv.js.map} +1 -1
  21. package/dist/assets/{theme-C1r1Zw8r.js → theme-BN1Bvweb.js} +2 -2
  22. package/dist/assets/{theme-C1r1Zw8r.js.map → theme-BN1Bvweb.js.map} +1 -1
  23. package/dist/assets/{user-resolver-DqI5KGh6.js → user-resolver-ArI0680e.js} +2 -2
  24. package/dist/assets/{user-resolver-DqI5KGh6.js.map → user-resolver-ArI0680e.js.map} +1 -1
  25. package/dist/assets/zap-utils-BiKkJPt6.js +2 -0
  26. package/dist/assets/zap-utils-BiKkJPt6.js.map +1 -0
  27. package/dist/components/nostr-comment.es.js +6 -6
  28. package/dist/components/nostr-comment.es.js.map +1 -1
  29. package/dist/components/nostr-dm.es.js +2 -2
  30. package/dist/components/nostr-dm.es.js.map +1 -1
  31. package/dist/components/nostr-follow-button.es.js +3 -3
  32. package/dist/components/nostr-follow-button.es.js.map +1 -1
  33. package/dist/components/nostr-like.es.js +6 -6
  34. package/dist/components/nostr-like.es.js.map +1 -1
  35. package/dist/components/nostr-live-chat.es.js +3 -3
  36. package/dist/components/nostr-live-chat.es.js.map +1 -1
  37. package/dist/components/nostr-post.es.js +2 -2
  38. package/dist/components/nostr-post.es.js.map +1 -1
  39. package/dist/components/nostr-profile-badge.es.js +3 -3
  40. package/dist/components/nostr-profile-badge.es.js.map +1 -1
  41. package/dist/components/nostr-profile.es.js +5 -5
  42. package/dist/components/nostr-profile.es.js.map +1 -1
  43. package/dist/components/nostr-zap.es.js +5 -5
  44. package/dist/components/nostr-zap.es.js.map +1 -1
  45. package/dist/index.d.ts +6 -0
  46. package/dist/nostr-comment.d.ts +4 -0
  47. package/dist/nostr-components.es.js +1 -1
  48. package/dist/nostr-components.es.js.map +1 -1
  49. package/dist/nostr-components.umd.js +69 -40
  50. package/dist/nostr-components.umd.js.map +1 -1
  51. package/dist/nostr-dm.d.ts +4 -0
  52. package/dist/nostr-follow-button.d.ts +4 -0
  53. package/dist/nostr-like.d.ts +4 -0
  54. package/dist/nostr-live-chat.d.ts +4 -0
  55. package/dist/nostr-post.d.ts +4 -0
  56. package/dist/nostr-profile-badge.d.ts +4 -0
  57. package/dist/nostr-profile.d.ts +4 -0
  58. package/dist/nostr-zap.d.ts +4 -0
  59. package/dist/src/base/base-component/nostr-base-component.d.ts +116 -0
  60. package/dist/src/base/copy-delegation.d.ts +5 -0
  61. package/dist/src/base/dialog-component/dialog-component.d.ts +67 -0
  62. package/dist/src/base/dialog-component/style.d.ts +5 -0
  63. package/dist/src/base/event-component/nostr-event-component.d.ts +53 -0
  64. package/dist/src/base/render-options.d.ts +5 -0
  65. package/dist/src/base/resolvers/event-resolver.d.ts +20 -0
  66. package/dist/src/base/resolvers/user-resolver.d.ts +19 -0
  67. package/dist/src/base/text-row/render-name.d.ts +7 -0
  68. package/dist/src/base/text-row/render-nip05.d.ts +1 -0
  69. package/dist/src/base/text-row/render-npub.d.ts +1 -0
  70. package/dist/src/base/text-row/render-text-row.d.ts +9 -0
  71. package/dist/src/base/user-component/nostr-user-component.d.ts +43 -0
  72. package/dist/src/common/base-styles.d.ts +44 -0
  73. package/dist/src/common/constants.d.ts +4 -0
  74. package/dist/src/common/date-utils.d.ts +9 -0
  75. package/dist/src/common/icons.d.ts +7 -0
  76. package/dist/src/common/nip05-utils.d.ts +13 -0
  77. package/dist/src/common/nostr-login-service.d.ts +26 -0
  78. package/dist/src/common/nostr-service.d.ts +40 -0
  79. package/dist/src/common/theme.d.ts +4 -0
  80. package/dist/src/common/types.d.ts +1 -0
  81. package/dist/src/common/utils.d.ts +34 -0
  82. package/dist/src/index.d.ts +32 -0
  83. package/dist/src/nostr-comment/nostr-comment.d.ts +60 -0
  84. package/dist/src/nostr-comment/render.d.ts +15 -0
  85. package/dist/src/nostr-comment/utils.d.ts +81 -0
  86. package/dist/src/nostr-dm/nostr-dm.d.ts +34 -0
  87. package/dist/src/nostr-dm/render.d.ts +15 -0
  88. package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +24 -0
  89. package/dist/src/nostr-follow-button/render.d.ts +11 -0
  90. package/dist/src/nostr-follow-button/style.d.ts +1 -0
  91. package/dist/src/nostr-like/dialog-help-style.d.ts +1 -0
  92. package/dist/src/nostr-like/dialog-help.d.ts +2 -0
  93. package/dist/src/nostr-like/dialog-likers-style.d.ts +1 -0
  94. package/dist/src/nostr-like/dialog-likers.d.ts +24 -0
  95. package/dist/src/nostr-like/like-utils.d.ts +48 -0
  96. package/dist/src/nostr-like/nostr-like.d.ts +49 -0
  97. package/dist/src/nostr-like/render.d.ts +10 -0
  98. package/dist/src/nostr-like/style.d.ts +1 -0
  99. package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +65 -0
  100. package/dist/src/nostr-live-chat/render.d.ts +31 -0
  101. package/dist/src/nostr-post/nostr-post.d.ts +25 -0
  102. package/dist/src/nostr-post/parse-text.d.ts +8 -0
  103. package/dist/src/nostr-post/render-content.d.ts +5 -0
  104. package/dist/src/nostr-post/render.d.ts +19 -0
  105. package/dist/src/nostr-post/style.d.ts +1 -0
  106. package/dist/src/nostr-profile/nostr-profile.d.ts +24 -0
  107. package/dist/src/nostr-profile/render-stats.d.ts +1 -0
  108. package/dist/src/nostr-profile/render.d.ts +22 -0
  109. package/dist/src/nostr-profile/style.d.ts +1 -0
  110. package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +34 -0
  111. package/dist/src/nostr-profile-badge/render.d.ts +11 -0
  112. package/dist/src/nostr-profile-badge/style.d.ts +1 -0
  113. package/dist/src/nostr-zap/dialog-help-style.d.ts +5 -0
  114. package/dist/src/nostr-zap/dialog-help.d.ts +2 -0
  115. package/dist/src/nostr-zap/dialog-zap-style.d.ts +6 -0
  116. package/dist/src/nostr-zap/dialog-zap.d.ts +31 -0
  117. package/dist/src/nostr-zap/dialog-zappers-style.d.ts +1 -0
  118. package/dist/src/nostr-zap/dialog-zappers.d.ts +25 -0
  119. package/dist/src/nostr-zap/nostr-zap.d.ts +45 -0
  120. package/dist/src/nostr-zap/render.d.ts +9 -0
  121. package/dist/src/nostr-zap/style.d.ts +1 -0
  122. package/dist/src/nostr-zap/zap-utils.d.ts +57 -0
  123. package/dist/vite.config.d.ts +2 -0
  124. package/dist/vite.config.esm.d.ts +2 -0
  125. package/dist/vite.config.umd.d.ts +2 -0
  126. package/package.json +1 -1
  127. package/dist/assets/dialog-component-Dqg0QU9I.js.map +0 -1
  128. package/dist/assets/nostr-user-component-XEnanH-d.js +0 -2
  129. package/dist/assets/nostr-user-component-XEnanH-d.js.map +0 -1
  130. package/dist/assets/zap-utils-BZcaCsT_.js +0 -2
  131. package/dist/assets/zap-utils-BZcaCsT_.js.map +0 -1
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zap-utils-BZcaCsT_.js","assets/nostr-service-m3Hgc5Xx.js","assets/nostr-login-service-D2FmscPI.js","assets/preload-helper-D7HrI6pR.js","assets/utils--bxLbhGF.js"])))=>i.map(i=>d[i]);
2
- import{_ as y}from"./preload-helper-D7HrI6pR.js";import"./dialog-component-Dqg0QU9I.js";import{getBatchedProfileMetadata as x,extractProfileMetadataContent as k}from"./zap-utils-BZcaCsT_.js";import{h as p,e as g,f as b,c as v}from"./base-styles-DC0ilu4S.js";import"./nostr-service-m3Hgc5Xx.js";import"./nostr-login-service-D2FmscPI.js";import"./utils--bxLbhGF.js";function $(t="light"){const e=t==="dark";return`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/zap-utils-BiKkJPt6.js","assets/nostr-service-CA0Qx4nJ.js","assets/nostr-login-service-D2FmscPI.js","assets/preload-helper-D7HrI6pR.js","assets/utils--bxLbhGF.js"])))=>i.map(i=>d[i]);
2
+ import{_ as y}from"./preload-helper-D7HrI6pR.js";import"./dialog-component-Da1ZIYh9.js";import{getBatchedProfileMetadata as x,extractProfileMetadataContent as k}from"./zap-utils-BiKkJPt6.js";import{j as p,e as g,k as b,i as v}from"./base-styles-Dmuzg8I4.js";import"./nostr-service-CA0Qx4nJ.js";import"./nostr-login-service-D2FmscPI.js";import"./utils--bxLbhGF.js";function $(t="light"){const e=t==="dark";return`
3
3
  .likers-dialog-content {
4
4
  padding: 0;
5
5
  max-height: 60vh;
@@ -234,5 +234,5 @@ import{_ as y}from"./preload-helper-D7HrI6pR.js";import"./dialog-component-Dqg0Q
234
234
  ${t.map((a,n)=>P(a,e[n],n)).join("")}
235
235
  </div>
236
236
  </div>
237
- `}async function N(t,e){const r=t.querySelector(".likers-list");if(!r)return;const a=[...new Set(e.map(n=>n.authorPubkey))];console.log("Nostr-Components: Likers dialog: Fetching profiles for",a.length,"unique authors");try{const n=await x(a),i=new Map;n.forEach(o=>{i.set(o.id,o.profile)});const s=new Map;a.forEach(o=>{s.set(o,p(o))});for(let o=0;o<e.length;o++){const l=e[o],c=i.get(l.authorPubkey),d=s.get(l.authorPubkey)||l.authorPubkey;let u;if(c){const h=k(c);u={...l,authorName:h.display_name||h.name||d,authorPicture:h.picture,authorNpub:d}}else u={...l,authorName:d,authorNpub:d};const f=r.querySelector(`[data-like-index="${o}"]`);if(f){const h=m(u,o);f.outerHTML=h}}console.log("Nostr-Components: Likers dialog: Progressive enhancement completed for",e.length,"like entries")}catch(n){console.error("Nostr-Components: Likers dialog: Error in batched profile enhancement",n),console.log("Nostr-Components: Likers dialog: Falling back to individual profile fetching"),await E(t,e)}}async function E(t,e){const r=t.querySelector(".likers-list");if(!r)return;const a=new Map,n=e.map(async(i,s)=>{if(a.has(i.authorPubkey)){const o=a.get(i.authorPubkey);return{index:s,enhanced:{...i,authorName:o.authorName,authorPicture:o.authorPicture,authorNpub:o.authorNpub}}}try{const{getProfileMetadata:o}=await y(async()=>{const{getProfileMetadata:f}=await import("./zap-utils-BZcaCsT_.js");return{getProfileMetadata:f}},__vite__mapDeps([0,1,2,3,4])),l=await o(i.authorPubkey),c=k(l),d=p(i.authorPubkey),u={...i,authorName:c.display_name||c.name||d,authorPicture:c.picture,authorNpub:d};return a.set(i.authorPubkey,u),{index:s,enhanced:u}}catch(o){console.error("Nostr-Components: Likers dialog: Error fetching profile for",i.authorPubkey,o);const l=p(i.authorPubkey),c={...i,authorName:l,authorNpub:l};return a.set(i.authorPubkey,c),{index:s,enhanced:c}}});for(const i of n)try{const{index:s,enhanced:o}=await i,l=r.querySelector(`[data-like-index="${s}"]`);if(l){const c=m(o,s);l.outerHTML=c}}catch(s){console.error("Nostr-Components: Likers dialog: Error processing profile enhancement",s)}}export{w as injectLikersDialogStyles,D as openLikersDialog};
238
- //# sourceMappingURL=dialog-likers-D3c7WIMp.js.map
237
+ `}async function N(t,e){const r=t.querySelector(".likers-list");if(!r)return;const a=[...new Set(e.map(n=>n.authorPubkey))];console.log("Nostr-Components: Likers dialog: Fetching profiles for",a.length,"unique authors");try{const n=await x(a),i=new Map;n.forEach(o=>{i.set(o.id,o.profile)});const s=new Map;a.forEach(o=>{s.set(o,p(o))});for(let o=0;o<e.length;o++){const l=e[o],c=i.get(l.authorPubkey),d=s.get(l.authorPubkey)||l.authorPubkey;let u;if(c){const h=k(c);u={...l,authorName:h.display_name||h.name||d,authorPicture:h.picture,authorNpub:d}}else u={...l,authorName:d,authorNpub:d};const f=r.querySelector(`[data-like-index="${o}"]`);if(f){const h=m(u,o);f.outerHTML=h}}console.log("Nostr-Components: Likers dialog: Progressive enhancement completed for",e.length,"like entries")}catch(n){console.error("Nostr-Components: Likers dialog: Error in batched profile enhancement",n),console.log("Nostr-Components: Likers dialog: Falling back to individual profile fetching"),await E(t,e)}}async function E(t,e){const r=t.querySelector(".likers-list");if(!r)return;const a=new Map,n=e.map(async(i,s)=>{if(a.has(i.authorPubkey)){const o=a.get(i.authorPubkey);return{index:s,enhanced:{...i,authorName:o.authorName,authorPicture:o.authorPicture,authorNpub:o.authorNpub}}}try{const{getProfileMetadata:o}=await y(async()=>{const{getProfileMetadata:f}=await import("./zap-utils-BiKkJPt6.js");return{getProfileMetadata:f}},__vite__mapDeps([0,1,2,3,4])),l=await o(i.authorPubkey),c=k(l),d=p(i.authorPubkey),u={...i,authorName:c.display_name||c.name||d,authorPicture:c.picture,authorNpub:d};return a.set(i.authorPubkey,u),{index:s,enhanced:u}}catch(o){console.error("Nostr-Components: Likers dialog: Error fetching profile for",i.authorPubkey,o);const l=p(i.authorPubkey),c={...i,authorName:l,authorNpub:l};return a.set(i.authorPubkey,c),{index:s,enhanced:c}}});for(const i of n)try{const{index:s,enhanced:o}=await i,l=r.querySelector(`[data-like-index="${s}"]`);if(l){const c=m(o,s);l.outerHTML=c}}catch(s){console.error("Nostr-Components: Likers dialog: Error processing profile enhancement",s)}}export{w as injectLikersDialogStyles,D as openLikersDialog};
238
+ //# sourceMappingURL=dialog-likers-Bq6kUbS0.js.map
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["getLikersDialogStyles","theme","isDark","injectLikersDialogStyles","style","renderLikeEntry","like","index","authorNameSafe","escapeHtml","njumpUrl","hexToNpub","profilePictureSafe","isValidUrl","profilePicture","isDislike","statusText","statusClass","formatRelativeTime","renderSkeletonLikeEntry","npub","openLikersDialog","params","likeDetails","dialogComponent","initialContent","renderInitialContent","dialogElement","_a","dialog","enhanceLikeDetailsProgressively","npubs","likersList","uniqueAuthorIds","profileResults","getBatchedProfileMetadata","profileMap","result","npubMap","pubkey","profile","enhanced","profileContent","extractProfileMetadataContent","skeletonEntry","enhancedEntry","error","enhanceLikeDetailsIndividually","profileCache","profilePromises","cachedProfile","getProfileMetadata","__vitePreload","profileMetadata","promise"],"ignoreList":[],"sources":["../../src/nostr-like/dialog-likers-style.ts","../../src/nostr-like/dialog-likers.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nexport function getLikersDialogStyles(theme: 'light' | 'dark' = 'light'): string {\n const isDark = theme === 'dark';\n \n return `\n .likers-dialog-content {\n padding: 0;\n max-height: 60vh;\n overflow-y: auto;\n }\n\n .likers-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .like-entry {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 8px;\n background: ${isDark ? '#2a2a2a' : '#f8f9fa'};\n border: 1px solid ${isDark ? '#3a3a3a' : '#e9ecef'};\n transition: background-color 0.2s ease;\n }\n\n .like-entry:hover {\n background: ${isDark ? '#3a3a3a' : '#e9ecef'};\n }\n\n .like-author-info {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n }\n\n .like-author-picture {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n object-fit: cover;\n flex-shrink: 0;\n }\n\n .like-author-picture-default {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: ${isDark ? '#3a3a3a' : '#e9ecef'};\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .like-author-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n min-width: 0;\n }\n\n .like-author-link {\n color: ${isDark ? '#ffffff' : '#000000'};\n text-decoration: none;\n font-weight: 500;\n font-size: 14px;\n transition: color 0.2s ease;\n }\n\n .like-author-link:hover {\n color: ${isDark ? '#4a9eff' : '#1877f2'};\n text-decoration: underline;\n }\n\n .like-date {\n color: ${isDark ? '#b0b0b0' : '#65676b'};\n font-size: 12px;\n font-weight: 400;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .like-status {\n font-weight: 500;\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 4px;\n }\n\n .like-status.liked {\n color: ${isDark ? '#4a9eff' : '#1877f2'};\n background: ${isDark ? 'rgba(74, 158, 255, 0.1)' : 'rgba(24, 119, 242, 0.1)'};\n }\n\n .like-status.disliked {\n color: #d32f2f;\n background: rgba(211, 47, 47, 0.1);\n }\n\n .no-likes {\n text-align: center;\n color: ${isDark ? '#b0b0b0' : '#65676b'};\n font-size: 14px;\n padding: 40px 20px;\n }\n\n /* Skeleton loading states */\n .skeleton-entry {\n opacity: 0.7;\n }\n\n .skeleton-picture {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(90deg, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 25%, \n ${isDark ? '#4a4a4a' : '#e0e0e0'} 50%, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 75%\n );\n background-size: 200% 100%;\n animation: skeleton-loading 1.5s infinite;\n flex-shrink: 0;\n }\n\n .skeleton-name {\n width: 120px;\n height: 14px;\n background: linear-gradient(90deg, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 25%, \n ${isDark ? '#4a4a4a' : '#e0e0e0'} 50%, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 75%\n );\n background-size: 200% 100%;\n animation: skeleton-loading 1.5s infinite;\n border-radius: 2px;\n }\n\n @keyframes skeleton-loading {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n }\n\n /* Responsive */\n @media (max-width: 480px) {\n .likers-dialog-content {\n max-height: 70vh;\n }\n\n .like-entry {\n padding: 10px;\n }\n\n .like-author-picture,\n .like-author-picture-default,\n .skeleton-picture {\n width: 36px;\n height: 36px;\n }\n\n .like-author-link {\n font-size: 13px;\n }\n\n .like-date {\n font-size: 11px;\n }\n }\n\n /* Scrollbar styling */\n .likers-dialog-content::-webkit-scrollbar {\n width: 6px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-track {\n background: ${isDark ? '#2a2a2a' : '#f1f1f1'};\n border-radius: 3px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-thumb {\n background: ${isDark ? '#555' : '#c1c1c1'};\n border-radius: 3px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-thumb:hover {\n background: ${isDark ? '#777' : '#a8a8a8'};\n }\n `;\n}\n","// SPDX-License-Identifier: MIT\n\n// Import for side effects to register the custom element\nimport '../base/dialog-component/dialog-component';\nimport type { DialogComponent } from '../base/dialog-component/dialog-component';\nimport { getLikersDialogStyles } from './dialog-likers-style';\nimport { getBatchedProfileMetadata, extractProfileMetadataContent } from '../nostr-zap/zap-utils';\nimport { escapeHtml, formatRelativeTime, hexToNpub, isValidUrl } from '../common/utils';\nimport { LikeDetails } from './like-utils';\n\n/**\n * Modal dialog for displaying individual like details (likers).\n * \n * Shows a list of all users who liked a URL with:\n * - User's name\n * - User's profile picture\n * - Time of like (relative time)\n * - Clickable links to user profiles via njump.me\n */\n\nexport interface OpenLikersModalParams {\n likeDetails: LikeDetails[];\n theme?: 'light' | 'dark';\n}\n\n/**\n * Inject likers dialog content styles into document head\n * Prevents duplicate injection by checking for existing styles\n */\nexport const injectLikersDialogStyles = (theme: 'light' | 'dark' = 'light') => {\n // Remove existing likers dialog styles\n const existingStyles = document.querySelectorAll('style[data-likers-dialog-styles]');\n existingStyles.forEach(style => style.remove());\n \n const style = document.createElement('style');\n style.setAttribute('data-likers-dialog-styles', 'true');\n style.textContent = getLikersDialogStyles(theme);\n document.head.appendChild(style);\n}\n\ninterface EnhancedLikeDetails extends LikeDetails {\n authorName?: string;\n authorPicture?: string;\n authorNpub?: string;\n}\n\n/**\n * Render individual like entry HTML (with profile data)\n */\nfunction renderLikeEntry(like: EnhancedLikeDetails, index: number): string {\n const authorNameSafe = escapeHtml(like.authorName || 'Unknown liker');\n const npubSafe = like.authorNpub || hexToNpub(like.authorPubkey);\n const njumpUrl = `https://njump.me/${npubSafe}`;\n const profilePictureSafe = isValidUrl(like.authorPicture || '') ? like.authorPicture || '' : '';\n \n const profilePicture = profilePictureSafe \n ? `<img src=\"${profilePictureSafe}\" alt=\"${authorNameSafe}\" class=\"like-author-picture\" />`\n : `<div class=\"like-author-picture-default\">👤</div>`;\n \n const isDislike = like.content === '-';\n const statusText = isDislike ? 'Disliked' : 'Liked';\n const statusClass = isDislike ? 'disliked' : 'liked';\n \n return `\n <div class=\"like-entry\" data-like-index=\"${index}\" data-author-pubkey=\"${like.authorPubkey}\">\n <div class=\"like-author-info\">\n ${profilePicture}\n <div class=\"like-author-details\">\n <a href=\"${njumpUrl}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"like-author-link\">\n ${authorNameSafe}\n </a>\n <div class=\"like-date\">\n ${formatRelativeTime(Math.floor(like.date.getTime() / 1000))}\n <span class=\"like-status ${statusClass}\">${statusText}</span>\n </div>\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Render skeleton like entry HTML (with npub)\n */\nfunction renderSkeletonLikeEntry(like: LikeDetails, npub: string, index: number): string {\n const isDislike = like.content === '-';\n const statusText = isDislike ? 'Disliked' : 'Liked';\n const statusClass = isDislike ? 'disliked' : 'liked';\n \n return `\n <div class=\"like-entry skeleton-entry\" data-like-index=\"${index}\" data-author-pubkey=\"${like.authorPubkey}\">\n <div class=\"like-author-info\">\n <div class=\"skeleton-picture\"></div>\n <div class=\"like-author-details\">\n <div class=\"like-author-link skeleton-name\">\n ${escapeHtml(npub)}\n </div>\n <div class=\"like-date\">\n ${formatRelativeTime(Math.floor(like.date.getTime() / 1000))}\n <span class=\"like-status ${statusClass}\">${statusText}</span>\n </div>\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Opens the likers dialog showing individual like details\n */\nexport async function openLikersDialog(params: OpenLikersModalParams): Promise<DialogComponent> {\n const { likeDetails, theme = 'light' } = params;\n \n // Inject styles\n injectLikersDialogStyles(theme);\n \n // Ensure custom element is defined\n if (!customElements.get('dialog-component')) {\n await customElements.whenDefined('dialog-component');\n }\n \n // Create dialog component (not added to DOM)\n const dialogComponent = document.createElement('dialog-component') as DialogComponent;\n dialogComponent.setAttribute('header', 'Likers');\n if (params.theme) {\n dialogComponent.setAttribute('data-theme', params.theme);\n }\n \n // Initial content with skeleton loaders showing npubs\n const initialContent = await renderInitialContent(likeDetails);\n dialogComponent.innerHTML = initialContent;\n \n // Show the dialog (this will create and append the actual dialog element)\n dialogComponent.showModal();\n \n // Get the actual dialog element for progressive enhancement\n const dialogElement: HTMLDialogElement | null = \n dialogComponent.querySelector('.nostr-base-dialog') ||\n dialogComponent.shadowRoot?.querySelector('.nostr-base-dialog') ||\n document.body.querySelector('.nostr-base-dialog');\n \n if (!dialogElement) {\n console.error('[openLikersDialog] Failed to find dialog element after showModal()');\n throw new Error('Dialog element not found. The dialog may not have been created properly.');\n }\n \n // Type assertion: dialog is guaranteed to be non-null after the check above\n const dialog = dialogElement as HTMLDialogElement;\n \n // Start progressive enhancement\n if (dialog && likeDetails.length > 0) {\n enhanceLikeDetailsProgressively(dialog, likeDetails);\n }\n\n return dialogComponent;\n}\n\n/**\n * Render initial dialog content with skeleton loaders showing npubs\n */\nasync function renderInitialContent(likeDetails: LikeDetails[]): Promise<string> {\n if (likeDetails.length === 0) {\n return `\n <div class=\"likers-dialog-content\">\n <div class=\"likers-list\">\n <div class=\"no-likes\">No likes yet</div>\n </div>\n </div>\n `;\n }\n\n // Convert all pubkeys to npubs for immediate display\n const npubs = likeDetails.map(like => hexToNpub(like.authorPubkey));\n\n const skeletonEntries = likeDetails.map((like, index) => \n renderSkeletonLikeEntry(like, npubs[index], index)\n ).join('');\n\n return `\n <div class=\"likers-dialog-content\">\n <div class=\"likers-list\">\n ${skeletonEntries}\n </div>\n </div>\n `;\n}\n\n/**\n * Progressively enhance like details with profile information (batched approach)\n */\nasync function enhanceLikeDetailsProgressively(dialog: HTMLDialogElement, likeDetails: LikeDetails[]): Promise<void> {\n const likersList = dialog.querySelector('.likers-list') as HTMLElement;\n if (!likersList) return;\n\n // Get unique author IDs\n const uniqueAuthorIds = [...new Set(likeDetails.map(like => like.authorPubkey))];\n console.log(\"Nostr-Components: Likers dialog: Fetching profiles for\", uniqueAuthorIds.length, \"unique authors\");\n\n try {\n // Fetch all profiles in a single batched call\n const profileResults = await getBatchedProfileMetadata(uniqueAuthorIds);\n \n // Create a map for quick lookup\n const profileMap = new Map<string, any>();\n profileResults.forEach(result => {\n profileMap.set(result.id, result.profile);\n });\n\n // Convert all pubkeys to npubs for display\n const npubMap = new Map<string, string>();\n uniqueAuthorIds.forEach(pubkey => {\n npubMap.set(pubkey, hexToNpub(pubkey));\n });\n\n // Process each like entry\n for (let index = 0; index < likeDetails.length; index++) {\n const like = likeDetails[index];\n const profile = profileMap.get(like.authorPubkey);\n const npub = npubMap.get(like.authorPubkey) || like.authorPubkey;\n \n let enhanced: EnhancedLikeDetails;\n \n if (profile) {\n const profileContent = extractProfileMetadataContent(profile);\n enhanced = {\n ...like,\n authorName: profileContent.display_name || profileContent.name || npub,\n authorPicture: profileContent.picture,\n authorNpub: npub,\n };\n } else {\n // Fallback if profile not found\n enhanced = {\n ...like,\n authorName: npub,\n authorNpub: npub,\n };\n }\n\n // Find the corresponding skeleton entry by index and replace it\n const skeletonEntry = likersList.querySelector(`[data-like-index=\"${index}\"]`);\n if (skeletonEntry) {\n const enhancedEntry = renderLikeEntry(enhanced, index);\n skeletonEntry.outerHTML = enhancedEntry;\n }\n }\n\n console.log(\"Nostr-Components: Likers dialog: Progressive enhancement completed for\", likeDetails.length, \"like entries\");\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error in batched profile enhancement\", error);\n \n // Fallback to individual processing if batched approach fails\n console.log(\"Nostr-Components: Likers dialog: Falling back to individual profile fetching\");\n await enhanceLikeDetailsIndividually(dialog, likeDetails);\n }\n}\n\n/**\n * Fallback: Enhance like details individually (original approach)\n */\nasync function enhanceLikeDetailsIndividually(dialog: HTMLDialogElement, likeDetails: LikeDetails[]): Promise<void> {\n const likersList = dialog.querySelector('.likers-list') as HTMLElement;\n if (!likersList) return;\n\n // Create a map to track which profiles we've already fetched\n const profileCache = new Map<string, EnhancedLikeDetails>();\n \n // Fetch all profile metadata in parallel\n const profilePromises = likeDetails.map(async (like, index) => {\n // Check if we already have this profile cached\n if (profileCache.has(like.authorPubkey)) {\n const cachedProfile = profileCache.get(like.authorPubkey)!;\n return {\n index,\n enhanced: {\n ...like,\n authorName: cachedProfile.authorName,\n authorPicture: cachedProfile.authorPicture,\n authorNpub: cachedProfile.authorNpub,\n }\n };\n }\n\n try {\n const { getProfileMetadata } = await import('../nostr-zap/zap-utils');\n const profileMetadata = await getProfileMetadata(like.authorPubkey);\n const profileContent = extractProfileMetadataContent(profileMetadata);\n const npub = hexToNpub(like.authorPubkey);\n \n const enhanced = {\n ...like,\n authorName: profileContent.display_name || profileContent.name || npub,\n authorPicture: profileContent.picture,\n authorNpub: npub,\n };\n\n // Cache the profile for other entries from the same author\n profileCache.set(like.authorPubkey, enhanced);\n \n return {\n index,\n enhanced\n };\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error fetching profile for\", like.authorPubkey, error);\n // Fallback with just pubkey converted to npub\n const npub = hexToNpub(like.authorPubkey);\n const enhanced = {\n ...like,\n authorName: npub,\n authorNpub: npub,\n };\n \n // Cache the fallback profile\n profileCache.set(like.authorPubkey, enhanced);\n \n return {\n index,\n enhanced\n };\n }\n });\n\n // Process each profile as it becomes available\n for (const promise of profilePromises) {\n try {\n const { index, enhanced } = await promise;\n \n // Find the corresponding skeleton entry by index and replace it\n const skeletonEntry = likersList.querySelector(`[data-like-index=\"${index}\"]`);\n if (skeletonEntry) {\n const enhancedEntry = renderLikeEntry(enhanced, index);\n skeletonEntry.outerHTML = enhancedEntry;\n }\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error processing profile enhancement\", error);\n }\n }\n}\n"],"file":"assets/dialog-likers-D3c7WIMp.js"}
1
+ {"version":3,"mappings":"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","names":["getLikersDialogStyles","theme","isDark","injectLikersDialogStyles","style","renderLikeEntry","like","index","authorNameSafe","escapeHtml","njumpUrl","hexToNpub","profilePictureSafe","isValidUrl","profilePicture","isDislike","statusText","statusClass","formatRelativeTime","renderSkeletonLikeEntry","npub","openLikersDialog","params","likeDetails","dialogComponent","initialContent","renderInitialContent","dialogElement","_a","dialog","enhanceLikeDetailsProgressively","npubs","likersList","uniqueAuthorIds","profileResults","getBatchedProfileMetadata","profileMap","result","npubMap","pubkey","profile","enhanced","profileContent","extractProfileMetadataContent","skeletonEntry","enhancedEntry","error","enhanceLikeDetailsIndividually","profileCache","profilePromises","cachedProfile","getProfileMetadata","__vitePreload","profileMetadata","promise"],"ignoreList":[],"sources":["../../src/nostr-like/dialog-likers-style.ts","../../src/nostr-like/dialog-likers.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nexport function getLikersDialogStyles(theme: 'light' | 'dark' = 'light'): string {\n const isDark = theme === 'dark';\n \n return `\n .likers-dialog-content {\n padding: 0;\n max-height: 60vh;\n overflow-y: auto;\n }\n\n .likers-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n }\n\n .like-entry {\n display: flex;\n align-items: center;\n padding: 12px;\n border-radius: 8px;\n background: ${isDark ? '#2a2a2a' : '#f8f9fa'};\n border: 1px solid ${isDark ? '#3a3a3a' : '#e9ecef'};\n transition: background-color 0.2s ease;\n }\n\n .like-entry:hover {\n background: ${isDark ? '#3a3a3a' : '#e9ecef'};\n }\n\n .like-author-info {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n }\n\n .like-author-picture {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n object-fit: cover;\n flex-shrink: 0;\n }\n\n .like-author-picture-default {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: ${isDark ? '#3a3a3a' : '#e9ecef'};\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n flex-shrink: 0;\n }\n\n .like-author-details {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n min-width: 0;\n }\n\n .like-author-link {\n color: ${isDark ? '#ffffff' : '#000000'};\n text-decoration: none;\n font-weight: 500;\n font-size: 14px;\n transition: color 0.2s ease;\n }\n\n .like-author-link:hover {\n color: ${isDark ? '#4a9eff' : '#1877f2'};\n text-decoration: underline;\n }\n\n .like-date {\n color: ${isDark ? '#b0b0b0' : '#65676b'};\n font-size: 12px;\n font-weight: 400;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .like-status {\n font-weight: 500;\n font-size: 11px;\n padding: 2px 6px;\n border-radius: 4px;\n }\n\n .like-status.liked {\n color: ${isDark ? '#4a9eff' : '#1877f2'};\n background: ${isDark ? 'rgba(74, 158, 255, 0.1)' : 'rgba(24, 119, 242, 0.1)'};\n }\n\n .like-status.disliked {\n color: #d32f2f;\n background: rgba(211, 47, 47, 0.1);\n }\n\n .no-likes {\n text-align: center;\n color: ${isDark ? '#b0b0b0' : '#65676b'};\n font-size: 14px;\n padding: 40px 20px;\n }\n\n /* Skeleton loading states */\n .skeleton-entry {\n opacity: 0.7;\n }\n\n .skeleton-picture {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(90deg, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 25%, \n ${isDark ? '#4a4a4a' : '#e0e0e0'} 50%, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 75%\n );\n background-size: 200% 100%;\n animation: skeleton-loading 1.5s infinite;\n flex-shrink: 0;\n }\n\n .skeleton-name {\n width: 120px;\n height: 14px;\n background: linear-gradient(90deg, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 25%, \n ${isDark ? '#4a4a4a' : '#e0e0e0'} 50%, \n ${isDark ? '#3a3a3a' : '#f0f0f0'} 75%\n );\n background-size: 200% 100%;\n animation: skeleton-loading 1.5s infinite;\n border-radius: 2px;\n }\n\n @keyframes skeleton-loading {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n }\n\n /* Responsive */\n @media (max-width: 480px) {\n .likers-dialog-content {\n max-height: 70vh;\n }\n\n .like-entry {\n padding: 10px;\n }\n\n .like-author-picture,\n .like-author-picture-default,\n .skeleton-picture {\n width: 36px;\n height: 36px;\n }\n\n .like-author-link {\n font-size: 13px;\n }\n\n .like-date {\n font-size: 11px;\n }\n }\n\n /* Scrollbar styling */\n .likers-dialog-content::-webkit-scrollbar {\n width: 6px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-track {\n background: ${isDark ? '#2a2a2a' : '#f1f1f1'};\n border-radius: 3px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-thumb {\n background: ${isDark ? '#555' : '#c1c1c1'};\n border-radius: 3px;\n }\n\n .likers-dialog-content::-webkit-scrollbar-thumb:hover {\n background: ${isDark ? '#777' : '#a8a8a8'};\n }\n `;\n}\n","// SPDX-License-Identifier: MIT\n\n// Import for side effects to register the custom element\nimport '../base/dialog-component/dialog-component';\nimport type { DialogComponent } from '../base/dialog-component/dialog-component';\nimport { getLikersDialogStyles } from './dialog-likers-style';\nimport { getBatchedProfileMetadata, extractProfileMetadataContent } from '../nostr-zap/zap-utils';\nimport { escapeHtml, formatRelativeTime, hexToNpub, isValidUrl } from '../common/utils';\nimport { LikeDetails } from './like-utils';\n\n/**\n * Modal dialog for displaying individual like details (likers).\n * \n * Shows a list of all users who liked a URL with:\n * - User's name\n * - User's profile picture\n * - Time of like (relative time)\n * - Clickable links to user profiles via njump.me\n */\n\nexport interface OpenLikersModalParams {\n likeDetails: LikeDetails[];\n theme?: 'light' | 'dark';\n}\n\n/**\n * Inject likers dialog content styles into document head\n * Prevents duplicate injection by checking for existing styles\n */\nexport const injectLikersDialogStyles = (theme: 'light' | 'dark' = 'light') => {\n // Remove existing likers dialog styles\n const existingStyles = document.querySelectorAll('style[data-likers-dialog-styles]');\n existingStyles.forEach(style => style.remove());\n \n const style = document.createElement('style');\n style.setAttribute('data-likers-dialog-styles', 'true');\n style.textContent = getLikersDialogStyles(theme);\n document.head.appendChild(style);\n}\n\ninterface EnhancedLikeDetails extends LikeDetails {\n authorName?: string;\n authorPicture?: string;\n authorNpub?: string;\n}\n\n/**\n * Render individual like entry HTML (with profile data)\n */\nfunction renderLikeEntry(like: EnhancedLikeDetails, index: number): string {\n const authorNameSafe = escapeHtml(like.authorName || 'Unknown liker');\n const npubSafe = like.authorNpub || hexToNpub(like.authorPubkey);\n const njumpUrl = `https://njump.me/${npubSafe}`;\n const profilePictureSafe = isValidUrl(like.authorPicture || '') ? like.authorPicture || '' : '';\n \n const profilePicture = profilePictureSafe \n ? `<img src=\"${profilePictureSafe}\" alt=\"${authorNameSafe}\" class=\"like-author-picture\" />`\n : `<div class=\"like-author-picture-default\">👤</div>`;\n \n const isDislike = like.content === '-';\n const statusText = isDislike ? 'Disliked' : 'Liked';\n const statusClass = isDislike ? 'disliked' : 'liked';\n \n return `\n <div class=\"like-entry\" data-like-index=\"${index}\" data-author-pubkey=\"${like.authorPubkey}\">\n <div class=\"like-author-info\">\n ${profilePicture}\n <div class=\"like-author-details\">\n <a href=\"${njumpUrl}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"like-author-link\">\n ${authorNameSafe}\n </a>\n <div class=\"like-date\">\n ${formatRelativeTime(Math.floor(like.date.getTime() / 1000))}\n <span class=\"like-status ${statusClass}\">${statusText}</span>\n </div>\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Render skeleton like entry HTML (with npub)\n */\nfunction renderSkeletonLikeEntry(like: LikeDetails, npub: string, index: number): string {\n const isDislike = like.content === '-';\n const statusText = isDislike ? 'Disliked' : 'Liked';\n const statusClass = isDislike ? 'disliked' : 'liked';\n \n return `\n <div class=\"like-entry skeleton-entry\" data-like-index=\"${index}\" data-author-pubkey=\"${like.authorPubkey}\">\n <div class=\"like-author-info\">\n <div class=\"skeleton-picture\"></div>\n <div class=\"like-author-details\">\n <div class=\"like-author-link skeleton-name\">\n ${escapeHtml(npub)}\n </div>\n <div class=\"like-date\">\n ${formatRelativeTime(Math.floor(like.date.getTime() / 1000))}\n <span class=\"like-status ${statusClass}\">${statusText}</span>\n </div>\n </div>\n </div>\n </div>\n `;\n}\n\n/**\n * Opens the likers dialog showing individual like details\n */\nexport async function openLikersDialog(params: OpenLikersModalParams): Promise<DialogComponent> {\n const { likeDetails, theme = 'light' } = params;\n \n // Inject styles\n injectLikersDialogStyles(theme);\n \n // Ensure custom element is defined\n if (!customElements.get('dialog-component')) {\n await customElements.whenDefined('dialog-component');\n }\n \n // Create dialog component (not added to DOM)\n const dialogComponent = document.createElement('dialog-component') as DialogComponent;\n dialogComponent.setAttribute('header', 'Likers');\n if (params.theme) {\n dialogComponent.setAttribute('data-theme', params.theme);\n }\n \n // Initial content with skeleton loaders showing npubs\n const initialContent = await renderInitialContent(likeDetails);\n dialogComponent.innerHTML = initialContent;\n \n // Show the dialog (this will create and append the actual dialog element)\n dialogComponent.showModal();\n \n // Get the actual dialog element for progressive enhancement\n const dialogElement: HTMLDialogElement | null = \n dialogComponent.querySelector('.nostr-base-dialog') ||\n dialogComponent.shadowRoot?.querySelector('.nostr-base-dialog') ||\n document.body.querySelector('.nostr-base-dialog');\n \n if (!dialogElement) {\n console.error('[openLikersDialog] Failed to find dialog element after showModal()');\n throw new Error('Dialog element not found. The dialog may not have been created properly.');\n }\n \n // Type assertion: dialog is guaranteed to be non-null after the check above\n const dialog = dialogElement as HTMLDialogElement;\n \n // Start progressive enhancement\n if (dialog && likeDetails.length > 0) {\n enhanceLikeDetailsProgressively(dialog, likeDetails);\n }\n\n return dialogComponent;\n}\n\n/**\n * Render initial dialog content with skeleton loaders showing npubs\n */\nasync function renderInitialContent(likeDetails: LikeDetails[]): Promise<string> {\n if (likeDetails.length === 0) {\n return `\n <div class=\"likers-dialog-content\">\n <div class=\"likers-list\">\n <div class=\"no-likes\">No likes yet</div>\n </div>\n </div>\n `;\n }\n\n // Convert all pubkeys to npubs for immediate display\n const npubs = likeDetails.map(like => hexToNpub(like.authorPubkey));\n\n const skeletonEntries = likeDetails.map((like, index) => \n renderSkeletonLikeEntry(like, npubs[index], index)\n ).join('');\n\n return `\n <div class=\"likers-dialog-content\">\n <div class=\"likers-list\">\n ${skeletonEntries}\n </div>\n </div>\n `;\n}\n\n/**\n * Progressively enhance like details with profile information (batched approach)\n */\nasync function enhanceLikeDetailsProgressively(dialog: HTMLDialogElement, likeDetails: LikeDetails[]): Promise<void> {\n const likersList = dialog.querySelector('.likers-list') as HTMLElement;\n if (!likersList) return;\n\n // Get unique author IDs\n const uniqueAuthorIds = [...new Set(likeDetails.map(like => like.authorPubkey))];\n console.log(\"Nostr-Components: Likers dialog: Fetching profiles for\", uniqueAuthorIds.length, \"unique authors\");\n\n try {\n // Fetch all profiles in a single batched call\n const profileResults = await getBatchedProfileMetadata(uniqueAuthorIds);\n \n // Create a map for quick lookup\n const profileMap = new Map<string, any>();\n profileResults.forEach(result => {\n profileMap.set(result.id, result.profile);\n });\n\n // Convert all pubkeys to npubs for display\n const npubMap = new Map<string, string>();\n uniqueAuthorIds.forEach(pubkey => {\n npubMap.set(pubkey, hexToNpub(pubkey));\n });\n\n // Process each like entry\n for (let index = 0; index < likeDetails.length; index++) {\n const like = likeDetails[index];\n const profile = profileMap.get(like.authorPubkey);\n const npub = npubMap.get(like.authorPubkey) || like.authorPubkey;\n \n let enhanced: EnhancedLikeDetails;\n \n if (profile) {\n const profileContent = extractProfileMetadataContent(profile);\n enhanced = {\n ...like,\n authorName: profileContent.display_name || profileContent.name || npub,\n authorPicture: profileContent.picture,\n authorNpub: npub,\n };\n } else {\n // Fallback if profile not found\n enhanced = {\n ...like,\n authorName: npub,\n authorNpub: npub,\n };\n }\n\n // Find the corresponding skeleton entry by index and replace it\n const skeletonEntry = likersList.querySelector(`[data-like-index=\"${index}\"]`);\n if (skeletonEntry) {\n const enhancedEntry = renderLikeEntry(enhanced, index);\n skeletonEntry.outerHTML = enhancedEntry;\n }\n }\n\n console.log(\"Nostr-Components: Likers dialog: Progressive enhancement completed for\", likeDetails.length, \"like entries\");\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error in batched profile enhancement\", error);\n \n // Fallback to individual processing if batched approach fails\n console.log(\"Nostr-Components: Likers dialog: Falling back to individual profile fetching\");\n await enhanceLikeDetailsIndividually(dialog, likeDetails);\n }\n}\n\n/**\n * Fallback: Enhance like details individually (original approach)\n */\nasync function enhanceLikeDetailsIndividually(dialog: HTMLDialogElement, likeDetails: LikeDetails[]): Promise<void> {\n const likersList = dialog.querySelector('.likers-list') as HTMLElement;\n if (!likersList) return;\n\n // Create a map to track which profiles we've already fetched\n const profileCache = new Map<string, EnhancedLikeDetails>();\n \n // Fetch all profile metadata in parallel\n const profilePromises = likeDetails.map(async (like, index) => {\n // Check if we already have this profile cached\n if (profileCache.has(like.authorPubkey)) {\n const cachedProfile = profileCache.get(like.authorPubkey)!;\n return {\n index,\n enhanced: {\n ...like,\n authorName: cachedProfile.authorName,\n authorPicture: cachedProfile.authorPicture,\n authorNpub: cachedProfile.authorNpub,\n }\n };\n }\n\n try {\n const { getProfileMetadata } = await import('../nostr-zap/zap-utils');\n const profileMetadata = await getProfileMetadata(like.authorPubkey);\n const profileContent = extractProfileMetadataContent(profileMetadata);\n const npub = hexToNpub(like.authorPubkey);\n \n const enhanced = {\n ...like,\n authorName: profileContent.display_name || profileContent.name || npub,\n authorPicture: profileContent.picture,\n authorNpub: npub,\n };\n\n // Cache the profile for other entries from the same author\n profileCache.set(like.authorPubkey, enhanced);\n \n return {\n index,\n enhanced\n };\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error fetching profile for\", like.authorPubkey, error);\n // Fallback with just pubkey converted to npub\n const npub = hexToNpub(like.authorPubkey);\n const enhanced = {\n ...like,\n authorName: npub,\n authorNpub: npub,\n };\n \n // Cache the fallback profile\n profileCache.set(like.authorPubkey, enhanced);\n \n return {\n index,\n enhanced\n };\n }\n });\n\n // Process each profile as it becomes available\n for (const promise of profilePromises) {\n try {\n const { index, enhanced } = await promise;\n \n // Find the corresponding skeleton entry by index and replace it\n const skeletonEntry = likersList.querySelector(`[data-like-index=\"${index}\"]`);\n if (skeletonEntry) {\n const enhancedEntry = renderLikeEntry(enhanced, index);\n skeletonEntry.outerHTML = enhancedEntry;\n }\n } catch (error) {\n console.error(\"Nostr-Components: Likers dialog: Error processing profile enhancement\", error);\n }\n }\n}\n"],"file":"assets/dialog-likers-Bq6kUbS0.js"}
@@ -261,6 +261,6 @@ For regular events (kind ${u}), use:
261
261
  • #e filter for specific event IDs
262
262
  • kinds + authors filters for event queries`,!1)}})}if(t["#t"]){const a=t["#t"];a==null||a.forEach((c,l)=>{typeof c=="string"&&c.startsWith("#")&&s.error(GuardrailCheckId.FILTER_HASHTAG_WITH_PREFIX,`Filter[${e}].#t[${l}] contains hashtag with # prefix: "${c}". Hashtag values should NOT include the # symbol.`,`Remove the # prefix from hashtag filters:
263
263
  ✅ { "#t": ["nostr"] }
264
- ❌ { "#t": ["#nostr"] }`,!1)})}}function queryFullyFilled(t){return!!(filterIncludesIds(t.filter)&&resultHasAllRequestedIds(t))}function filterIncludesIds(t){return!!t.ids}function resultHasAllRequestedIds(t){const e=t.filter.ids;return!!e&&e.length===t.eventFirstSeen.size}function filterFromId(t){let e;if(t.match(NIP33_A_REGEX)){const[n,s,r]=t.split(":"),o={authors:[s],kinds:[Number.parseInt(n)]};return r&&(o["#d"]=[r]),o}if(t.match(BECH32_REGEX))try{switch(e=nip19_exports$1.decode(t),e.type){case"nevent":{const n={ids:[e.data.id]};return e.data.author&&(n.authors=[e.data.author]),e.data.kind&&(n.kinds=[e.data.kind]),n}case"note":return{ids:[e.data]};case"naddr":{const n={authors:[e.data.pubkey],kinds:[e.data.kind]};return e.data.identifier&&(n["#d"]=[e.data.identifier]),n}}}catch(n){console.error("Error decoding",t,n)}return{ids:[t]}}function isNip33AValue(t){return t.match(NIP33_A_REGEX)!==null}var NIP33_A_REGEX=/^(\d+):([0-9A-Fa-f]+)(?::(.*))?$/,BECH32_REGEX=/^n(event|ote|profile|pub|addr)1[\d\w]+$/;function relaysFromBech32(t,e){try{const n=nip19_exports$1.decode(t);if(["naddr","nevent"].includes(n==null?void 0:n.type)){const s=n.data;if(s!=null&&s.relays)return s.relays.map(r=>new NDKRelay(r,e.relayAuthDefaultPolicy,e))}}catch{}return[]}var defaultOpts={closeOnEose:!1,cacheUsage:"CACHE_FIRST",dontSaveToCache:!1,groupable:!0,groupableDelay:100,groupableDelayType:"at-most",cacheUnconstrainFilter:["limit","since","until"],includeMuted:!1},NDKSubscription=class extends lib$1.EventEmitter{constructor(e,n,s,r){super();g(this,"subId");g(this,"filters");g(this,"opts");g(this,"pool");g(this,"skipVerification",!1);g(this,"skipValidation",!1);g(this,"exclusiveRelay",!1);g(this,"relayFilters");g(this,"relaySet");g(this,"ndk");g(this,"debug");g(this,"eventFirstSeen",new Map);g(this,"eosesSeen",new Set);g(this,"lastEventReceivedAt");g(this,"mostRecentCacheEventTimestamp");g(this,"internalId");g(this,"closeOnEose");g(this,"poolMonitor");g(this,"skipOptimisticPublishEvent",!1);g(this,"cacheUnconstrainFilter");g(this,"onStopped");g(this,"eoseTimeout");g(this,"eosed",!1);this.ndk=e,this.opts={...defaultOpts,...s||{}},this.pool=this.opts.pool||e.pool;const o=Array.isArray(n)?n:[n],a=e.filterValidationMode==="validate"?"validate":e.filterValidationMode==="fix"?"fix":"ignore";if(this.filters=processFilters(o,a,e.debug,e),this.filters.length===0)throw new Error("Subscription must have at least one filter");this.subId=r||this.opts.subId,this.internalId=Math.random().toString(36).substring(7),this.debug=e.debug.extend(`subscription[${this.opts.subId??this.internalId}]`),this.opts.relaySet?this.relaySet=this.opts.relaySet:this.opts.relayUrls&&(this.relaySet=NDKRelaySet.fromRelayUrls(this.opts.relayUrls,this.ndk)),this.skipVerification=this.opts.skipVerification||!1,this.skipValidation=this.opts.skipValidation||!1,this.closeOnEose=this.opts.closeOnEose||!1,this.skipOptimisticPublishEvent=this.opts.skipOptimisticPublishEvent||!1,this.cacheUnconstrainFilter=this.opts.cacheUnconstrainFilter,this.exclusiveRelay=this.opts.exclusiveRelay||!1,this.opts.onEvent&&this.on("event",this.opts.onEvent),this.opts.onEose&&this.on("eose",this.opts.onEose),this.opts.onClose&&this.on("close",this.opts.onClose)}relaysMissingEose(){var n;return this.relayFilters?Array.from((n=this.relayFilters)==null?void 0:n.keys()).filter(s=>!this.eosesSeen.has(this.pool.getRelay(s,!1,!1))):[]}get filter(){return this.filters[0]}get groupableDelay(){var e;if(this.isGroupable())return(e=this.opts)==null?void 0:e.groupableDelay}get groupableDelayType(){var e;return((e=this.opts)==null?void 0:e.groupableDelayType)||"at-most"}isGroupable(){var e;return((e=this.opts)==null?void 0:e.groupable)||!1}shouldQueryCache(){var n;return this.opts.addSinceFromCache?!0:((n=this.opts)==null?void 0:n.cacheUsage)==="ONLY_RELAY"?!1:(this.filters.some(s=>{var r;return(r=s.kinds)==null?void 0:r.some(o=>kindIsEphemeral(o))}),!0)}shouldQueryRelays(){var e;return((e=this.opts)==null?void 0:e.cacheUsage)!=="ONLY_CACHE"}shouldWaitForCache(){var e;return this.opts.addSinceFromCache?!0:!!this.opts.closeOnEose&&!!((e=this.ndk.cacheAdapter)!=null&&e.locking)&&this.opts.cacheUsage!=="PARALLEL"}start(e=!0){let n;const s=o=>{for(const a of o)a.created_at&&(!this.mostRecentCacheEventTimestamp||a.created_at>this.mostRecentCacheEventTimestamp)&&(this.mostRecentCacheEventTimestamp=a.created_at),this.eventReceived(a,void 0,!0,!1);e||(n=o)},r=()=>{this.shouldQueryRelays()?(this.startWithRelays(),this.startPoolMonitor()):this.emit("eose",this)};return this.shouldQueryCache()?(n=this.startWithCache(),n instanceof Promise?this.shouldWaitForCache()?(n.then(o=>{if(s(o),queryFullyFilled(this)){this.emit("eose",this);return}r()}),null):(n.then(o=>{s(o),this.shouldQueryRelays()||this.emit("eose",this)}),this.shouldQueryRelays()&&r(),null):(s(n),queryFullyFilled(this)?this.emit("eose",this):r(),n)):(r(),null)}startPoolMonitor(){this.debug.extend("pool-monitor"),this.poolMonitor=e=>{var s,r;if((s=this.relayFilters)!=null&&s.has(e.url))return;calculateRelaySetsFromFilters(this.ndk,this.filters,this.pool,this.opts.relayGoalPerAuthor).get(e.url)&&((r=this.relayFilters)==null||r.set(e.url,this.filters),e.subscribe(this,this.filters))},this.pool.on("relay:connect",this.poolMonitor)}stop(){var e;this.emit("close",this),this.poolMonitor&&this.pool.off("relay:connect",this.poolMonitor),(e=this.onStopped)==null||e.call(this)}hasAuthorsFilter(){return this.filters.some(e=>{var n;return(n=e.authors)==null?void 0:n.length})}startWithCache(){var e;return(e=this.ndk.cacheAdapter)!=null&&e.query?this.ndk.cacheAdapter.query(this):[]}startWithRelays(){let e=this.filters;if(this.opts.addSinceFromCache&&this.mostRecentCacheEventTimestamp){const n=this.mostRecentCacheEventTimestamp+1;e=e.map(s=>({...s,since:Math.max(s.since||0,n)}))}if(!this.relaySet||this.relaySet.relays.size===0)this.relayFilters=calculateRelaySetsFromFilters(this.ndk,e,this.pool,this.opts.relayGoalPerAuthor);else{this.relayFilters=new Map;for(const n of this.relaySet.relays)this.relayFilters.set(n.url,e)}for(const[n,s]of this.relayFilters)this.pool.getRelay(n,!0,!0,s).subscribe(this,s)}refreshRelayConnections(){var n,s;if(this.relaySet&&this.relaySet.relays.size>0)return;const e=calculateRelaySetsFromFilters(this.ndk,this.filters,this.pool,this.opts.relayGoalPerAuthor);for(const[r,o]of e)(n=this.relayFilters)!=null&&n.has(r)||((s=this.relayFilters)==null||s.set(r,o),this.pool.getRelay(r,!0,!0,o).subscribe(this,o))}eventReceived(e,n,s=!1,r=!1){var l,u,f;const o=e.id,a=this.eventFirstSeen.has(o);let c;if(e instanceof NDKEvent&&(c=e),a){const h=Date.now()-(this.eventFirstSeen.get(o)||0);if(this.emit("event:dup",e,n,h,this,s,r),(u=this.opts)!=null&&u.onEventDup&&this.opts.onEventDup(e,n,h,this,s,r),!s&&!r&&n&&((f=this.ndk.cacheAdapter)!=null&&f.setEventDup)&&!this.opts.dontSaveToCache&&(c??(c=e instanceof NDKEvent?e:new NDKEvent(this.ndk,e)),this.ndk.cacheAdapter.setEventDup(c,n)),n){const p=verifiedSignatures.get(o);if(p&&typeof p=="string")if(e.sig===p)n.addValidatedEvent();else{const y=e instanceof NDKEvent?e:new NDKEvent(this.ndk,e);this.ndk.reportInvalidSignature(y,n)}}}else{if(c??(c=new NDKEvent(this.ndk,e)),c.ndk=this.ndk,c.relay=n,!s&&!r){if(!this.skipValidation&&!c.isValid){this.debug("Event failed validation %s from relay %s",o,n==null?void 0:n.url);return}if(n)if(n.shouldValidateEvent()&&!this.skipVerification)if(c.relay=n,this.ndk.asyncSigVerification)c.verifySignature(!0);else{if(!c.verifySignature(!0)){this.debug("Event failed signature validation",e),this.ndk.reportInvalidSignature(c,n);return}n.addValidatedEvent()}else n.addNonValidatedEvent();this.ndk.cacheAdapter&&!this.opts.dontSaveToCache&&this.ndk.cacheAdapter.setEvent(c,this.filters,n)}if(!this.opts.includeMuted&&this.ndk.muteFilter&&this.ndk.muteFilter(c)){this.debug("Event muted, skipping");return}(!r||this.skipOptimisticPublishEvent!==!0)&&(this.emitEvent(((l=this.opts)==null?void 0:l.wrap)??!1,c,n,s,r),this.eventFirstSeen.set(o,Date.now()))}this.lastEventReceivedAt=Date.now()}emitEvent(e,n,s,r,o){const a=e?wrapEvent(n):n;a instanceof Promise?a.then(c=>this.emitEvent(!1,c,s,r,o)):a&&this.emit("event",a,s,this,r,o)}closedReceived(e,n){this.emit("closed",e,n)}eoseReceived(e){var a;this.debug("EOSE received from %s",e.url),this.eosesSeen.add(e);let n=this.lastEventReceivedAt?Date.now()-this.lastEventReceivedAt:void 0;const s=this.eosesSeen.size===((a=this.relayFilters)==null?void 0:a.size),r=queryFullyFilled(this),o=c=>{var l;this.debug("Performing EOSE: %s %d",c,this.eosed),!this.eosed&&(this.eoseTimeout&&clearTimeout(this.eoseTimeout),this.emit("eose",this),this.eosed=!0,(l=this.opts)!=null&&l.closeOnEose&&this.stop())};if(r||s)o("query filled or seen all");else if(this.relayFilters){let c=1e3;const l=new Set(this.pool.connectedRelays().map(h=>h.url)),u=Array.from(this.relayFilters.keys()).filter(h=>l.has(h));if(u.length===0){this.debug("No connected relays, waiting for all relays to connect",Array.from(this.relayFilters.keys()).join(", "));return}const f=this.eosesSeen.size/u.length;if(this.debug("Percentage of relays that have sent EOSE",{subId:this.subId,percentageOfRelaysThatHaveSentEose:f,seen:this.eosesSeen.size,total:u.length}),this.eosesSeen.size>=2&&f>=.5){if(c=c*(1-f),c===0){o("time to wait was 0");return}this.eoseTimeout&&clearTimeout(this.eoseTimeout);const h=()=>{n=this.lastEventReceivedAt?Date.now()-this.lastEventReceivedAt:void 0,n!==void 0&&n<20?this.eoseTimeout=setTimeout(h,c):o(`send eose timeout: ${c}`)};this.eoseTimeout=setTimeout(h,c)}}}},kindIsEphemeral=t=>t>=2e4&&t<3e4;async function follows(t,e,n=3){var r,o;if(!this.ndk)throw new Error("NDK not set");const s=await this.ndk.fetchEvent({kinds:[n],authors:[this.pubkey]},t||{groupable:!1});if(s){const a=new Set;return s.tags.forEach(c=>{c[0]==="p"&&c[1]&&isValidPubkey(c[1])&&a.add(c[1])}),e&&((o=(r=this.ndk)==null?void 0:r.outboxTracker)==null||o.trackUsers(Array.from(a))),[...a].reduce((c,l)=>{const u=new NDKUser({pubkey:l});return u.ndk=this.ndk,c.add(u),c},new Set)}return new Set}var NIP05_REGEX=/^(?:([\w.+-]+)@)?([\w.-]+)$/;async function getNip05For(t,e,n=fetch,s={}){return await t.queuesNip05.add({id:e,func:async()=>{var l,u,f;if((l=t.cacheAdapter)!=null&&l.loadNip05){const h=await t.cacheAdapter.loadNip05(e);if(h!=="missing"){if(h){const p=new NDKUser({pubkey:h.pubkey,relayUrls:h.relays,nip46Urls:h.nip46});return p.ndk=t,p}if(s.cache!=="no-cache")return null}}const r=e.match(NIP05_REGEX);if(!r)return null;const[o,a="_",c]=r;try{const h=await n(`https://${c}/.well-known/nostr.json?name=${a}`,s),{names:p,relays:y,nip46:b}=parseNIP05Result(await h.json()),m=p[a.toLowerCase()];let w=null;return m&&(w={pubkey:m,relays:y==null?void 0:y[m],nip46:b==null?void 0:b[m]}),(u=t==null?void 0:t.cacheAdapter)!=null&&u.saveNip05&&t.cacheAdapter.saveNip05(e,w),w}catch(h){return(f=t==null?void 0:t.cacheAdapter)!=null&&f.saveNip05&&(t==null||t.cacheAdapter.saveNip05(e,null)),console.error("Failed to fetch NIP05 for",e,h),null}}})}function parseNIP05Result(t){const e={names:{}};for(const[n,s]of Object.entries(t.names))typeof n=="string"&&typeof s=="string"&&(e.names[n.toLowerCase()]=s);if(t.relays){e.relays={};for(const[n,s]of Object.entries(t.relays))typeof n=="string"&&Array.isArray(s)&&(e.relays[n]=s.filter(r=>typeof r=="string"))}if(t.nip46){e.nip46={};for(const[n,s]of Object.entries(t.nip46))typeof n=="string"&&Array.isArray(s)&&(e.nip46[n]=s.filter(r=>typeof r=="string"))}return e}function profileFromEvent(t){const e={};let n;try{n=JSON.parse(t.content)}catch(s){throw new Error(`Failed to parse profile event: ${s}`)}e.profileEvent=JSON.stringify(t.rawEvent());for(const s of Object.keys(n))switch(s){case"name":e.name=n.name;break;case"display_name":e.displayName=n.display_name;break;case"image":case"picture":e.picture=n.picture||n.image,e.image=e.picture;break;case"banner":e.banner=n.banner;break;case"bio":e.bio=n.bio;break;case"nip05":e.nip05=n.nip05;break;case"lud06":e.lud06=n.lud06;break;case"lud16":e.lud16=n.lud16;break;case"about":e.about=n.about;break;case"website":e.website=n.website;break;default:e[s]=n[s];break}return e.created_at=t.created_at,e}function serializeProfile(t){const e={};for(const[n,s]of Object.entries(t))switch(n){case"username":case"name":e.name=s;break;case"displayName":e.display_name=s;break;case"image":case"picture":e.picture=s;break;case"bio":case"about":e.about=s;break;default:e[n]=s;break}return JSON.stringify(e)}var NDKUser=class Ve{constructor(e){g(this,"ndk");g(this,"profile");g(this,"profileEvent");g(this,"_npub");g(this,"_pubkey");g(this,"relayUrls",[]);g(this,"nip46Urls",[]);g(this,"follows",follows.bind(this));if(e.npub&&(this._npub=e.npub),e.hexpubkey&&(this._pubkey=e.hexpubkey),e.pubkey&&(this._pubkey=e.pubkey),e.relayUrls&&(this.relayUrls=e.relayUrls),e.nip46Urls&&(this.nip46Urls=e.nip46Urls),e.nprofile)try{const n=nip19_exports$1.decode(e.nprofile);n.type==="nprofile"&&(this._pubkey=n.data.pubkey,n.data.relays&&n.data.relays.length>0&&this.relayUrls.push(...n.data.relays))}catch(n){console.error("Failed to decode nprofile",n)}}get npub(){if(!this._npub){if(!this._pubkey)throw new Error("pubkey not set");this._npub=nip19_exports$1.npubEncode(this.pubkey)}return this._npub}get nprofile(){var n,s;const e=(s=(n=this.profileEvent)==null?void 0:n.onRelays)==null?void 0:s.map(r=>r.url);return nip19_exports$1.nprofileEncode({pubkey:this.pubkey,relays:e})}set npub(e){this._npub=e}get pubkey(){if(!this._pubkey){if(!this._npub)throw new Error("npub not set");this._pubkey=nip19_exports$1.decode(this.npub).data}return this._pubkey}set pubkey(e){this._pubkey=e}filter(){return{"#p":[this.pubkey]}}async getZapInfo(e){if(!this.ndk)throw new Error("No NDK instance found");const n=async a=>{if(!e)return a;let c;const l=new Promise((u,f)=>{c=setTimeout(()=>f(new Error("Timeout")),e)});try{const u=await Promise.race([a,l]);return c&&clearTimeout(c),u}catch(u){if(u instanceof Error&&u.message==="Timeout")try{return await a}catch{return}return}},[s,r]=await Promise.all([n(this.fetchProfile()),n(this.ndk.fetchEvent({kinds:[10019],authors:[this.pubkey]}))]),o=new Map;if(r){const a=NDKCashuMintList.from(r);a.mints.length>0&&o.set("nip61",{mints:a.mints,relays:a.relays,p2pk:a.p2pk})}if(s){const{lud06:a,lud16:c}=s;o.set("nip57",{lud06:a,lud16:c})}return o}static async fromNip05(e,n,s=!1){if(!n)throw new Error("No NDK instance found");const r={};s&&(r.cache="no-cache");const o=await getNip05For(n,e,n==null?void 0:n.httpFetch,r);if(o){const a=new Ve({pubkey:o.pubkey,relayUrls:o.relays,nip46Urls:o.nip46});return a.ndk=n,a}}async fetchProfile(e,n=!1){if(!this.ndk)throw new Error("NDK not set");let s=null;if(this.ndk.cacheAdapter&&(this.ndk.cacheAdapter.fetchProfile||this.ndk.cacheAdapter.fetchProfileSync)&&(e==null?void 0:e.cacheUsage)!=="ONLY_RELAY"){let r=null;if(this.ndk.cacheAdapter.fetchProfileSync?r=this.ndk.cacheAdapter.fetchProfileSync(this.pubkey):this.ndk.cacheAdapter.fetchProfile&&(r=await this.ndk.cacheAdapter.fetchProfile(this.pubkey)),r)return this.profile=r,r}return e??(e={}),e.cacheUsage??(e.cacheUsage="ONLY_RELAY"),e.closeOnEose??(e.closeOnEose=!0),e.groupable??(e.groupable=!0),e.groupableDelay??(e.groupableDelay=250),s||(s=await this.ndk.fetchEvent({kinds:[0],authors:[this.pubkey]},e)),s?(this.profile=profileFromEvent(s),n&&this.profile&&this.ndk.cacheAdapter&&this.ndk.cacheAdapter.saveProfile&&this.ndk.cacheAdapter.saveProfile(this.pubkey,this.profile),this.profile):null}async followSet(e,n,s=3){const r=await this.follows(e,n,s);return new Set(Array.from(r).map(o=>o.pubkey))}tagReference(){return["p",this.pubkey]}referenceTags(e){const n=[["p",this.pubkey]];return e&&n[0].push("",e),n}async publish(){if(!this.ndk)throw new Error("No NDK instance found");if(!this.profile)throw new Error("No profile available");this.ndk.assertSigner(),await new NDKEvent(this.ndk,{kind:0,content:serializeProfile(this.profile)}).publish()}async follow(e,n,s=3){if(!this.ndk)throw new Error("No NDK instance found");this.ndk.assertSigner(),n||(n=await this.follows(void 0,void 0,s));const r=typeof e=="string"?e:e.pubkey;if(Array.from(n).some(c=>typeof c=="string"?c===r:c.pubkey===r))return!1;n.add(e);const a=new NDKEvent(this.ndk,{kind:s});for(const c of n)typeof c=="string"?a.tags.push(["p",c]):a.tag(c);return await a.publish(),!0}async unfollow(e,n,s=3){if(!this.ndk)throw new Error("No NDK instance found");this.ndk.assertSigner(),n||(n=await this.follows(void 0,void 0,s));const r=typeof e=="string"?e:e.pubkey,o=new Set;let a=!1;for(const l of n)(typeof l=="string"?l:l.pubkey)!==r?o.add(l):a=!0;if(!a)return!1;const c=new NDKEvent(this.ndk,{kind:s});for(const l of o)typeof l=="string"?c.tags.push(["p",l]):c.tag(l);return await c.publish()}async validateNip05(e){if(!this.ndk)throw new Error("No NDK instance found");const n=await getNip05For(this.ndk,e);return n===null?null:n.pubkey===this.pubkey}},signerRegistry=new Map;function registerSigner(t,e){signerRegistry.set(t,e)}var NDKPrivateKeySigner=class Fe{constructor(e,n){g(this,"_user");g(this,"_privateKey");g(this,"_pubkey");if(typeof e=="string")if(e.startsWith("nsec1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s==="nsec")this._privateKey=r;else throw new Error("Invalid private key provided.")}else if(e.length===64)this._privateKey=hexToBytes(e);else throw new Error("Invalid private key provided.");else this._privateKey=e;this._pubkey=getPublicKey(this._privateKey),n&&(this._user=n.getUser({pubkey:this._pubkey})),this._user??(this._user=new NDKUser({pubkey:this._pubkey}))}get privateKey(){if(!this._privateKey)throw new Error("Not ready");return bytesToHex(this._privateKey)}get pubkey(){if(!this._pubkey)throw new Error("Not ready");return this._pubkey}get nsec(){if(!this._privateKey)throw new Error("Not ready");return nip19_exports$1.nsecEncode(this._privateKey)}get npub(){if(!this._pubkey)throw new Error("Not ready");return nip19_exports$1.npubEncode(this._pubkey)}encryptToNcryptsec(e,n=16,s=2){if(!this._privateKey)throw new Error("Private key not available");return encrypt$1(this._privateKey,e,n,s)}static generate(){const e=generateSecretKey();return new Fe(e)}static fromNcryptsec(e,n,s){const r=decrypt$1(e,n);return new Fe(r,s)}async blockUntilReady(){return this._user}async user(){return this._user}get userSync(){return this._user}async sign(e){if(!this._privateKey)throw Error("Attempted to sign without a private key");return finalizeEvent(e,this._privateKey).sig}async encryptionEnabled(e){const n=[];return(!e||e==="nip04")&&n.push("nip04"),(!e||e==="nip44")&&n.push("nip44"),n}async encrypt(e,n,s){if(!this._privateKey||!this.privateKey)throw Error("Attempted to encrypt without a private key");const r=e.pubkey;if(s==="nip44"){const o=nip44_exports.v2.utils.getConversationKey(this._privateKey,r);return await nip44_exports.v2.encrypt(n,o)}return await nip04_exports.encrypt(this._privateKey,r,n)}async decrypt(e,n,s){if(!this._privateKey||!this.privateKey)throw Error("Attempted to decrypt without a private key");const r=e.pubkey;if(s==="nip44"){const o=nip44_exports.v2.utils.getConversationKey(this._privateKey,r);return await nip44_exports.v2.decrypt(n,o)}return await nip04_exports.decrypt(this._privateKey,r,n)}toPayload(){if(!this._privateKey)throw new Error("Private key not available");const e={type:"private-key",payload:this.privateKey};return JSON.stringify(e)}static async fromPayload(e,n){const s=JSON.parse(e);if(s.type!=="private-key")throw new Error(`Invalid payload type: expected 'private-key', got ${s.type}`);if(!s.payload||typeof s.payload!="string")throw new Error("Invalid payload content for private-key signer");return new Fe(s.payload,n)}};registerSigner("private-key",NDKPrivateKeySigner);function dedup(t,e){return t.created_at>e.created_at?t:e}async function getRelayListForUser(t,e){return(await getRelayListForUsers([t],e)).get(t)}async function getRelayListForUsers(t,e,n=!1,s=1e3,r){var p;const o=e.outboxPool||e.pool,a=new Set;for(const y of o.relays.values())a.add(y);if(r)for(const y of r.values())for(const b of y){const m=o.getRelay(b,!0,!0);m&&a.add(m)}const c=new Map,l=new Map,u=new NDKRelaySet(a,e);if((p=e.cacheAdapter)!=null&&p.locking&&!n){const y=await e.fetchEvents({kinds:[3,10002],authors:Array.from(new Set(t))},{cacheUsage:"ONLY_CACHE",subId:"ndk-relay-list-fetch"});for(const b of y)b.kind===10002&&c.set(b.pubkey,NDKRelayList.from(b));for(const b of y)if(b.kind===3){if(c.has(b.pubkey))continue;const m=relayListFromKind3(e,b);m&&l.set(b.pubkey,m)}t=t.filter(b=>!c.has(b)&&!l.has(b))}if(t.length===0)return c;const f=new Map,h=new Map;return new Promise(y=>{let b=!1;(async()=>{const w={closeOnEose:!0,pool:o,groupable:!0,subId:"ndk-relay-list-fetch",addSinceFromCache:!0,relaySet:u};u&&(w.relaySet=u),e.subscribe({kinds:[3,10002],authors:t},w,{onEvent:P=>{if(P.kind===10002){const O=f.get(P.pubkey);if(O&&O.created_at>P.created_at)return;f.set(P.pubkey,P)}else if(P.kind===3){const O=h.get(P.pubkey);if(O&&O.created_at>P.created_at)return;h.set(P.pubkey,P)}},onEose:()=>{if(!b){b=!0,e.debug(`[getRelayListForUsers] EOSE - relayListEvents: ${f.size}, contactListEvents: ${h.size}`);for(const P of f.values())c.set(P.pubkey,NDKRelayList.from(P));for(const P of t){if(c.has(P))continue;const O=h.get(P);if(!O)continue;const U=relayListFromKind3(e,O);U&&c.set(P,U)}e.debug(`[getRelayListForUsers] Returning ${c.size} relay lists for ${t.length} pubkeys`),y(c)}}});const k=Array.from(a).some(P=>P.status<=2),A=Array.from(a).some(P=>P.status===4);let B=s;(k||A)&&(B=s+3e3),e.debug(`[getRelayListForUsers] Setting fallback timeout to ${B}ms (disconnected: ${k}, connecting: ${A})`,{pubkeys:t}),setTimeout(()=>{b||(b=!0,e.debug(`[getRelayListForUsers] Timeout reached, returning ${c.size} relay lists`),y(c))},B)})()})}var OutboxItem=class{constructor(t){g(this,"type");g(this,"relayUrlScores");g(this,"readRelays");g(this,"writeRelays");this.type=t,this.relayUrlScores=new Map,this.readRelays=new Set,this.writeRelays=new Set}},OutboxTracker=class extends lib$1.EventEmitter{constructor(e){super();g(this,"data");g(this,"ndk");g(this,"debug");this.ndk=e,this.debug=e.debug.extend("outbox-tracker"),this.data=new dist.LRUCache({maxSize:1e5,entryExpirationTimeInMS:2*60*1e3})}async trackUsers(e,n=!1){const s=[];for(let r=0;r<e.length;r+=400){const o=e.slice(r,r+400),a=o.map(l=>getKeyFromItem(l)).filter(l=>!this.data.has(l));if(a.length===0)continue;for(const l of a)this.data.set(l,new OutboxItem("user"));const c=new Map;for(const l of o)l instanceof NDKUser&&l.relayUrls.length>0&&c.set(l.pubkey,l.relayUrls);s.push(new Promise(l=>{getRelayListForUsers(a,this.ndk,n,1e3,c).then(u=>{this.debug(`Received relay lists for ${u.size} pubkeys out of ${a.length} requested`);for(const[f,h]of u){let p=this.data.get(f);if(p??(p=new OutboxItem("user")),h){if(p.readRelays=new Set(normalize(h.readRelayUrls)),p.writeRelays=new Set(normalize(h.writeRelayUrls)),this.ndk.relayConnectionFilter){for(const y of p.readRelays)this.ndk.relayConnectionFilter(y)||p.readRelays.delete(y);for(const y of p.writeRelays)this.ndk.relayConnectionFilter(y)||p.writeRelays.delete(y)}this.data.set(f,p),this.emit("user:relay-list-updated",f,p),this.debug(`Adding ${p.readRelays.size} read relays and ${p.writeRelays.size} write relays for ${f}`,h==null?void 0:h.rawEvent())}}}).finally(l)}))}return Promise.all(s)}track(e,n,s=!0){const r=getKeyFromItem(e);n??(n=getTypeFromItem(e));let o=this.data.get(r);return o||(o=new OutboxItem(n),e instanceof NDKUser&&this.trackUsers([e])),o}};function getKeyFromItem(t){return t instanceof NDKUser?t.pubkey:t}function getTypeFromItem(t){return t instanceof NDKUser?"user":"kind"}function correctRelaySet(t,e){const n=e.connectedRelays();if(!Array.from(t.relays).some(r=>n.map(o=>o.url).includes(r.url)))for(const r of n)t.addRelay(r);if(n.length===0)for(const r of e.relays.values())t.addRelay(r);return t}var NDKSubscriptionManager=class{constructor(){g(this,"subscriptions");g(this,"seenEvents",new dist.LRUCache({maxSize:1e4,entryExpirationTimeInMS:5*60*1e3}));this.subscriptions=new Map}add(t){this.subscriptions.set(t.internalId,t),t.onStopped,t.onStopped=()=>{this.subscriptions.delete(t.internalId)},t.on("close",()=>{this.subscriptions.delete(t.internalId)})}seenEvent(t,e){const n=this.seenEvents.get(t)||[];n.some(s=>s.url===e.url)||n.push(e),this.seenEvents.set(t,n)}dispatchEvent(t,e,n=!1){e&&this.seenEvent(t.id,e);const s=this.subscriptions.values(),r=[];for(const o of s)matchFilters(o.filters,t)&&r.push(o);for(const o of r){if(o.exclusiveRelay&&o.relaySet){let a=!1;if(n?a=!o.skipOptimisticPublishEvent:e?a=o.relaySet.relays.has(e):a=(this.seenEvents.get(t.id)||[]).some(l=>o.relaySet.relays.has(l)),!a){o.debug.extend("exclusive-relay")("Rejected event %s from %s (relay not in exclusive set)",t.id,(e==null?void 0:e.url)||(n?"optimistic":"cache"));continue}}o.eventReceived(t,e,!1,n)}}},debug6=createDebug5("ndk:active-user");async function getUserRelayList(t){if(!this.autoConnectUserRelays)return;const e=await getRelayListForUser(t.pubkey,this);if(e){for(const n of e.relays){let s=this.pool.relays.get(n);s||(s=new NDKRelay(n,this.relayAuthDefaultPolicy,this),this.pool.addRelay(s))}return debug6("Connected to %d user relays",e.relays.length),e}}async function setActiveUser(t){if(!this.autoConnectUserRelays)return;const e=this.outboxPool||this.pool;e.connectedRelays.length>0?await getUserRelayList.call(this,t):e.once("connect",async()=>{await getUserRelayList.call(this,t)})}function getEntity(t){try{const e=nip19_exports$1.decode(t);return e.type==="npub"?npub(this,e.data):e.type==="nprofile"?nprofile(this,e.data):e}catch{return null}}function npub(t,e){return t.getUser({pubkey:e})}function nprofile(t,e){const n=t.getUser({pubkey:e.pubkey});return e.relays&&(n.relayUrls=e.relays),n}function isValidHint(t){if(!t||t==="")return!1;try{return new URL(t),!0}catch{return!1}}async function fetchEventFromTag(t,e,n,s={type:"timeout"}){const r=this.debug.extend("fetch-event-from-tag"),[o,a,c]=t;n={},r("fetching event from tag",t,n,s);const l=getRelaysForSync(this,e.pubkey);if(l&&l.size>0){r("fetching event from author relays %o",Array.from(l));const m=NDKRelaySet.fromRelayUrls(Array.from(l),this),w=await this.fetchEvent(a,n,m);if(w)return w}else r("no author relays found for %s",e.pubkey,e);const u=calculateRelaySetsFromFilters(this,[{ids:[a]}],this.pool);r("fetching event without relay hint",u);const f=await this.fetchEvent(a,n);if(f)return f;if(c&&c!==""){const m=await this.fetchEvent(a,n,this.pool.getRelay(c,!0,!0,[{ids:[a]}]));if(m)return m}let h;const p=isValidHint(c)?this.pool.getRelay(c,!1,!0,[{ids:[a]}]):void 0,y=new Promise(m=>{this.fetchEvent(a,n,p).then(m)});if(!isValidHint(c)||s.type==="none")return y;const b=new Promise(async m=>{const w=s.relaySet,k=s.timeout??1500,A=new Promise(B=>setTimeout(B,k));if(s.type==="timeout"&&await A,h)m(h);else{r("fallback fetch triggered");const B=await this.fetchEvent(a,n,w);m(B)}});switch(s.type){case"timeout":return Promise.race([y,b]);case"eose":return h=await y,h||b}}var Queue=class{constructor(t,e){g(this,"queue",[]);g(this,"maxConcurrency");g(this,"processing",new Set);g(this,"promises",new Map);this.maxConcurrency=e}add(t){if(this.promises.has(t.id))return this.promises.get(t.id);const e=new Promise((n,s)=>{this.queue.push({...t,func:()=>t.func().then(r=>(n(r),r),r=>{throw s(r),r})}),this.process()});return this.promises.set(t.id,e),e.finally(()=>{this.promises.delete(t.id),this.processing.delete(t.id),this.process()}),e}process(){if(this.processing.size>=this.maxConcurrency||this.queue.length===0)return;const t=this.queue.shift();!t||this.processing.has(t.id)||(this.processing.add(t.id),t.func())}clear(){this.queue=[]}clearProcessing(){this.processing.clear()}clearAll(){this.clear(),this.clearProcessing()}length(){return this.queue.length}},DEFAULT_OUTBOX_RELAYS=["wss://purplepag.es/","wss://nos.lol/"],NDK=class extends lib$1.EventEmitter{constructor(e={}){super();g(this,"_explicitRelayUrls");g(this,"pool");g(this,"outboxPool");g(this,"_signer");g(this,"_activeUser");g(this,"cacheAdapter");g(this,"debug");g(this,"devWriteRelaySet");g(this,"outboxTracker");g(this,"muteFilter");g(this,"relayConnectionFilter");g(this,"clientName");g(this,"clientNip89");g(this,"queuesZapConfig");g(this,"queuesNip05");g(this,"asyncSigVerification",!1);g(this,"initialValidationRatio",1);g(this,"lowestValidationRatio",.1);g(this,"validationRatioFn");g(this,"filterValidationMode","validate");g(this,"subManager");g(this,"aiGuardrails");g(this,"_signatureVerificationFunction");g(this,"_signatureVerificationWorker");g(this,"signatureVerificationTimeMs",0);g(this,"publishingFailureHandled",!1);g(this,"pools",[]);g(this,"relayAuthDefaultPolicy");g(this,"httpFetch");g(this,"netDebug");g(this,"autoConnectUserRelays",!0);g(this,"_wallet");g(this,"walletConfig");g(this,"fetchEventFromTag",fetchEventFromTag.bind(this));g(this,"getEntity",getEntity.bind(this));this.debug=e.debug||createDebug5("ndk"),this.netDebug=e.netDebug,this._explicitRelayUrls=e.explicitRelayUrls||[],this.subManager=new NDKSubscriptionManager,this.pool=new NDKPool(e.explicitRelayUrls||[],this),this.pool.name="Main",this.pool.on("relay:auth",async(n,s)=>{this.relayAuthDefaultPolicy&&await this.relayAuthDefaultPolicy(n,s)}),this.autoConnectUserRelays=e.autoConnectUserRelays??!0,this.clientName=e.clientName,this.clientNip89=e.clientNip89,this.relayAuthDefaultPolicy=e.relayAuthDefaultPolicy,e.enableOutboxModel!==!1&&(this.outboxPool=new NDKPool(e.outboxRelayUrls||DEFAULT_OUTBOX_RELAYS,this,{debug:this.debug.extend("outbox-pool"),name:"Outbox Pool"}),this.outboxTracker=new OutboxTracker(this),this.outboxTracker.on("user:relay-list-updated",(n,s)=>{this.debug(`Outbox relay list updated for ${n}`);for(const r of this.subManager.subscriptions.values())r.filters.some(a=>{var c;return(c=a.authors)==null?void 0:c.includes(n)})&&typeof r.refreshRelayConnections=="function"&&(this.debug(`Refreshing relay connections for subscription ${r.internalId}`),r.refreshRelayConnections())})),this.signer=e.signer,this.cacheAdapter=e.cacheAdapter,this.muteFilter=e.muteFilter,this.relayConnectionFilter=e.relayConnectionFilter,e.devWriteRelayUrls&&(this.devWriteRelaySet=NDKRelaySet.fromRelayUrls(e.devWriteRelayUrls,this)),this.queuesZapConfig=new Queue("zaps",3),this.queuesNip05=new Queue("nip05",10),e.signatureVerificationWorker&&(this.signatureVerificationWorker=e.signatureVerificationWorker),e.signatureVerificationFunction&&(this.signatureVerificationFunction=e.signatureVerificationFunction),this.initialValidationRatio=e.initialValidationRatio||1,this.lowestValidationRatio=e.lowestValidationRatio||.1,this.validationRatioFn=e.validationRatioFn||this.defaultValidationRatioFn,this.filterValidationMode=e.filterValidationMode||"validate",this.aiGuardrails=new AIGuardrails(e.aiGuardrails||!1),this.aiGuardrails.ndkInstantiated(this);try{this.httpFetch=fetch}catch{}}set explicitRelayUrls(e){this._explicitRelayUrls=e.map(normalizeRelayUrl),this.pool.relayUrls=e}get explicitRelayUrls(){return this._explicitRelayUrls||[]}set signatureVerificationWorker(e){this._signatureVerificationWorker=e,e?(signatureVerificationInit(e),this.asyncSigVerification=!0):this.asyncSigVerification=!1}set signatureVerificationFunction(e){this._signatureVerificationFunction=e,this.asyncSigVerification=!!e}get signatureVerificationFunction(){return this._signatureVerificationFunction}addExplicitRelay(e,n,s=!0){var o;let r;return typeof e=="string"?r=new NDKRelay(e,n,this):r=e,this.pool.addRelay(r,s),(o=this.explicitRelayUrls)==null||o.push(r.url),r}toJSON(){return{relayCount:this.pool.relays.size}.toString()}get activeUser(){return this._activeUser}set activeUser(e){var s;const n=((s=this._activeUser)==null?void 0:s.pubkey)!==(e==null?void 0:e.pubkey);this._activeUser=e,n&&this.emit("activeUser:change",e),e&&n&&setActiveUser.call(this,e)}get signer(){return this._signer}set signer(e){this._signer=e,e&&this.emit("signer:ready",e),e==null||e.user().then(n=>{n.ndk=this,this.activeUser=n})}async connect(e){var s,r,o;this._signer&&this.autoConnectUserRelays&&(this.debug("Attempting to connect to user relays specified by signer %o",await((r=(s=this._signer).relays)==null?void 0:r.call(s,this))),this._signer.relays&&(await this._signer.relays(this)).forEach(c=>this.pool.addRelay(c)));const n=[this.pool.connect(e)];return this.outboxPool&&n.push(this.outboxPool.connect(e)),(o=this.cacheAdapter)!=null&&o.initializeAsync&&n.push(this.cacheAdapter.initializeAsync(this)),Promise.allSettled(n).then(()=>{})}reportInvalidSignature(e,n){this.debug(`Invalid signature detected for event ${e.id}${n?` from relay ${n.url}`:""}`),this.emit("event:invalid-sig",e,n)}defaultValidationRatioFn(e,n,s){if(n<10)return this.initialValidationRatio;const r=Math.min(n/100,1),o=this.initialValidationRatio*(1-r)+this.lowestValidationRatio*r;return Math.max(o,this.lowestValidationRatio)}getUser(e){if(typeof e=="string")if(e.startsWith("npub1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="npub")throw new Error(`Invalid npub: ${e}`);return this.getUser({pubkey:r})}else if(e.startsWith("nprofile1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="nprofile")throw new Error(`Invalid nprofile: ${e}`);return this.getUser({pubkey:r.pubkey,relayUrls:r.relays})}else return this.getUser({pubkey:e});const n=new NDKUser(e);return n.ndk=this,n}async getUserFromNip05(e,n=!1){return NDKUser.fromNip05(e,this,n)}async fetchUser(e,n=!1){if(isValidNip05(e))return NDKUser.fromNip05(e,this,n);if(e.startsWith("npub1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="npub")throw new Error(`Invalid npub: ${e}`);const o=new NDKUser({pubkey:r});return o.ndk=this,o}else if(e.startsWith("nprofile1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="nprofile")throw new Error(`Invalid nprofile: ${e}`);const o=new NDKUser({pubkey:r.pubkey,relayUrls:r.relays});return o.ndk=this,o}else{const s=new NDKUser({pubkey:e});return s.ndk=this,s}}subscribe(e,n,s=!0,r=!0){var h,p,y;let o=n==null?void 0:n.relaySet,a=r;s instanceof NDKRelaySet?(console.warn("relaySet is deprecated, use opts.relaySet instead. This will be removed in version v2.14.0"),o=s,a=r):(typeof s=="boolean"||typeof s=="object")&&(a=s);let c;const l={relaySet:o,...n};a&&typeof a=="object"&&(a.onEvent&&(l.onEvent=a.onEvent),a.onEose&&(l.onEose=a.onEose),a.onClose&&(l.onClose=a.onClose),a.onEvents&&(c=a.onEvents));const u=new NDKSubscription(this,e,l);this.subManager.add(u),(p=(h=this.aiGuardrails)==null?void 0:h.subscription)==null||p.created(Array.isArray(e)?e:[e],l);const f=u.pool;if(u.relaySet)for(const b of u.relaySet.relays)f.useTemporaryRelay(b,void 0,u.filters);if(this.outboxPool&&u.hasAuthorsFilter()){const b=u.filters.filter(m=>{var w;return m.authors&&((w=m.authors)==null?void 0:w.length)>0}).flatMap(m=>m.authors);(y=this.outboxTracker)==null||y.trackUsers(b)}return a&&setTimeout(async()=>{var m;(m=this.cacheAdapter)!=null&&m.initializeAsync&&!this.cacheAdapter.ready&&await this.cacheAdapter.initializeAsync(this);const b=u.start(!c);b&&b.length>0&&c&&c(b)},0),u}fetchEventSync(e){if(!this.cacheAdapter)throw new Error("Cache adapter not set");let n;typeof e=="string"?n=[filterFromId(e)]:n=e;const s=new NDKSubscription(this,n),r=this.cacheAdapter.query(s);if(r instanceof Promise)throw new Error("Cache adapter is async");return r.map(o=>(o.ndk=this,o))}async fetchEvent(e,n,s){var a,c;let r,o;if(s instanceof NDKRelay?o=new NDKRelaySet(new Set([s]),this):s instanceof NDKRelaySet&&(o=s),!s&&typeof e=="string"&&!isNip33AValue(e)){const l=relaysFromBech32(e,this);l.length>0&&(o=new NDKRelaySet(new Set(l),this),o=correctRelaySet(o,this.pool))}if(typeof e=="string"?r=[filterFromId(e)]:Array.isArray(e)?r=e:r=[e],typeof e!="string"&&((c=(a=this.aiGuardrails)==null?void 0:a.ndk)==null||c.fetchingEvents(r)),r.length===0)throw new Error(`Invalid filter: ${JSON.stringify(e)}`);return new Promise((l,u)=>{let f=null;const h={...n||{},closeOnEose:!0};o&&(h.relaySet=o);const p=setTimeout(()=>{y.stop(),this.aiGuardrails._nextCallDisabled=null,l(f)},1e4),y=this.subscribe(r,h,{onEvent:b=>{b.ndk=this,b.isReplaceable()?(!f||f.created_at<b.created_at)&&(f=b):(clearTimeout(p),this.aiGuardrails._nextCallDisabled=null,l(b))},onEose:()=>{clearTimeout(p),this.aiGuardrails._nextCallDisabled=null,l(f)}})})}async fetchEvents(e,n,s){var r,o;return(o=(r=this.aiGuardrails)==null?void 0:r.ndk)==null||o.fetchingEvents(e,n),new Promise(a=>{const c=new Map,l={...n||{},closeOnEose:!0};s&&(l.relaySet=s);const u=f=>{let h;f instanceof NDKEvent?h=f:h=new NDKEvent(void 0,f);const p=h.deduplicationKey(),y=c.get(p);y&&(h=dedup(y,h)),h.ndk=this,c.set(p,h)};this.subscribe(e,{...l,onEvent:u,onEose:()=>{this.aiGuardrails._nextCallDisabled=null,a(new Set(c.values()))}})})}assertSigner(){if(!this.signer)throw this.emit("signer:required"),new Error("Signer required")}guardrailOff(e){return e?typeof e=="string"?this.aiGuardrails._nextCallDisabled=new Set([e]):this.aiGuardrails._nextCallDisabled=new Set(e):this.aiGuardrails._nextCallDisabled="all",this}set wallet(e){var n,s;if(!e){this._wallet=void 0,this.walletConfig=void 0;return}this._wallet=e,this.walletConfig??(this.walletConfig={}),this.walletConfig.lnPay=(n=e==null?void 0:e.lnPay)==null?void 0:n.bind(e),this.walletConfig.cashuPay=(s=e==null?void 0:e.cashuPay)==null?void 0:s.bind(e)}get wallet(){return this._wallet}},nip19_exports={};__reExport(nip19_exports,nip19_star);var nip49_exports={};__reExport(nip49_exports,nip49_star);function disconnect(t,e){return e??(e=createDebug5("ndk:relay:auth-policies:disconnect")),async n=>{e==null||e(`Relay ${n.url} requested authentication, disconnecting`),t.removeRelay(n.url)}}async function signAndAuth(t,e,n,s,r,o){try{await t.sign(n),r(t)}catch(a){s==null||s(`Failed to publish auth event to relay ${e.url}`,a),o(t)}}function signIn({ndk:t,signer:e,debug:n}={}){return n??(n=createDebug5("ndk:auth-policies:signIn")),async(s,r)=>{n==null||n(`Relay ${s.url} requested authentication, signing in`);const o=new NDKEvent(t);return o.kind=22242,o.tags=[["relay",s.url],["challenge",r]],e??(e=t==null?void 0:t.signer),new Promise(async(a,c)=>{e?await signAndAuth(o,s,e,n,a,c):t==null||t.once("signer:ready",async l=>{await signAndAuth(o,s,l,n,a,c)})})}}var NDKRelayAuthPolicies={disconnect,signIn};async function ndkSignerFromPayload(t,e){let n;try{n=JSON.parse(t)}catch(r){console.error("Failed to parse signer payload string",t,r);return}if(!n||typeof n.type!="string"){console.error("Failed to parse signer payload string",t,new Error("Missing type field"));return}const s=signerRegistry.get(n.type);if(!s)throw new Error(`Unknown signer type: ${n.type}`);try{return await s.fromPayload(t,e)}catch(r){const o=r instanceof Error?r.message:String(r);throw new Error(`Failed to deserialize signer type ${n.type}: ${o}`)}}var NDKNip07Signer=class ze{constructor(e=1e3,n){g(this,"_userPromise");g(this,"encryptionQueue",[]);g(this,"encryptionProcessing",!1);g(this,"debug");g(this,"waitTimeout");g(this,"_pubkey");g(this,"ndk");g(this,"_user");this.debug=createDebug5("ndk:nip07"),this.waitTimeout=e,this.ndk=n}get pubkey(){if(!this._pubkey)throw new Error("Not ready");return this._pubkey}async blockUntilReady(){var s;await this.waitForExtension();const e=await((s=window.nostr)==null?void 0:s.getPublicKey());if(!e)throw new Error("User rejected access");this._pubkey=e;let n;return this.ndk?n=this.ndk.getUser({pubkey:e}):n=new NDKUser({pubkey:e}),this._user=n,n}async user(){return this._userPromise||(this._userPromise=this.blockUntilReady()),this._userPromise}get userSync(){if(!this._user)throw new Error("User not ready");return this._user}async sign(e){var s;await this.waitForExtension();const n=await((s=window.nostr)==null?void 0:s.signEvent(e));if(!n)throw new Error("Failed to sign event");return n.sig}async relays(e){var r,o;await this.waitForExtension();const n=await((o=(r=window.nostr)==null?void 0:r.getRelays)==null?void 0:o.call(r))||{},s=[];for(const a of Object.keys(n))n[a].read&&n[a].write&&s.push(a);return s.map(a=>new NDKRelay(a,e==null?void 0:e.relayAuthDefaultPolicy,e))}async encryptionEnabled(e){var s,r;const n=[];return(!e||e==="nip04")&&((s=window.nostr)!=null&&s.nip04)&&n.push("nip04"),(!e||e==="nip44")&&((r=window.nostr)!=null&&r.nip44)&&n.push("nip44"),n}async encrypt(e,n,s="nip04"){if(!await this.encryptionEnabled(s))throw new Error(`${s}encryption is not available from your browser extension`);await this.waitForExtension();const r=e.pubkey;return this.queueEncryption(s,"encrypt",r,n)}async decrypt(e,n,s="nip04"){if(!await this.encryptionEnabled(s))throw new Error(`${s}encryption is not available from your browser extension`);await this.waitForExtension();const r=e.pubkey;return this.queueEncryption(s,"decrypt",r,n)}async queueEncryption(e,n,s,r){return new Promise((o,a)=>{this.encryptionQueue.push({scheme:e,method:n,counterpartyHexpubkey:s,value:r,resolve:o,reject:a}),this.encryptionProcessing||this.processEncryptionQueue()})}async processEncryptionQueue(e,n=0){var f,h;if(!e&&this.encryptionQueue.length===0){this.encryptionProcessing=!1;return}this.encryptionProcessing=!0;const s=e||this.encryptionQueue.shift();if(!s){this.encryptionProcessing=!1;return}const{scheme:r,method:o,counterpartyHexpubkey:a,value:c,resolve:l,reject:u}=s;this.debug("Processing encryption queue item",{method:o,counterpartyHexpubkey:a,value:c});try{const p=await((h=(f=window.nostr)==null?void 0:f[r])==null?void 0:h[o](a,c));if(!p)throw new Error("Failed to encrypt/decrypt");l(p)}catch(p){const y=p instanceof Error?p.message:String(p);if(y.includes("call already executing")&&n<5){this.debug("Retrying encryption queue item",{method:o,counterpartyHexpubkey:a,value:c,retries:n}),setTimeout(()=>{this.processEncryptionQueue(s,n+1)},50*n);return}u(p instanceof Error?p:new Error(y))}this.processEncryptionQueue()}waitForExtension(){return new Promise((e,n)=>{if(window.nostr){e();return}let s;const r=setInterval(()=>{window.nostr&&(clearTimeout(s),clearInterval(r),e())},100);s=setTimeout(()=>{clearInterval(r),n(new Error("NIP-07 extension not available"))},this.waitTimeout)})}toPayload(){return JSON.stringify({type:"nip07",payload:""})}static async fromPayload(e,n){const s=JSON.parse(e);if(s.type!=="nip07")throw new Error(`Invalid payload type: expected 'nip07', got ${s.type}`);return new ze(void 0,n)}};registerSigner("nip07",NDKNip07Signer);var NDKNostrRpc=class extends lib$1.EventEmitter{constructor(e,n,s,r){super();g(this,"ndk");g(this,"signer");g(this,"relaySet");g(this,"debug");g(this,"encryptionType","nip04");g(this,"pool");if(this.ndk=e,this.signer=n,r){this.pool=new NDKPool(r,e,{debug:s.extend("rpc-pool"),name:"Nostr RPC"}),this.relaySet=new NDKRelaySet(new Set,e,this.pool);for(const o of r){const a=this.pool.getRelay(o,!1,!1);a.authPolicy=NDKRelayAuthPolicies.signIn({ndk:e,signer:n,debug:s}),this.relaySet.addRelay(a),a.connect()}}this.debug=s.extend("rpc")}subscribe(e){return new Promise(n=>{const s=this.ndk.subscribe(e,{closeOnEose:!1,groupable:!1,cacheUsage:"ONLY_RELAY",pool:this.pool,relaySet:this.relaySet,onEvent:async r=>{try{const o=await this.parseEvent(r);o.method?this.emit("request",o):(this.emit(`response-${o.id}`,o),this.emit("response",o))}catch(o){this.debug("error parsing event",o,r.rawEvent())}},onEose:()=>{this.debug("eosed"),n(s)}})})}async parseEvent(e){this.encryptionType==="nip44"&&e.content.includes("?iv=")?this.encryptionType="nip04":this.encryptionType==="nip04"&&!e.content.includes("?iv=")&&(this.encryptionType="nip44");const n=this.ndk.getUser({pubkey:e.pubkey});n.ndk=this.ndk;let s;try{s=await this.signer.decrypt(n,e.content,this.encryptionType)}catch{const h=this.encryptionType==="nip04"?"nip44":"nip04";s=await this.signer.decrypt(n,e.content,h),this.encryptionType=h}const r=JSON.parse(s),{id:o,method:a,params:c,result:l,error:u}=r;return a?{id:o,pubkey:e.pubkey,method:a,params:c,event:e}:{id:o,result:l,error:u,event:e}}async sendResponse(e,n,s,r=24133,o){const a={id:e,result:s};o&&(a.error=o);const c=await this.signer.user(),l=this.ndk.getUser({pubkey:n}),u=new NDKEvent(this.ndk,{kind:r,content:JSON.stringify(a),tags:[["p",n]],pubkey:c.pubkey});u.content=await this.signer.encrypt(l,u.content,this.encryptionType),await u.sign(this.signer),await u.publish(this.relaySet)}async sendRequest(e,n,s=[],r=24133,o){const a=Math.random().toString(36).substring(7),c=await this.signer.user(),l=this.ndk.getUser({pubkey:e}),u={id:a,method:n,params:s},f=new Promise(()=>{const p=y=>{y.result==="auth_url"?(this.once(`response-${a}`,p),this.emit("authUrl",y.error)):o&&o(y)};this.once(`response-${a}`,p)}),h=new NDKEvent(this.ndk,{kind:r,content:JSON.stringify(u),tags:[["p",e]],pubkey:c.pubkey});return h.content=await this.signer.encrypt(l,h.content,this.encryptionType),await h.sign(this.signer),await h.publish(this.relaySet),f}};function nostrConnectGenerateSecret(){return Math.random().toString(36).substring(2,15)}function generateNostrConnectUri(t,e,n,s){const r={name:s!=null&&s.name?encodeURIComponent(s.name):"",url:s!=null&&s.url?encodeURIComponent(s.url):"",image:s!=null&&s.image?encodeURIComponent(s.image):"",perms:s!=null&&s.perms?encodeURIComponent(s.perms):""};let o=`nostrconnect://${t}?image=${r.image}&url=${r.url}&name=${r.name}&perms=${r.perms}&secret=${encodeURIComponent(e)}`;return n&&(o+=`&relay=${encodeURIComponent(n)}`),o}var NDKNip46Signer=class Me extends lib$1.EventEmitter{constructor(n,s,r,o,a){super();g(this,"ndk");g(this,"_user");g(this,"bunkerPubkey");g(this,"userPubkey");g(this,"secret");g(this,"localSigner");g(this,"nip05");g(this,"rpc");g(this,"debug");g(this,"relayUrls");g(this,"subscription");g(this,"nostrConnectUri");g(this,"nostrConnectSecret");this.ndk=n,this.debug=n.debug.extend("nip46:signer"),this.relayUrls=o,r?typeof r=="string"?this.localSigner=new NDKPrivateKeySigner(r):this.localSigner=r:this.localSigner=NDKPrivateKeySigner.generate(),s===!1||(s?s.startsWith("bunker://")?this.bunkerFlowInit(s):this.nip05Init(s):this.nostrconnectFlowInit(a)),this.rpc=new NDKNostrRpc(this.ndk,this.localSigner,this.debug,this.relayUrls)}get pubkey(){if(!this.userPubkey)throw new Error("Not ready");return this.userPubkey}static bunker(n,s,r){return new Me(n,s,r)}static nostrconnect(n,s,r,o){return new Me(n,void 0,r,[s],o)}nostrconnectFlowInit(n){var r;this.nostrConnectSecret=nostrConnectGenerateSecret();const s=this.localSigner.pubkey;this.nostrConnectUri=generateNostrConnectUri(s,this.nostrConnectSecret,(r=this.relayUrls)==null?void 0:r[0],n)}bunkerFlowInit(n){const s=new URL(n),r=s.hostname||s.pathname.replace(/^\/\//,""),o=s.searchParams.get("pubkey"),a=s.searchParams.getAll("relay"),c=s.searchParams.get("secret");this.bunkerPubkey=r,this.userPubkey=o,this.relayUrls=a,this.secret=c}nip05Init(n){this.nip05=n}async startListening(){if(this.subscription)return;const n=await this.localSigner.user();if(!n)throw new Error("Local signer not ready");this.subscription=await this.rpc.subscribe({kinds:[24133],"#p":[n.pubkey]})}async user(){return this._user?this._user:this.blockUntilReady()}get userSync(){if(!this._user)throw new Error("Remote user not ready synchronously");return this._user}async blockUntilReadyNostrConnect(){return new Promise((n,s)=>{const r=o=>{o.result===this.nostrConnectSecret&&(this._user=o.event.author,this.userPubkey=o.event.pubkey,this.bunkerPubkey=o.event.pubkey,this.rpc.off("response",r),n(this._user))};this.startListening(),this.rpc.on("response",r)})}async blockUntilReady(){if(!this.bunkerPubkey&&!this.nostrConnectSecret&&!this.nip05)throw new Error("Bunker pubkey not set");if(this.nostrConnectSecret)return this.blockUntilReadyNostrConnect();if(this.nip05&&!this.userPubkey){const n=await NDKUser.fromNip05(this.nip05,this.ndk);n&&(this._user=n,this.userPubkey=n.pubkey,this.relayUrls=n.nip46Urls,this.rpc=new NDKNostrRpc(this.ndk,this.localSigner,this.debug,this.relayUrls))}if(!this.bunkerPubkey&&this.userPubkey)this.bunkerPubkey=this.userPubkey;else if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");return await this.startListening(),this.rpc.on("authUrl",(...n)=>{this.emit("authUrl",...n)}),new Promise((n,s)=>{const r=[this.userPubkey??""];if(this.secret&&r.push(this.secret),!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"connect",r,24133,o=>{o.result==="ack"?this.getPublicKey().then(a=>{this.userPubkey=a,this._user=this.ndk.getUser({pubkey:a}),n(this._user)}):s(o.error)})})}stop(){var n;(n=this.subscription)==null||n.stop(),this.subscription=void 0}async getPublicKey(){return this.userPubkey?this.userPubkey:new Promise((n,s)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"get_public_key",[],24133,r=>{n(r.result)})})}async encryptionEnabled(n){return n?[n]:Promise.resolve(["nip04","nip44"])}async encrypt(n,s,r="nip04"){return this.encryption(n,s,r,"encrypt")}async decrypt(n,s,r="nip04"){return this.encryption(n,s,r,"decrypt")}async encryption(n,s,r,o){return new Promise((c,l)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,`${r}_${o}`,[n.pubkey,s],24133,u=>{u.error?l(u.error):c(u.result)})})}async sign(n){return new Promise((r,o)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"sign_event",[JSON.stringify(n)],24133,a=>{if(a.error)o(a.error);else{const c=JSON.parse(a.result);r(c.sig)}})})}async createAccount(n,s,r){await this.startListening();const o=[];return n&&o.push(n),s&&o.push(s),r&&o.push(r),new Promise((a,c)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"create_account",o,24133,l=>{if(l.error)c(l.error);else{const u=l.result;a(u)}})})}toPayload(){if(!this.bunkerPubkey||!this.userPubkey)throw new Error("NIP-46 signer is not fully initialized for serialization");const n={type:"nip46",payload:{bunkerPubkey:this.bunkerPubkey,userPubkey:this.userPubkey,relayUrls:this.relayUrls,secret:this.secret,localSignerPayload:this.localSigner.toPayload(),nip05:this.nip05||null}};return JSON.stringify(n)}static async fromPayload(n,s){if(!s)throw new Error("NDK instance is required to deserialize NIP-46 signer");const r=JSON.parse(n);if(r.type!=="nip46")throw new Error(`Invalid payload type: expected 'nip46', got ${r.type}`);const o=r.payload;if(!o||typeof o!="object"||!o.localSignerPayload)throw new Error("Invalid payload content for nip46 signer");const a=await ndkSignerFromPayload(o.localSignerPayload,s);if(!a)throw new Error("Failed to deserialize local signer for NIP-46");if(!(a instanceof NDKPrivateKeySigner))throw new Error("Local signer must be an instance of NDKPrivateKeySigner");let c;return c=new Me(s,!1,a,o.relayUrls),c.userPubkey=o.userPubkey,c.bunkerPubkey=o.bunkerPubkey,c.relayUrls=o.relayUrls,c.secret=o.secret,o.userPubkey&&(c._user=new NDKUser({pubkey:o.userPubkey}),c._user&&(c._user.ndk=s)),c}};registerSigner("nip46",NDKNip46Signer);createDebug5("ndk:zapper:ln");createDebug5("ndk:zapper");const index=Object.freeze(Object.defineProperty({__proto__:null,BECH32_REGEX,NDKAppHandlerEvent,NDKArticle,NDKBlossomList,NDKCashuMintAnnouncement,NDKCashuMintList,NDKClassified,NDKDVMJobFeedback,NDKDraft,NDKEvent,NDKFedimintMint,NDKFollowPack,NDKHighlight,NDKImage,NDKKind,NDKList,NDKMintRecommendation,NDKNip07Signer,NDKNip46Signer,NDKNostrRpc,NDKNutzap,NDKPool,NDKPrivateKeySigner,NDKProject,NDKProjectTemplate,NDKPublishError,NDKRelay,NDKRelayAuthPolicies,NDKRelayList,NDKRelaySet,NDKRepost,NDKSimpleGroupMemberList,NDKSimpleGroupMetadata,NDKStory,NDKStorySticker,NDKSubscription,NDKSubscriptionReceipt,NDKSubscriptionStart,NDKSubscriptionTier,NDKTask,NDKThread,NDKUser,NDKVideo,NDKWiki,NDKWikiMergeRequest,NIP33_A_REGEX,calculateRelaySetFromEvent,default:NDK,defaultOpts,deserialize,eventHasETagMarkers,fetchRelayInformation,filterFingerprint,filterFromId,generateContentTags,generateHashtags,getRelayListForUser,getRelayListForUsers,getReplyTag,getRootTag,imetaTagToTag,isNip33AValue,isValidHex64,isValidNip05,isValidPubkey,mapImetaTag,mergeFilters,mergeTags,ndkSignerFromPayload,newAmount,nip19:nip19_exports,nip49:nip49_exports,normalize,normalizeRelayUrl,normalizeUrl,parseTagToSubscriptionAmount,possibleIntervalFrequencies,processFilters,profileFromEvent,queryFullyFilled,registerSigner,relayListFromKind3,relaysFromBech32,serialize,serializeProfile,strToDimension,strToPosition,tryNormalizeRelayUrl,wrapEvent},Symbol.toStringTag,{value:"Module"})),DEFAULT_RELAYS=["wss://relay.damus.io","wss://nostr.wine","wss://relay.nostr.net","wss://relay.nostr.band","wss://nos.lol","wss://nostr-pub.wellorder.net","wss://relay.getalby.com","wss://relay.primal.net"],MILLISATS_PER_SAT=1e3,DEFAULT_PROFILE_IMAGE="./assets/default_dp.png",xe=class xe{constructor(){g(this,"ndk");g(this,"isConnected",!1);this.ndk=new NDK}static getInstance(){return xe.instance||(xe.instance=new xe),xe.instance}async connectToNostr(e=[...DEFAULT_RELAYS]){const n=e.filter(s=>!this.getRelays().includes(s));if(this.isConnected&&n.length){n.forEach(s=>this.ndk.addExplicitRelay(s));return}this.ndk.explicitRelayUrls=e,await this.ndk.connect(),this.isConnected=!0}getRelays(){return this.ndk.explicitRelayUrls||DEFAULT_RELAYS}async resolveNDKUser(e){return e.npub?this.ndk.getUser({npub:e.npub}):e.nip05?await this.ndk.getUserFromNip05(e.nip05)??null:e.pubkey?this.ndk.getUser({pubkey:e.pubkey}):null}async resolveNDKEvent(e){return e.hex?this.ndk.fetchEvent(e.hex):null}async getZapCount(e){const n=await this.resolveNDKUser(e);return n?this.fetchZaps(n):0}async getProfile(e){if(!e)return null;await e.fetchProfile();const n=e.profile;return n&&(n.picture===void 0||n.picture===null)&&(n.picture=DEFAULT_PROFILE_IMAGE),n}async getPost(e){const n=await this.ndk.fetchEvent(e);if(!n)return null;const s=n.getMatchingTags("e");if(s.length>0){const o=s.map(a=>a[1]);await this.ndk.fetchEvents({ids:o})}const r=n.getMatchingTags("a");for(const o of r){const a=o[1],c=o[2];a!=null&&a.startsWith("video/")&&c&&(n.content=n.content+`
265
- ${c}`)}return n}async fetchFollows(e){try{return(await e.followSet()).size}catch{return 0}}async fetchFollowers(e){try{const n=await this.ndk.fetchEvents({kinds:[NDKKind.Contacts],"#p":[e.pubkey]}),s=new Set;return n.forEach(o=>s.add(o.pubkey)),s.size}catch{return 0}}async fetchNotesAndReplies(e){try{const n=await this.ndk.fetchEvents({kinds:[NDKKind.Text],authors:[e.pubkey],limit:1e3});let s=0,r=0;n.forEach(c=>{c&&(c.tags.some(u=>u[0]==="e"&&u[3]!=="mention")&&s++,r++)});const o=s;return[Math.max(0,r-s),o]}catch{return[0,0]}}async fetchZaps(e){try{return(await this.ndk.fetchEvents({kinds:[9735],"#p":[e.pubkey],limit:1e3})).size}catch{return 0}}getNDK(){return this.ndk}hasSigner(){return typeof window<"u"&&window.nostr||typeof window<"u"&&typeof localStorage<"u"&&localStorage.getItem("nostr_nsec")?!0:!!this.ndk.signer}};g(xe,"instance");let NostrService=xe;export{DEFAULT_RELAYS as D,MILLISATS_PER_SAT as M,NostrService as N,SimplePool as S,sha256$2 as a,bytesToHex$2 as b,nip19_exports$1 as c,NDKNip07Signer as d,NDKEvent as e,finalizeEvent as f,NDKKind as g,DEFAULT_PROFILE_IMAGE as h,nip21_exports as i,index$1 as j,index as k,nip57_exports as n,schnorr$1 as s};
266
- //# sourceMappingURL=nostr-service-m3Hgc5Xx.js.map
264
+ ❌ { "#t": ["#nostr"] }`,!1)})}}function queryFullyFilled(t){return!!(filterIncludesIds(t.filter)&&resultHasAllRequestedIds(t))}function filterIncludesIds(t){return!!t.ids}function resultHasAllRequestedIds(t){const e=t.filter.ids;return!!e&&e.length===t.eventFirstSeen.size}function filterFromId(t){let e;if(t.match(NIP33_A_REGEX)){const[n,s,r]=t.split(":"),o={authors:[s],kinds:[Number.parseInt(n)]};return r&&(o["#d"]=[r]),o}if(t.match(BECH32_REGEX))try{switch(e=nip19_exports$1.decode(t),e.type){case"nevent":{const n={ids:[e.data.id]};return e.data.author&&(n.authors=[e.data.author]),e.data.kind&&(n.kinds=[e.data.kind]),n}case"note":return{ids:[e.data]};case"naddr":{const n={authors:[e.data.pubkey],kinds:[e.data.kind]};return e.data.identifier&&(n["#d"]=[e.data.identifier]),n}}}catch(n){console.error("Error decoding",t,n)}return{ids:[t]}}function isNip33AValue(t){return t.match(NIP33_A_REGEX)!==null}var NIP33_A_REGEX=/^(\d+):([0-9A-Fa-f]+)(?::(.*))?$/,BECH32_REGEX=/^n(event|ote|profile|pub|addr)1[\d\w]+$/;function relaysFromBech32(t,e){try{const n=nip19_exports$1.decode(t);if(["naddr","nevent"].includes(n==null?void 0:n.type)){const s=n.data;if(s!=null&&s.relays)return s.relays.map(r=>new NDKRelay(r,e.relayAuthDefaultPolicy,e))}}catch{}return[]}var defaultOpts={closeOnEose:!1,cacheUsage:"CACHE_FIRST",dontSaveToCache:!1,groupable:!0,groupableDelay:100,groupableDelayType:"at-most",cacheUnconstrainFilter:["limit","since","until"],includeMuted:!1},NDKSubscription=class extends lib$1.EventEmitter{constructor(e,n,s,r){super();g(this,"subId");g(this,"filters");g(this,"opts");g(this,"pool");g(this,"skipVerification",!1);g(this,"skipValidation",!1);g(this,"exclusiveRelay",!1);g(this,"relayFilters");g(this,"relaySet");g(this,"ndk");g(this,"debug");g(this,"eventFirstSeen",new Map);g(this,"eosesSeen",new Set);g(this,"lastEventReceivedAt");g(this,"mostRecentCacheEventTimestamp");g(this,"internalId");g(this,"closeOnEose");g(this,"poolMonitor");g(this,"skipOptimisticPublishEvent",!1);g(this,"cacheUnconstrainFilter");g(this,"onStopped");g(this,"eoseTimeout");g(this,"eosed",!1);this.ndk=e,this.opts={...defaultOpts,...s||{}},this.pool=this.opts.pool||e.pool;const o=Array.isArray(n)?n:[n],a=e.filterValidationMode==="validate"?"validate":e.filterValidationMode==="fix"?"fix":"ignore";if(this.filters=processFilters(o,a,e.debug,e),this.filters.length===0)throw new Error("Subscription must have at least one filter");this.subId=r||this.opts.subId,this.internalId=Math.random().toString(36).substring(7),this.debug=e.debug.extend(`subscription[${this.opts.subId??this.internalId}]`),this.opts.relaySet?this.relaySet=this.opts.relaySet:this.opts.relayUrls&&(this.relaySet=NDKRelaySet.fromRelayUrls(this.opts.relayUrls,this.ndk)),this.skipVerification=this.opts.skipVerification||!1,this.skipValidation=this.opts.skipValidation||!1,this.closeOnEose=this.opts.closeOnEose||!1,this.skipOptimisticPublishEvent=this.opts.skipOptimisticPublishEvent||!1,this.cacheUnconstrainFilter=this.opts.cacheUnconstrainFilter,this.exclusiveRelay=this.opts.exclusiveRelay||!1,this.opts.onEvent&&this.on("event",this.opts.onEvent),this.opts.onEose&&this.on("eose",this.opts.onEose),this.opts.onClose&&this.on("close",this.opts.onClose)}relaysMissingEose(){var n;return this.relayFilters?Array.from((n=this.relayFilters)==null?void 0:n.keys()).filter(s=>!this.eosesSeen.has(this.pool.getRelay(s,!1,!1))):[]}get filter(){return this.filters[0]}get groupableDelay(){var e;if(this.isGroupable())return(e=this.opts)==null?void 0:e.groupableDelay}get groupableDelayType(){var e;return((e=this.opts)==null?void 0:e.groupableDelayType)||"at-most"}isGroupable(){var e;return((e=this.opts)==null?void 0:e.groupable)||!1}shouldQueryCache(){var n;return this.opts.addSinceFromCache?!0:((n=this.opts)==null?void 0:n.cacheUsage)==="ONLY_RELAY"?!1:(this.filters.some(s=>{var r;return(r=s.kinds)==null?void 0:r.some(o=>kindIsEphemeral(o))}),!0)}shouldQueryRelays(){var e;return((e=this.opts)==null?void 0:e.cacheUsage)!=="ONLY_CACHE"}shouldWaitForCache(){var e;return this.opts.addSinceFromCache?!0:!!this.opts.closeOnEose&&!!((e=this.ndk.cacheAdapter)!=null&&e.locking)&&this.opts.cacheUsage!=="PARALLEL"}start(e=!0){let n;const s=o=>{for(const a of o)a.created_at&&(!this.mostRecentCacheEventTimestamp||a.created_at>this.mostRecentCacheEventTimestamp)&&(this.mostRecentCacheEventTimestamp=a.created_at),this.eventReceived(a,void 0,!0,!1);e||(n=o)},r=()=>{this.shouldQueryRelays()?(this.startWithRelays(),this.startPoolMonitor()):this.emit("eose",this)};return this.shouldQueryCache()?(n=this.startWithCache(),n instanceof Promise?this.shouldWaitForCache()?(n.then(o=>{if(s(o),queryFullyFilled(this)){this.emit("eose",this);return}r()}),null):(n.then(o=>{s(o),this.shouldQueryRelays()||this.emit("eose",this)}),this.shouldQueryRelays()&&r(),null):(s(n),queryFullyFilled(this)?this.emit("eose",this):r(),n)):(r(),null)}startPoolMonitor(){this.debug.extend("pool-monitor"),this.poolMonitor=e=>{var s,r;if((s=this.relayFilters)!=null&&s.has(e.url))return;calculateRelaySetsFromFilters(this.ndk,this.filters,this.pool,this.opts.relayGoalPerAuthor).get(e.url)&&((r=this.relayFilters)==null||r.set(e.url,this.filters),e.subscribe(this,this.filters))},this.pool.on("relay:connect",this.poolMonitor)}stop(){var e;this.emit("close",this),this.poolMonitor&&this.pool.off("relay:connect",this.poolMonitor),(e=this.onStopped)==null||e.call(this)}hasAuthorsFilter(){return this.filters.some(e=>{var n;return(n=e.authors)==null?void 0:n.length})}startWithCache(){var e;return(e=this.ndk.cacheAdapter)!=null&&e.query?this.ndk.cacheAdapter.query(this):[]}startWithRelays(){let e=this.filters;if(this.opts.addSinceFromCache&&this.mostRecentCacheEventTimestamp){const n=this.mostRecentCacheEventTimestamp+1;e=e.map(s=>({...s,since:Math.max(s.since||0,n)}))}if(!this.relaySet||this.relaySet.relays.size===0)this.relayFilters=calculateRelaySetsFromFilters(this.ndk,e,this.pool,this.opts.relayGoalPerAuthor);else{this.relayFilters=new Map;for(const n of this.relaySet.relays)this.relayFilters.set(n.url,e)}for(const[n,s]of this.relayFilters)this.pool.getRelay(n,!0,!0,s).subscribe(this,s)}refreshRelayConnections(){var n,s;if(this.relaySet&&this.relaySet.relays.size>0)return;const e=calculateRelaySetsFromFilters(this.ndk,this.filters,this.pool,this.opts.relayGoalPerAuthor);for(const[r,o]of e)(n=this.relayFilters)!=null&&n.has(r)||((s=this.relayFilters)==null||s.set(r,o),this.pool.getRelay(r,!0,!0,o).subscribe(this,o))}eventReceived(e,n,s=!1,r=!1){var l,u,f;const o=e.id,a=this.eventFirstSeen.has(o);let c;if(e instanceof NDKEvent&&(c=e),a){const h=Date.now()-(this.eventFirstSeen.get(o)||0);if(this.emit("event:dup",e,n,h,this,s,r),(u=this.opts)!=null&&u.onEventDup&&this.opts.onEventDup(e,n,h,this,s,r),!s&&!r&&n&&((f=this.ndk.cacheAdapter)!=null&&f.setEventDup)&&!this.opts.dontSaveToCache&&(c??(c=e instanceof NDKEvent?e:new NDKEvent(this.ndk,e)),this.ndk.cacheAdapter.setEventDup(c,n)),n){const p=verifiedSignatures.get(o);if(p&&typeof p=="string")if(e.sig===p)n.addValidatedEvent();else{const y=e instanceof NDKEvent?e:new NDKEvent(this.ndk,e);this.ndk.reportInvalidSignature(y,n)}}}else{if(c??(c=new NDKEvent(this.ndk,e)),c.ndk=this.ndk,c.relay=n,!s&&!r){if(!this.skipValidation&&!c.isValid){this.debug("Event failed validation %s from relay %s",o,n==null?void 0:n.url);return}if(n)if(n.shouldValidateEvent()&&!this.skipVerification)if(c.relay=n,this.ndk.asyncSigVerification)c.verifySignature(!0);else{if(!c.verifySignature(!0)){this.debug("Event failed signature validation",e),this.ndk.reportInvalidSignature(c,n);return}n.addValidatedEvent()}else n.addNonValidatedEvent();this.ndk.cacheAdapter&&!this.opts.dontSaveToCache&&this.ndk.cacheAdapter.setEvent(c,this.filters,n)}if(!this.opts.includeMuted&&this.ndk.muteFilter&&this.ndk.muteFilter(c)){this.debug("Event muted, skipping");return}(!r||this.skipOptimisticPublishEvent!==!0)&&(this.emitEvent(((l=this.opts)==null?void 0:l.wrap)??!1,c,n,s,r),this.eventFirstSeen.set(o,Date.now()))}this.lastEventReceivedAt=Date.now()}emitEvent(e,n,s,r,o){const a=e?wrapEvent(n):n;a instanceof Promise?a.then(c=>this.emitEvent(!1,c,s,r,o)):a&&this.emit("event",a,s,this,r,o)}closedReceived(e,n){this.emit("closed",e,n)}eoseReceived(e){var a;this.debug("EOSE received from %s",e.url),this.eosesSeen.add(e);let n=this.lastEventReceivedAt?Date.now()-this.lastEventReceivedAt:void 0;const s=this.eosesSeen.size===((a=this.relayFilters)==null?void 0:a.size),r=queryFullyFilled(this),o=c=>{var l;this.debug("Performing EOSE: %s %d",c,this.eosed),!this.eosed&&(this.eoseTimeout&&clearTimeout(this.eoseTimeout),this.emit("eose",this),this.eosed=!0,(l=this.opts)!=null&&l.closeOnEose&&this.stop())};if(r||s)o("query filled or seen all");else if(this.relayFilters){let c=1e3;const l=new Set(this.pool.connectedRelays().map(h=>h.url)),u=Array.from(this.relayFilters.keys()).filter(h=>l.has(h));if(u.length===0){this.debug("No connected relays, waiting for all relays to connect",Array.from(this.relayFilters.keys()).join(", "));return}const f=this.eosesSeen.size/u.length;if(this.debug("Percentage of relays that have sent EOSE",{subId:this.subId,percentageOfRelaysThatHaveSentEose:f,seen:this.eosesSeen.size,total:u.length}),this.eosesSeen.size>=2&&f>=.5){if(c=c*(1-f),c===0){o("time to wait was 0");return}this.eoseTimeout&&clearTimeout(this.eoseTimeout);const h=()=>{n=this.lastEventReceivedAt?Date.now()-this.lastEventReceivedAt:void 0,n!==void 0&&n<20?this.eoseTimeout=setTimeout(h,c):o(`send eose timeout: ${c}`)};this.eoseTimeout=setTimeout(h,c)}}}},kindIsEphemeral=t=>t>=2e4&&t<3e4;async function follows(t,e,n=3){var r,o;if(!this.ndk)throw new Error("NDK not set");const s=await this.ndk.fetchEvent({kinds:[n],authors:[this.pubkey]},t||{groupable:!1});if(s){const a=new Set;return s.tags.forEach(c=>{c[0]==="p"&&c[1]&&isValidPubkey(c[1])&&a.add(c[1])}),e&&((o=(r=this.ndk)==null?void 0:r.outboxTracker)==null||o.trackUsers(Array.from(a))),[...a].reduce((c,l)=>{const u=new NDKUser({pubkey:l});return u.ndk=this.ndk,c.add(u),c},new Set)}return new Set}var NIP05_REGEX=/^(?:([\w.+-]+)@)?([\w.-]+)$/;async function getNip05For(t,e,n=fetch,s={}){return await t.queuesNip05.add({id:e,func:async()=>{var l,u,f;if((l=t.cacheAdapter)!=null&&l.loadNip05){const h=await t.cacheAdapter.loadNip05(e);if(h!=="missing"){if(h){const p=new NDKUser({pubkey:h.pubkey,relayUrls:h.relays,nip46Urls:h.nip46});return p.ndk=t,p}if(s.cache!=="no-cache")return null}}const r=e.match(NIP05_REGEX);if(!r)return null;const[o,a="_",c]=r;try{const h=await n(`https://${c}/.well-known/nostr.json?name=${a}`,s),{names:p,relays:y,nip46:b}=parseNIP05Result(await h.json()),m=p[a.toLowerCase()];let w=null;return m&&(w={pubkey:m,relays:y==null?void 0:y[m],nip46:b==null?void 0:b[m]}),(u=t==null?void 0:t.cacheAdapter)!=null&&u.saveNip05&&t.cacheAdapter.saveNip05(e,w),w}catch(h){return(f=t==null?void 0:t.cacheAdapter)!=null&&f.saveNip05&&(t==null||t.cacheAdapter.saveNip05(e,null)),console.error("Failed to fetch NIP05 for",e,h),null}}})}function parseNIP05Result(t){const e={names:{}};for(const[n,s]of Object.entries(t.names))typeof n=="string"&&typeof s=="string"&&(e.names[n.toLowerCase()]=s);if(t.relays){e.relays={};for(const[n,s]of Object.entries(t.relays))typeof n=="string"&&Array.isArray(s)&&(e.relays[n]=s.filter(r=>typeof r=="string"))}if(t.nip46){e.nip46={};for(const[n,s]of Object.entries(t.nip46))typeof n=="string"&&Array.isArray(s)&&(e.nip46[n]=s.filter(r=>typeof r=="string"))}return e}function profileFromEvent(t){const e={};let n;try{n=JSON.parse(t.content)}catch(s){throw new Error(`Failed to parse profile event: ${s}`)}e.profileEvent=JSON.stringify(t.rawEvent());for(const s of Object.keys(n))switch(s){case"name":e.name=n.name;break;case"display_name":e.displayName=n.display_name;break;case"image":case"picture":e.picture=n.picture||n.image,e.image=e.picture;break;case"banner":e.banner=n.banner;break;case"bio":e.bio=n.bio;break;case"nip05":e.nip05=n.nip05;break;case"lud06":e.lud06=n.lud06;break;case"lud16":e.lud16=n.lud16;break;case"about":e.about=n.about;break;case"website":e.website=n.website;break;default:e[s]=n[s];break}return e.created_at=t.created_at,e}function serializeProfile(t){const e={};for(const[n,s]of Object.entries(t))switch(n){case"username":case"name":e.name=s;break;case"displayName":e.display_name=s;break;case"image":case"picture":e.picture=s;break;case"bio":case"about":e.about=s;break;default:e[n]=s;break}return JSON.stringify(e)}var NDKUser=class Ve{constructor(e){g(this,"ndk");g(this,"profile");g(this,"profileEvent");g(this,"_npub");g(this,"_pubkey");g(this,"relayUrls",[]);g(this,"nip46Urls",[]);g(this,"follows",follows.bind(this));if(e.npub&&(this._npub=e.npub),e.hexpubkey&&(this._pubkey=e.hexpubkey),e.pubkey&&(this._pubkey=e.pubkey),e.relayUrls&&(this.relayUrls=e.relayUrls),e.nip46Urls&&(this.nip46Urls=e.nip46Urls),e.nprofile)try{const n=nip19_exports$1.decode(e.nprofile);n.type==="nprofile"&&(this._pubkey=n.data.pubkey,n.data.relays&&n.data.relays.length>0&&this.relayUrls.push(...n.data.relays))}catch(n){console.error("Failed to decode nprofile",n)}}get npub(){if(!this._npub){if(!this._pubkey)throw new Error("pubkey not set");this._npub=nip19_exports$1.npubEncode(this.pubkey)}return this._npub}get nprofile(){var n,s;const e=(s=(n=this.profileEvent)==null?void 0:n.onRelays)==null?void 0:s.map(r=>r.url);return nip19_exports$1.nprofileEncode({pubkey:this.pubkey,relays:e})}set npub(e){this._npub=e}get pubkey(){if(!this._pubkey){if(!this._npub)throw new Error("npub not set");this._pubkey=nip19_exports$1.decode(this.npub).data}return this._pubkey}set pubkey(e){this._pubkey=e}filter(){return{"#p":[this.pubkey]}}async getZapInfo(e){if(!this.ndk)throw new Error("No NDK instance found");const n=async a=>{if(!e)return a;let c;const l=new Promise((u,f)=>{c=setTimeout(()=>f(new Error("Timeout")),e)});try{const u=await Promise.race([a,l]);return c&&clearTimeout(c),u}catch(u){if(u instanceof Error&&u.message==="Timeout")try{return await a}catch{return}return}},[s,r]=await Promise.all([n(this.fetchProfile()),n(this.ndk.fetchEvent({kinds:[10019],authors:[this.pubkey]}))]),o=new Map;if(r){const a=NDKCashuMintList.from(r);a.mints.length>0&&o.set("nip61",{mints:a.mints,relays:a.relays,p2pk:a.p2pk})}if(s){const{lud06:a,lud16:c}=s;o.set("nip57",{lud06:a,lud16:c})}return o}static async fromNip05(e,n,s=!1){if(!n)throw new Error("No NDK instance found");const r={};s&&(r.cache="no-cache");const o=await getNip05For(n,e,n==null?void 0:n.httpFetch,r);if(o){const a=new Ve({pubkey:o.pubkey,relayUrls:o.relays,nip46Urls:o.nip46});return a.ndk=n,a}}async fetchProfile(e,n=!1){if(!this.ndk)throw new Error("NDK not set");let s=null;if(this.ndk.cacheAdapter&&(this.ndk.cacheAdapter.fetchProfile||this.ndk.cacheAdapter.fetchProfileSync)&&(e==null?void 0:e.cacheUsage)!=="ONLY_RELAY"){let r=null;if(this.ndk.cacheAdapter.fetchProfileSync?r=this.ndk.cacheAdapter.fetchProfileSync(this.pubkey):this.ndk.cacheAdapter.fetchProfile&&(r=await this.ndk.cacheAdapter.fetchProfile(this.pubkey)),r)return this.profile=r,r}return e??(e={}),e.cacheUsage??(e.cacheUsage="ONLY_RELAY"),e.closeOnEose??(e.closeOnEose=!0),e.groupable??(e.groupable=!0),e.groupableDelay??(e.groupableDelay=250),s||(s=await this.ndk.fetchEvent({kinds:[0],authors:[this.pubkey]},e)),s?(this.profile=profileFromEvent(s),n&&this.profile&&this.ndk.cacheAdapter&&this.ndk.cacheAdapter.saveProfile&&this.ndk.cacheAdapter.saveProfile(this.pubkey,this.profile),this.profile):null}async followSet(e,n,s=3){const r=await this.follows(e,n,s);return new Set(Array.from(r).map(o=>o.pubkey))}tagReference(){return["p",this.pubkey]}referenceTags(e){const n=[["p",this.pubkey]];return e&&n[0].push("",e),n}async publish(){if(!this.ndk)throw new Error("No NDK instance found");if(!this.profile)throw new Error("No profile available");this.ndk.assertSigner(),await new NDKEvent(this.ndk,{kind:0,content:serializeProfile(this.profile)}).publish()}async follow(e,n,s=3){if(!this.ndk)throw new Error("No NDK instance found");this.ndk.assertSigner(),n||(n=await this.follows(void 0,void 0,s));const r=typeof e=="string"?e:e.pubkey;if(Array.from(n).some(c=>typeof c=="string"?c===r:c.pubkey===r))return!1;n.add(e);const a=new NDKEvent(this.ndk,{kind:s});for(const c of n)typeof c=="string"?a.tags.push(["p",c]):a.tag(c);return await a.publish(),!0}async unfollow(e,n,s=3){if(!this.ndk)throw new Error("No NDK instance found");this.ndk.assertSigner(),n||(n=await this.follows(void 0,void 0,s));const r=typeof e=="string"?e:e.pubkey,o=new Set;let a=!1;for(const l of n)(typeof l=="string"?l:l.pubkey)!==r?o.add(l):a=!0;if(!a)return!1;const c=new NDKEvent(this.ndk,{kind:s});for(const l of o)typeof l=="string"?c.tags.push(["p",l]):c.tag(l);return await c.publish()}async validateNip05(e){if(!this.ndk)throw new Error("No NDK instance found");const n=await getNip05For(this.ndk,e);return n===null?null:n.pubkey===this.pubkey}},signerRegistry=new Map;function registerSigner(t,e){signerRegistry.set(t,e)}var NDKPrivateKeySigner=class Fe{constructor(e,n){g(this,"_user");g(this,"_privateKey");g(this,"_pubkey");if(typeof e=="string")if(e.startsWith("nsec1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s==="nsec")this._privateKey=r;else throw new Error("Invalid private key provided.")}else if(e.length===64)this._privateKey=hexToBytes(e);else throw new Error("Invalid private key provided.");else this._privateKey=e;this._pubkey=getPublicKey(this._privateKey),n&&(this._user=n.getUser({pubkey:this._pubkey})),this._user??(this._user=new NDKUser({pubkey:this._pubkey}))}get privateKey(){if(!this._privateKey)throw new Error("Not ready");return bytesToHex(this._privateKey)}get pubkey(){if(!this._pubkey)throw new Error("Not ready");return this._pubkey}get nsec(){if(!this._privateKey)throw new Error("Not ready");return nip19_exports$1.nsecEncode(this._privateKey)}get npub(){if(!this._pubkey)throw new Error("Not ready");return nip19_exports$1.npubEncode(this._pubkey)}encryptToNcryptsec(e,n=16,s=2){if(!this._privateKey)throw new Error("Private key not available");return encrypt$1(this._privateKey,e,n,s)}static generate(){const e=generateSecretKey();return new Fe(e)}static fromNcryptsec(e,n,s){const r=decrypt$1(e,n);return new Fe(r,s)}async blockUntilReady(){return this._user}async user(){return this._user}get userSync(){return this._user}async sign(e){if(!this._privateKey)throw Error("Attempted to sign without a private key");return finalizeEvent(e,this._privateKey).sig}async encryptionEnabled(e){const n=[];return(!e||e==="nip04")&&n.push("nip04"),(!e||e==="nip44")&&n.push("nip44"),n}async encrypt(e,n,s){if(!this._privateKey||!this.privateKey)throw Error("Attempted to encrypt without a private key");const r=e.pubkey;if(s==="nip44"){const o=nip44_exports.v2.utils.getConversationKey(this._privateKey,r);return await nip44_exports.v2.encrypt(n,o)}return await nip04_exports.encrypt(this._privateKey,r,n)}async decrypt(e,n,s){if(!this._privateKey||!this.privateKey)throw Error("Attempted to decrypt without a private key");const r=e.pubkey;if(s==="nip44"){const o=nip44_exports.v2.utils.getConversationKey(this._privateKey,r);return await nip44_exports.v2.decrypt(n,o)}return await nip04_exports.decrypt(this._privateKey,r,n)}toPayload(){if(!this._privateKey)throw new Error("Private key not available");const e={type:"private-key",payload:this.privateKey};return JSON.stringify(e)}static async fromPayload(e,n){const s=JSON.parse(e);if(s.type!=="private-key")throw new Error(`Invalid payload type: expected 'private-key', got ${s.type}`);if(!s.payload||typeof s.payload!="string")throw new Error("Invalid payload content for private-key signer");return new Fe(s.payload,n)}};registerSigner("private-key",NDKPrivateKeySigner);function dedup(t,e){return t.created_at>e.created_at?t:e}async function getRelayListForUser(t,e){return(await getRelayListForUsers([t],e)).get(t)}async function getRelayListForUsers(t,e,n=!1,s=1e3,r){var p;const o=e.outboxPool||e.pool,a=new Set;for(const y of o.relays.values())a.add(y);if(r)for(const y of r.values())for(const b of y){const m=o.getRelay(b,!0,!0);m&&a.add(m)}const c=new Map,l=new Map,u=new NDKRelaySet(a,e);if((p=e.cacheAdapter)!=null&&p.locking&&!n){const y=await e.fetchEvents({kinds:[3,10002],authors:Array.from(new Set(t))},{cacheUsage:"ONLY_CACHE",subId:"ndk-relay-list-fetch"});for(const b of y)b.kind===10002&&c.set(b.pubkey,NDKRelayList.from(b));for(const b of y)if(b.kind===3){if(c.has(b.pubkey))continue;const m=relayListFromKind3(e,b);m&&l.set(b.pubkey,m)}t=t.filter(b=>!c.has(b)&&!l.has(b))}if(t.length===0)return c;const f=new Map,h=new Map;return new Promise(y=>{let b=!1;(async()=>{const w={closeOnEose:!0,pool:o,groupable:!0,subId:"ndk-relay-list-fetch",addSinceFromCache:!0,relaySet:u};u&&(w.relaySet=u),e.subscribe({kinds:[3,10002],authors:t},w,{onEvent:P=>{if(P.kind===10002){const O=f.get(P.pubkey);if(O&&O.created_at>P.created_at)return;f.set(P.pubkey,P)}else if(P.kind===3){const O=h.get(P.pubkey);if(O&&O.created_at>P.created_at)return;h.set(P.pubkey,P)}},onEose:()=>{if(!b){b=!0,e.debug(`[getRelayListForUsers] EOSE - relayListEvents: ${f.size}, contactListEvents: ${h.size}`);for(const P of f.values())c.set(P.pubkey,NDKRelayList.from(P));for(const P of t){if(c.has(P))continue;const O=h.get(P);if(!O)continue;const U=relayListFromKind3(e,O);U&&c.set(P,U)}e.debug(`[getRelayListForUsers] Returning ${c.size} relay lists for ${t.length} pubkeys`),y(c)}}});const k=Array.from(a).some(P=>P.status<=2),A=Array.from(a).some(P=>P.status===4);let B=s;(k||A)&&(B=s+3e3),e.debug(`[getRelayListForUsers] Setting fallback timeout to ${B}ms (disconnected: ${k}, connecting: ${A})`,{pubkeys:t}),setTimeout(()=>{b||(b=!0,e.debug(`[getRelayListForUsers] Timeout reached, returning ${c.size} relay lists`),y(c))},B)})()})}var OutboxItem=class{constructor(t){g(this,"type");g(this,"relayUrlScores");g(this,"readRelays");g(this,"writeRelays");this.type=t,this.relayUrlScores=new Map,this.readRelays=new Set,this.writeRelays=new Set}},OutboxTracker=class extends lib$1.EventEmitter{constructor(e){super();g(this,"data");g(this,"ndk");g(this,"debug");this.ndk=e,this.debug=e.debug.extend("outbox-tracker"),this.data=new dist.LRUCache({maxSize:1e5,entryExpirationTimeInMS:2*60*1e3})}async trackUsers(e,n=!1){const s=[];for(let r=0;r<e.length;r+=400){const o=e.slice(r,r+400),a=o.map(l=>getKeyFromItem(l)).filter(l=>!this.data.has(l));if(a.length===0)continue;for(const l of a)this.data.set(l,new OutboxItem("user"));const c=new Map;for(const l of o)l instanceof NDKUser&&l.relayUrls.length>0&&c.set(l.pubkey,l.relayUrls);s.push(new Promise(l=>{getRelayListForUsers(a,this.ndk,n,1e3,c).then(u=>{this.debug(`Received relay lists for ${u.size} pubkeys out of ${a.length} requested`);for(const[f,h]of u){let p=this.data.get(f);if(p??(p=new OutboxItem("user")),h){if(p.readRelays=new Set(normalize(h.readRelayUrls)),p.writeRelays=new Set(normalize(h.writeRelayUrls)),this.ndk.relayConnectionFilter){for(const y of p.readRelays)this.ndk.relayConnectionFilter(y)||p.readRelays.delete(y);for(const y of p.writeRelays)this.ndk.relayConnectionFilter(y)||p.writeRelays.delete(y)}this.data.set(f,p),this.emit("user:relay-list-updated",f,p),this.debug(`Adding ${p.readRelays.size} read relays and ${p.writeRelays.size} write relays for ${f}`,h==null?void 0:h.rawEvent())}}}).finally(l)}))}return Promise.all(s)}track(e,n,s=!0){const r=getKeyFromItem(e);n??(n=getTypeFromItem(e));let o=this.data.get(r);return o||(o=new OutboxItem(n),e instanceof NDKUser&&this.trackUsers([e])),o}};function getKeyFromItem(t){return t instanceof NDKUser?t.pubkey:t}function getTypeFromItem(t){return t instanceof NDKUser?"user":"kind"}function correctRelaySet(t,e){const n=e.connectedRelays();if(!Array.from(t.relays).some(r=>n.map(o=>o.url).includes(r.url)))for(const r of n)t.addRelay(r);if(n.length===0)for(const r of e.relays.values())t.addRelay(r);return t}var NDKSubscriptionManager=class{constructor(){g(this,"subscriptions");g(this,"seenEvents",new dist.LRUCache({maxSize:1e4,entryExpirationTimeInMS:5*60*1e3}));this.subscriptions=new Map}add(t){this.subscriptions.set(t.internalId,t),t.onStopped,t.onStopped=()=>{this.subscriptions.delete(t.internalId)},t.on("close",()=>{this.subscriptions.delete(t.internalId)})}seenEvent(t,e){const n=this.seenEvents.get(t)||[];n.some(s=>s.url===e.url)||n.push(e),this.seenEvents.set(t,n)}dispatchEvent(t,e,n=!1){e&&this.seenEvent(t.id,e);const s=this.subscriptions.values(),r=[];for(const o of s)matchFilters(o.filters,t)&&r.push(o);for(const o of r){if(o.exclusiveRelay&&o.relaySet){let a=!1;if(n?a=!o.skipOptimisticPublishEvent:e?a=o.relaySet.relays.has(e):a=(this.seenEvents.get(t.id)||[]).some(l=>o.relaySet.relays.has(l)),!a){o.debug.extend("exclusive-relay")("Rejected event %s from %s (relay not in exclusive set)",t.id,(e==null?void 0:e.url)||(n?"optimistic":"cache"));continue}}o.eventReceived(t,e,!1,n)}}},debug6=createDebug5("ndk:active-user");async function getUserRelayList(t){if(!this.autoConnectUserRelays)return;const e=await getRelayListForUser(t.pubkey,this);if(e){for(const n of e.relays){let s=this.pool.relays.get(n);s||(s=new NDKRelay(n,this.relayAuthDefaultPolicy,this),this.pool.addRelay(s))}return debug6("Connected to %d user relays",e.relays.length),e}}async function setActiveUser(t){if(!this.autoConnectUserRelays)return;const e=this.outboxPool||this.pool;e.connectedRelays.length>0?await getUserRelayList.call(this,t):e.once("connect",async()=>{await getUserRelayList.call(this,t)})}function getEntity(t){try{const e=nip19_exports$1.decode(t);return e.type==="npub"?npub(this,e.data):e.type==="nprofile"?nprofile(this,e.data):e}catch{return null}}function npub(t,e){return t.getUser({pubkey:e})}function nprofile(t,e){const n=t.getUser({pubkey:e.pubkey});return e.relays&&(n.relayUrls=e.relays),n}function isValidHint(t){if(!t||t==="")return!1;try{return new URL(t),!0}catch{return!1}}async function fetchEventFromTag(t,e,n,s={type:"timeout"}){const r=this.debug.extend("fetch-event-from-tag"),[o,a,c]=t;n={},r("fetching event from tag",t,n,s);const l=getRelaysForSync(this,e.pubkey);if(l&&l.size>0){r("fetching event from author relays %o",Array.from(l));const m=NDKRelaySet.fromRelayUrls(Array.from(l),this),w=await this.fetchEvent(a,n,m);if(w)return w}else r("no author relays found for %s",e.pubkey,e);const u=calculateRelaySetsFromFilters(this,[{ids:[a]}],this.pool);r("fetching event without relay hint",u);const f=await this.fetchEvent(a,n);if(f)return f;if(c&&c!==""){const m=await this.fetchEvent(a,n,this.pool.getRelay(c,!0,!0,[{ids:[a]}]));if(m)return m}let h;const p=isValidHint(c)?this.pool.getRelay(c,!1,!0,[{ids:[a]}]):void 0,y=new Promise(m=>{this.fetchEvent(a,n,p).then(m)});if(!isValidHint(c)||s.type==="none")return y;const b=new Promise(async m=>{const w=s.relaySet,k=s.timeout??1500,A=new Promise(B=>setTimeout(B,k));if(s.type==="timeout"&&await A,h)m(h);else{r("fallback fetch triggered");const B=await this.fetchEvent(a,n,w);m(B)}});switch(s.type){case"timeout":return Promise.race([y,b]);case"eose":return h=await y,h||b}}var Queue=class{constructor(t,e){g(this,"queue",[]);g(this,"maxConcurrency");g(this,"processing",new Set);g(this,"promises",new Map);this.maxConcurrency=e}add(t){if(this.promises.has(t.id))return this.promises.get(t.id);const e=new Promise((n,s)=>{this.queue.push({...t,func:()=>t.func().then(r=>(n(r),r),r=>{throw s(r),r})}),this.process()});return this.promises.set(t.id,e),e.finally(()=>{this.promises.delete(t.id),this.processing.delete(t.id),this.process()}),e}process(){if(this.processing.size>=this.maxConcurrency||this.queue.length===0)return;const t=this.queue.shift();!t||this.processing.has(t.id)||(this.processing.add(t.id),t.func())}clear(){this.queue=[]}clearProcessing(){this.processing.clear()}clearAll(){this.clear(),this.clearProcessing()}length(){return this.queue.length}},DEFAULT_OUTBOX_RELAYS=["wss://purplepag.es/","wss://nos.lol/"],NDK=class extends lib$1.EventEmitter{constructor(e={}){super();g(this,"_explicitRelayUrls");g(this,"pool");g(this,"outboxPool");g(this,"_signer");g(this,"_activeUser");g(this,"cacheAdapter");g(this,"debug");g(this,"devWriteRelaySet");g(this,"outboxTracker");g(this,"muteFilter");g(this,"relayConnectionFilter");g(this,"clientName");g(this,"clientNip89");g(this,"queuesZapConfig");g(this,"queuesNip05");g(this,"asyncSigVerification",!1);g(this,"initialValidationRatio",1);g(this,"lowestValidationRatio",.1);g(this,"validationRatioFn");g(this,"filterValidationMode","validate");g(this,"subManager");g(this,"aiGuardrails");g(this,"_signatureVerificationFunction");g(this,"_signatureVerificationWorker");g(this,"signatureVerificationTimeMs",0);g(this,"publishingFailureHandled",!1);g(this,"pools",[]);g(this,"relayAuthDefaultPolicy");g(this,"httpFetch");g(this,"netDebug");g(this,"autoConnectUserRelays",!0);g(this,"_wallet");g(this,"walletConfig");g(this,"fetchEventFromTag",fetchEventFromTag.bind(this));g(this,"getEntity",getEntity.bind(this));this.debug=e.debug||createDebug5("ndk"),this.netDebug=e.netDebug,this._explicitRelayUrls=e.explicitRelayUrls||[],this.subManager=new NDKSubscriptionManager,this.pool=new NDKPool(e.explicitRelayUrls||[],this),this.pool.name="Main",this.pool.on("relay:auth",async(n,s)=>{this.relayAuthDefaultPolicy&&await this.relayAuthDefaultPolicy(n,s)}),this.autoConnectUserRelays=e.autoConnectUserRelays??!0,this.clientName=e.clientName,this.clientNip89=e.clientNip89,this.relayAuthDefaultPolicy=e.relayAuthDefaultPolicy,e.enableOutboxModel!==!1&&(this.outboxPool=new NDKPool(e.outboxRelayUrls||DEFAULT_OUTBOX_RELAYS,this,{debug:this.debug.extend("outbox-pool"),name:"Outbox Pool"}),this.outboxTracker=new OutboxTracker(this),this.outboxTracker.on("user:relay-list-updated",(n,s)=>{this.debug(`Outbox relay list updated for ${n}`);for(const r of this.subManager.subscriptions.values())r.filters.some(a=>{var c;return(c=a.authors)==null?void 0:c.includes(n)})&&typeof r.refreshRelayConnections=="function"&&(this.debug(`Refreshing relay connections for subscription ${r.internalId}`),r.refreshRelayConnections())})),this.signer=e.signer,this.cacheAdapter=e.cacheAdapter,this.muteFilter=e.muteFilter,this.relayConnectionFilter=e.relayConnectionFilter,e.devWriteRelayUrls&&(this.devWriteRelaySet=NDKRelaySet.fromRelayUrls(e.devWriteRelayUrls,this)),this.queuesZapConfig=new Queue("zaps",3),this.queuesNip05=new Queue("nip05",10),e.signatureVerificationWorker&&(this.signatureVerificationWorker=e.signatureVerificationWorker),e.signatureVerificationFunction&&(this.signatureVerificationFunction=e.signatureVerificationFunction),this.initialValidationRatio=e.initialValidationRatio||1,this.lowestValidationRatio=e.lowestValidationRatio||.1,this.validationRatioFn=e.validationRatioFn||this.defaultValidationRatioFn,this.filterValidationMode=e.filterValidationMode||"validate",this.aiGuardrails=new AIGuardrails(e.aiGuardrails||!1),this.aiGuardrails.ndkInstantiated(this);try{this.httpFetch=fetch}catch{}}set explicitRelayUrls(e){this._explicitRelayUrls=e.map(normalizeRelayUrl),this.pool.relayUrls=e}get explicitRelayUrls(){return this._explicitRelayUrls||[]}set signatureVerificationWorker(e){this._signatureVerificationWorker=e,e?(signatureVerificationInit(e),this.asyncSigVerification=!0):this.asyncSigVerification=!1}set signatureVerificationFunction(e){this._signatureVerificationFunction=e,this.asyncSigVerification=!!e}get signatureVerificationFunction(){return this._signatureVerificationFunction}addExplicitRelay(e,n,s=!0){var o;let r;return typeof e=="string"?r=new NDKRelay(e,n,this):r=e,this.pool.addRelay(r,s),(o=this.explicitRelayUrls)==null||o.push(r.url),r}toJSON(){return{relayCount:this.pool.relays.size}.toString()}get activeUser(){return this._activeUser}set activeUser(e){var s;const n=((s=this._activeUser)==null?void 0:s.pubkey)!==(e==null?void 0:e.pubkey);this._activeUser=e,n&&this.emit("activeUser:change",e),e&&n&&setActiveUser.call(this,e)}get signer(){return this._signer}set signer(e){this._signer=e,e&&this.emit("signer:ready",e),e==null||e.user().then(n=>{n.ndk=this,this.activeUser=n})}async connect(e){var s,r,o;this._signer&&this.autoConnectUserRelays&&(this.debug("Attempting to connect to user relays specified by signer %o",await((r=(s=this._signer).relays)==null?void 0:r.call(s,this))),this._signer.relays&&(await this._signer.relays(this)).forEach(c=>this.pool.addRelay(c)));const n=[this.pool.connect(e)];return this.outboxPool&&n.push(this.outboxPool.connect(e)),(o=this.cacheAdapter)!=null&&o.initializeAsync&&n.push(this.cacheAdapter.initializeAsync(this)),Promise.allSettled(n).then(()=>{})}reportInvalidSignature(e,n){this.debug(`Invalid signature detected for event ${e.id}${n?` from relay ${n.url}`:""}`),this.emit("event:invalid-sig",e,n)}defaultValidationRatioFn(e,n,s){if(n<10)return this.initialValidationRatio;const r=Math.min(n/100,1),o=this.initialValidationRatio*(1-r)+this.lowestValidationRatio*r;return Math.max(o,this.lowestValidationRatio)}getUser(e){if(typeof e=="string")if(e.startsWith("npub1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="npub")throw new Error(`Invalid npub: ${e}`);return this.getUser({pubkey:r})}else if(e.startsWith("nprofile1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="nprofile")throw new Error(`Invalid nprofile: ${e}`);return this.getUser({pubkey:r.pubkey,relayUrls:r.relays})}else return this.getUser({pubkey:e});const n=new NDKUser(e);return n.ndk=this,n}async getUserFromNip05(e,n=!1){return NDKUser.fromNip05(e,this,n)}async fetchUser(e,n=!1){if(isValidNip05(e))return NDKUser.fromNip05(e,this,n);if(e.startsWith("npub1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="npub")throw new Error(`Invalid npub: ${e}`);const o=new NDKUser({pubkey:r});return o.ndk=this,o}else if(e.startsWith("nprofile1")){const{type:s,data:r}=nip19_exports$1.decode(e);if(s!=="nprofile")throw new Error(`Invalid nprofile: ${e}`);const o=new NDKUser({pubkey:r.pubkey,relayUrls:r.relays});return o.ndk=this,o}else{const s=new NDKUser({pubkey:e});return s.ndk=this,s}}subscribe(e,n,s=!0,r=!0){var h,p,y;let o=n==null?void 0:n.relaySet,a=r;s instanceof NDKRelaySet?(console.warn("relaySet is deprecated, use opts.relaySet instead. This will be removed in version v2.14.0"),o=s,a=r):(typeof s=="boolean"||typeof s=="object")&&(a=s);let c;const l={relaySet:o,...n};a&&typeof a=="object"&&(a.onEvent&&(l.onEvent=a.onEvent),a.onEose&&(l.onEose=a.onEose),a.onClose&&(l.onClose=a.onClose),a.onEvents&&(c=a.onEvents));const u=new NDKSubscription(this,e,l);this.subManager.add(u),(p=(h=this.aiGuardrails)==null?void 0:h.subscription)==null||p.created(Array.isArray(e)?e:[e],l);const f=u.pool;if(u.relaySet)for(const b of u.relaySet.relays)f.useTemporaryRelay(b,void 0,u.filters);if(this.outboxPool&&u.hasAuthorsFilter()){const b=u.filters.filter(m=>{var w;return m.authors&&((w=m.authors)==null?void 0:w.length)>0}).flatMap(m=>m.authors);(y=this.outboxTracker)==null||y.trackUsers(b)}return a&&setTimeout(async()=>{var m;(m=this.cacheAdapter)!=null&&m.initializeAsync&&!this.cacheAdapter.ready&&await this.cacheAdapter.initializeAsync(this);const b=u.start(!c);b&&b.length>0&&c&&c(b)},0),u}fetchEventSync(e){if(!this.cacheAdapter)throw new Error("Cache adapter not set");let n;typeof e=="string"?n=[filterFromId(e)]:n=e;const s=new NDKSubscription(this,n),r=this.cacheAdapter.query(s);if(r instanceof Promise)throw new Error("Cache adapter is async");return r.map(o=>(o.ndk=this,o))}async fetchEvent(e,n,s){var a,c;let r,o;if(s instanceof NDKRelay?o=new NDKRelaySet(new Set([s]),this):s instanceof NDKRelaySet&&(o=s),!s&&typeof e=="string"&&!isNip33AValue(e)){const l=relaysFromBech32(e,this);l.length>0&&(o=new NDKRelaySet(new Set(l),this),o=correctRelaySet(o,this.pool))}if(typeof e=="string"?r=[filterFromId(e)]:Array.isArray(e)?r=e:r=[e],typeof e!="string"&&((c=(a=this.aiGuardrails)==null?void 0:a.ndk)==null||c.fetchingEvents(r)),r.length===0)throw new Error(`Invalid filter: ${JSON.stringify(e)}`);return new Promise((l,u)=>{let f=null;const h={...n||{},closeOnEose:!0};o&&(h.relaySet=o);const p=setTimeout(()=>{y.stop(),this.aiGuardrails._nextCallDisabled=null,l(f)},1e4),y=this.subscribe(r,h,{onEvent:b=>{b.ndk=this,b.isReplaceable()?(!f||f.created_at<b.created_at)&&(f=b):(clearTimeout(p),this.aiGuardrails._nextCallDisabled=null,l(b))},onEose:()=>{clearTimeout(p),this.aiGuardrails._nextCallDisabled=null,l(f)}})})}async fetchEvents(e,n,s){var r,o;return(o=(r=this.aiGuardrails)==null?void 0:r.ndk)==null||o.fetchingEvents(e,n),new Promise(a=>{const c=new Map,l={...n||{},closeOnEose:!0};s&&(l.relaySet=s);const u=f=>{let h;f instanceof NDKEvent?h=f:h=new NDKEvent(void 0,f);const p=h.deduplicationKey(),y=c.get(p);y&&(h=dedup(y,h)),h.ndk=this,c.set(p,h)};this.subscribe(e,{...l,onEvent:u,onEose:()=>{this.aiGuardrails._nextCallDisabled=null,a(new Set(c.values()))}})})}assertSigner(){if(!this.signer)throw this.emit("signer:required"),new Error("Signer required")}guardrailOff(e){return e?typeof e=="string"?this.aiGuardrails._nextCallDisabled=new Set([e]):this.aiGuardrails._nextCallDisabled=new Set(e):this.aiGuardrails._nextCallDisabled="all",this}set wallet(e){var n,s;if(!e){this._wallet=void 0,this.walletConfig=void 0;return}this._wallet=e,this.walletConfig??(this.walletConfig={}),this.walletConfig.lnPay=(n=e==null?void 0:e.lnPay)==null?void 0:n.bind(e),this.walletConfig.cashuPay=(s=e==null?void 0:e.cashuPay)==null?void 0:s.bind(e)}get wallet(){return this._wallet}},nip19_exports={};__reExport(nip19_exports,nip19_star);var nip49_exports={};__reExport(nip49_exports,nip49_star);function disconnect(t,e){return e??(e=createDebug5("ndk:relay:auth-policies:disconnect")),async n=>{e==null||e(`Relay ${n.url} requested authentication, disconnecting`),t.removeRelay(n.url)}}async function signAndAuth(t,e,n,s,r,o){try{await t.sign(n),r(t)}catch(a){s==null||s(`Failed to publish auth event to relay ${e.url}`,a),o(t)}}function signIn({ndk:t,signer:e,debug:n}={}){return n??(n=createDebug5("ndk:auth-policies:signIn")),async(s,r)=>{n==null||n(`Relay ${s.url} requested authentication, signing in`);const o=new NDKEvent(t);return o.kind=22242,o.tags=[["relay",s.url],["challenge",r]],e??(e=t==null?void 0:t.signer),new Promise(async(a,c)=>{e?await signAndAuth(o,s,e,n,a,c):t==null||t.once("signer:ready",async l=>{await signAndAuth(o,s,l,n,a,c)})})}}var NDKRelayAuthPolicies={disconnect,signIn};async function ndkSignerFromPayload(t,e){let n;try{n=JSON.parse(t)}catch(r){console.error("Failed to parse signer payload string",t,r);return}if(!n||typeof n.type!="string"){console.error("Failed to parse signer payload string",t,new Error("Missing type field"));return}const s=signerRegistry.get(n.type);if(!s)throw new Error(`Unknown signer type: ${n.type}`);try{return await s.fromPayload(t,e)}catch(r){const o=r instanceof Error?r.message:String(r);throw new Error(`Failed to deserialize signer type ${n.type}: ${o}`)}}var NDKNip07Signer=class ze{constructor(e=1e3,n){g(this,"_userPromise");g(this,"encryptionQueue",[]);g(this,"encryptionProcessing",!1);g(this,"debug");g(this,"waitTimeout");g(this,"_pubkey");g(this,"ndk");g(this,"_user");this.debug=createDebug5("ndk:nip07"),this.waitTimeout=e,this.ndk=n}get pubkey(){if(!this._pubkey)throw new Error("Not ready");return this._pubkey}async blockUntilReady(){var s;await this.waitForExtension();const e=await((s=window.nostr)==null?void 0:s.getPublicKey());if(!e)throw new Error("User rejected access");this._pubkey=e;let n;return this.ndk?n=this.ndk.getUser({pubkey:e}):n=new NDKUser({pubkey:e}),this._user=n,n}async user(){return this._userPromise||(this._userPromise=this.blockUntilReady()),this._userPromise}get userSync(){if(!this._user)throw new Error("User not ready");return this._user}async sign(e){var s;await this.waitForExtension();const n=await((s=window.nostr)==null?void 0:s.signEvent(e));if(!n)throw new Error("Failed to sign event");return n.sig}async relays(e){var r,o;await this.waitForExtension();const n=await((o=(r=window.nostr)==null?void 0:r.getRelays)==null?void 0:o.call(r))||{},s=[];for(const a of Object.keys(n))n[a].read&&n[a].write&&s.push(a);return s.map(a=>new NDKRelay(a,e==null?void 0:e.relayAuthDefaultPolicy,e))}async encryptionEnabled(e){var s,r;const n=[];return(!e||e==="nip04")&&((s=window.nostr)!=null&&s.nip04)&&n.push("nip04"),(!e||e==="nip44")&&((r=window.nostr)!=null&&r.nip44)&&n.push("nip44"),n}async encrypt(e,n,s="nip04"){if(!await this.encryptionEnabled(s))throw new Error(`${s}encryption is not available from your browser extension`);await this.waitForExtension();const r=e.pubkey;return this.queueEncryption(s,"encrypt",r,n)}async decrypt(e,n,s="nip04"){if(!await this.encryptionEnabled(s))throw new Error(`${s}encryption is not available from your browser extension`);await this.waitForExtension();const r=e.pubkey;return this.queueEncryption(s,"decrypt",r,n)}async queueEncryption(e,n,s,r){return new Promise((o,a)=>{this.encryptionQueue.push({scheme:e,method:n,counterpartyHexpubkey:s,value:r,resolve:o,reject:a}),this.encryptionProcessing||this.processEncryptionQueue()})}async processEncryptionQueue(e,n=0){var f,h;if(!e&&this.encryptionQueue.length===0){this.encryptionProcessing=!1;return}this.encryptionProcessing=!0;const s=e||this.encryptionQueue.shift();if(!s){this.encryptionProcessing=!1;return}const{scheme:r,method:o,counterpartyHexpubkey:a,value:c,resolve:l,reject:u}=s;this.debug("Processing encryption queue item",{method:o,counterpartyHexpubkey:a,value:c});try{const p=await((h=(f=window.nostr)==null?void 0:f[r])==null?void 0:h[o](a,c));if(!p)throw new Error("Failed to encrypt/decrypt");l(p)}catch(p){const y=p instanceof Error?p.message:String(p);if(y.includes("call already executing")&&n<5){this.debug("Retrying encryption queue item",{method:o,counterpartyHexpubkey:a,value:c,retries:n}),setTimeout(()=>{this.processEncryptionQueue(s,n+1)},50*n);return}u(p instanceof Error?p:new Error(y))}this.processEncryptionQueue()}waitForExtension(){return new Promise((e,n)=>{if(window.nostr){e();return}let s;const r=setInterval(()=>{window.nostr&&(clearTimeout(s),clearInterval(r),e())},100);s=setTimeout(()=>{clearInterval(r),n(new Error("NIP-07 extension not available"))},this.waitTimeout)})}toPayload(){return JSON.stringify({type:"nip07",payload:""})}static async fromPayload(e,n){const s=JSON.parse(e);if(s.type!=="nip07")throw new Error(`Invalid payload type: expected 'nip07', got ${s.type}`);return new ze(void 0,n)}};registerSigner("nip07",NDKNip07Signer);var NDKNostrRpc=class extends lib$1.EventEmitter{constructor(e,n,s,r){super();g(this,"ndk");g(this,"signer");g(this,"relaySet");g(this,"debug");g(this,"encryptionType","nip04");g(this,"pool");if(this.ndk=e,this.signer=n,r){this.pool=new NDKPool(r,e,{debug:s.extend("rpc-pool"),name:"Nostr RPC"}),this.relaySet=new NDKRelaySet(new Set,e,this.pool);for(const o of r){const a=this.pool.getRelay(o,!1,!1);a.authPolicy=NDKRelayAuthPolicies.signIn({ndk:e,signer:n,debug:s}),this.relaySet.addRelay(a),a.connect()}}this.debug=s.extend("rpc")}subscribe(e){return new Promise(n=>{const s=this.ndk.subscribe(e,{closeOnEose:!1,groupable:!1,cacheUsage:"ONLY_RELAY",pool:this.pool,relaySet:this.relaySet,onEvent:async r=>{try{const o=await this.parseEvent(r);o.method?this.emit("request",o):(this.emit(`response-${o.id}`,o),this.emit("response",o))}catch(o){this.debug("error parsing event",o,r.rawEvent())}},onEose:()=>{this.debug("eosed"),n(s)}})})}async parseEvent(e){this.encryptionType==="nip44"&&e.content.includes("?iv=")?this.encryptionType="nip04":this.encryptionType==="nip04"&&!e.content.includes("?iv=")&&(this.encryptionType="nip44");const n=this.ndk.getUser({pubkey:e.pubkey});n.ndk=this.ndk;let s;try{s=await this.signer.decrypt(n,e.content,this.encryptionType)}catch{const h=this.encryptionType==="nip04"?"nip44":"nip04";s=await this.signer.decrypt(n,e.content,h),this.encryptionType=h}const r=JSON.parse(s),{id:o,method:a,params:c,result:l,error:u}=r;return a?{id:o,pubkey:e.pubkey,method:a,params:c,event:e}:{id:o,result:l,error:u,event:e}}async sendResponse(e,n,s,r=24133,o){const a={id:e,result:s};o&&(a.error=o);const c=await this.signer.user(),l=this.ndk.getUser({pubkey:n}),u=new NDKEvent(this.ndk,{kind:r,content:JSON.stringify(a),tags:[["p",n]],pubkey:c.pubkey});u.content=await this.signer.encrypt(l,u.content,this.encryptionType),await u.sign(this.signer),await u.publish(this.relaySet)}async sendRequest(e,n,s=[],r=24133,o){const a=Math.random().toString(36).substring(7),c=await this.signer.user(),l=this.ndk.getUser({pubkey:e}),u={id:a,method:n,params:s},f=new Promise(()=>{const p=y=>{y.result==="auth_url"?(this.once(`response-${a}`,p),this.emit("authUrl",y.error)):o&&o(y)};this.once(`response-${a}`,p)}),h=new NDKEvent(this.ndk,{kind:r,content:JSON.stringify(u),tags:[["p",e]],pubkey:c.pubkey});return h.content=await this.signer.encrypt(l,h.content,this.encryptionType),await h.sign(this.signer),await h.publish(this.relaySet),f}};function nostrConnectGenerateSecret(){return Math.random().toString(36).substring(2,15)}function generateNostrConnectUri(t,e,n,s){const r={name:s!=null&&s.name?encodeURIComponent(s.name):"",url:s!=null&&s.url?encodeURIComponent(s.url):"",image:s!=null&&s.image?encodeURIComponent(s.image):"",perms:s!=null&&s.perms?encodeURIComponent(s.perms):""};let o=`nostrconnect://${t}?image=${r.image}&url=${r.url}&name=${r.name}&perms=${r.perms}&secret=${encodeURIComponent(e)}`;return n&&(o+=`&relay=${encodeURIComponent(n)}`),o}var NDKNip46Signer=class Me extends lib$1.EventEmitter{constructor(n,s,r,o,a){super();g(this,"ndk");g(this,"_user");g(this,"bunkerPubkey");g(this,"userPubkey");g(this,"secret");g(this,"localSigner");g(this,"nip05");g(this,"rpc");g(this,"debug");g(this,"relayUrls");g(this,"subscription");g(this,"nostrConnectUri");g(this,"nostrConnectSecret");this.ndk=n,this.debug=n.debug.extend("nip46:signer"),this.relayUrls=o,r?typeof r=="string"?this.localSigner=new NDKPrivateKeySigner(r):this.localSigner=r:this.localSigner=NDKPrivateKeySigner.generate(),s===!1||(s?s.startsWith("bunker://")?this.bunkerFlowInit(s):this.nip05Init(s):this.nostrconnectFlowInit(a)),this.rpc=new NDKNostrRpc(this.ndk,this.localSigner,this.debug,this.relayUrls)}get pubkey(){if(!this.userPubkey)throw new Error("Not ready");return this.userPubkey}static bunker(n,s,r){return new Me(n,s,r)}static nostrconnect(n,s,r,o){return new Me(n,void 0,r,[s],o)}nostrconnectFlowInit(n){var r;this.nostrConnectSecret=nostrConnectGenerateSecret();const s=this.localSigner.pubkey;this.nostrConnectUri=generateNostrConnectUri(s,this.nostrConnectSecret,(r=this.relayUrls)==null?void 0:r[0],n)}bunkerFlowInit(n){const s=new URL(n),r=s.hostname||s.pathname.replace(/^\/\//,""),o=s.searchParams.get("pubkey"),a=s.searchParams.getAll("relay"),c=s.searchParams.get("secret");this.bunkerPubkey=r,this.userPubkey=o,this.relayUrls=a,this.secret=c}nip05Init(n){this.nip05=n}async startListening(){if(this.subscription)return;const n=await this.localSigner.user();if(!n)throw new Error("Local signer not ready");this.subscription=await this.rpc.subscribe({kinds:[24133],"#p":[n.pubkey]})}async user(){return this._user?this._user:this.blockUntilReady()}get userSync(){if(!this._user)throw new Error("Remote user not ready synchronously");return this._user}async blockUntilReadyNostrConnect(){return new Promise((n,s)=>{const r=o=>{o.result===this.nostrConnectSecret&&(this._user=o.event.author,this.userPubkey=o.event.pubkey,this.bunkerPubkey=o.event.pubkey,this.rpc.off("response",r),n(this._user))};this.startListening(),this.rpc.on("response",r)})}async blockUntilReady(){if(!this.bunkerPubkey&&!this.nostrConnectSecret&&!this.nip05)throw new Error("Bunker pubkey not set");if(this.nostrConnectSecret)return this.blockUntilReadyNostrConnect();if(this.nip05&&!this.userPubkey){const n=await NDKUser.fromNip05(this.nip05,this.ndk);n&&(this._user=n,this.userPubkey=n.pubkey,this.relayUrls=n.nip46Urls,this.rpc=new NDKNostrRpc(this.ndk,this.localSigner,this.debug,this.relayUrls))}if(!this.bunkerPubkey&&this.userPubkey)this.bunkerPubkey=this.userPubkey;else if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");return await this.startListening(),this.rpc.on("authUrl",(...n)=>{this.emit("authUrl",...n)}),new Promise((n,s)=>{const r=[this.userPubkey??""];if(this.secret&&r.push(this.secret),!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"connect",r,24133,o=>{o.result==="ack"?this.getPublicKey().then(a=>{this.userPubkey=a,this._user=this.ndk.getUser({pubkey:a}),n(this._user)}):s(o.error)})})}stop(){var n;(n=this.subscription)==null||n.stop(),this.subscription=void 0}async getPublicKey(){return this.userPubkey?this.userPubkey:new Promise((n,s)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"get_public_key",[],24133,r=>{n(r.result)})})}async encryptionEnabled(n){return n?[n]:Promise.resolve(["nip04","nip44"])}async encrypt(n,s,r="nip04"){return this.encryption(n,s,r,"encrypt")}async decrypt(n,s,r="nip04"){return this.encryption(n,s,r,"decrypt")}async encryption(n,s,r,o){return new Promise((c,l)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,`${r}_${o}`,[n.pubkey,s],24133,u=>{u.error?l(u.error):c(u.result)})})}async sign(n){return new Promise((r,o)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"sign_event",[JSON.stringify(n)],24133,a=>{if(a.error)o(a.error);else{const c=JSON.parse(a.result);r(c.sig)}})})}async createAccount(n,s,r){await this.startListening();const o=[];return n&&o.push(n),s&&o.push(s),r&&o.push(r),new Promise((a,c)=>{if(!this.bunkerPubkey)throw new Error("Bunker pubkey not set");this.rpc.sendRequest(this.bunkerPubkey,"create_account",o,24133,l=>{if(l.error)c(l.error);else{const u=l.result;a(u)}})})}toPayload(){if(!this.bunkerPubkey||!this.userPubkey)throw new Error("NIP-46 signer is not fully initialized for serialization");const n={type:"nip46",payload:{bunkerPubkey:this.bunkerPubkey,userPubkey:this.userPubkey,relayUrls:this.relayUrls,secret:this.secret,localSignerPayload:this.localSigner.toPayload(),nip05:this.nip05||null}};return JSON.stringify(n)}static async fromPayload(n,s){if(!s)throw new Error("NDK instance is required to deserialize NIP-46 signer");const r=JSON.parse(n);if(r.type!=="nip46")throw new Error(`Invalid payload type: expected 'nip46', got ${r.type}`);const o=r.payload;if(!o||typeof o!="object"||!o.localSignerPayload)throw new Error("Invalid payload content for nip46 signer");const a=await ndkSignerFromPayload(o.localSignerPayload,s);if(!a)throw new Error("Failed to deserialize local signer for NIP-46");if(!(a instanceof NDKPrivateKeySigner))throw new Error("Local signer must be an instance of NDKPrivateKeySigner");let c;return c=new Me(s,!1,a,o.relayUrls),c.userPubkey=o.userPubkey,c.bunkerPubkey=o.bunkerPubkey,c.relayUrls=o.relayUrls,c.secret=o.secret,o.userPubkey&&(c._user=new NDKUser({pubkey:o.userPubkey}),c._user&&(c._user.ndk=s)),c}};registerSigner("nip46",NDKNip46Signer);createDebug5("ndk:zapper:ln");createDebug5("ndk:zapper");const index=Object.freeze(Object.defineProperty({__proto__:null,BECH32_REGEX,NDKAppHandlerEvent,NDKArticle,NDKBlossomList,NDKCashuMintAnnouncement,NDKCashuMintList,NDKClassified,NDKDVMJobFeedback,NDKDraft,NDKEvent,NDKFedimintMint,NDKFollowPack,NDKHighlight,NDKImage,NDKKind,NDKList,NDKMintRecommendation,NDKNip07Signer,NDKNip46Signer,NDKNostrRpc,NDKNutzap,NDKPool,NDKPrivateKeySigner,NDKProject,NDKProjectTemplate,NDKPublishError,NDKRelay,NDKRelayAuthPolicies,NDKRelayList,NDKRelaySet,NDKRepost,NDKSimpleGroupMemberList,NDKSimpleGroupMetadata,NDKStory,NDKStorySticker,NDKSubscription,NDKSubscriptionReceipt,NDKSubscriptionStart,NDKSubscriptionTier,NDKTask,NDKThread,NDKUser,NDKVideo,NDKWiki,NDKWikiMergeRequest,NIP33_A_REGEX,calculateRelaySetFromEvent,default:NDK,defaultOpts,deserialize,eventHasETagMarkers,fetchRelayInformation,filterFingerprint,filterFromId,generateContentTags,generateHashtags,getRelayListForUser,getRelayListForUsers,getReplyTag,getRootTag,imetaTagToTag,isNip33AValue,isValidHex64,isValidNip05,isValidPubkey,mapImetaTag,mergeFilters,mergeTags,ndkSignerFromPayload,newAmount,nip19:nip19_exports,nip49:nip49_exports,normalize,normalizeRelayUrl,normalizeUrl,parseTagToSubscriptionAmount,possibleIntervalFrequencies,processFilters,profileFromEvent,queryFullyFilled,registerSigner,relayListFromKind3,relaysFromBech32,serialize,serializeProfile,strToDimension,strToPosition,tryNormalizeRelayUrl,wrapEvent},Symbol.toStringTag,{value:"Module"})),DEFAULT_RELAYS=["wss://relay.damus.io","wss://nostr.wine","wss://relay.nostr.net","wss://nos.lol","wss://nostr-pub.wellorder.net","wss://relay.getalby.com","wss://relay.primal.net"],MILLISATS_PER_SAT=1e3,DEFAULT_PROFILE_IMAGE="./assets/default_dp.png",xe=class xe{constructor(){g(this,"ndk");g(this,"isConnected",!1);this.ndk=new NDK}static getInstance(){return xe.instance||(xe.instance=new xe),xe.instance}async connectToNostr(e=[...DEFAULT_RELAYS]){const n=e.filter(s=>!this.getRelays().includes(s));if(this.isConnected&&n.length){n.forEach(s=>this.ndk.addExplicitRelay(s));return}this.ndk.explicitRelayUrls=e,await this.ndk.connect(),this.isConnected=!0}getRelays(){return this.ndk.explicitRelayUrls||DEFAULT_RELAYS}async resolveNDKUser(e){return e.npub?this.ndk.getUser({npub:e.npub}):e.nip05?await this.ndk.getUserFromNip05(e.nip05)??null:e.pubkey?this.ndk.getUser({pubkey:e.pubkey}):null}async resolveNDKEvent(e){return e.hex?this.ndk.fetchEvent(e.hex):null}async getZapCount(e){const n=await this.resolveNDKUser(e);return n?this.fetchZaps(n):0}async getProfile(e){if(!e)return null;await e.fetchProfile();const n=e.profile;return n&&(n.picture===void 0||n.picture===null)&&(n.picture=DEFAULT_PROFILE_IMAGE),n}async getPost(e){const n=await this.ndk.fetchEvent(e);if(!n)return null;const s=n.getMatchingTags("e");if(s.length>0){const o=s.map(a=>a[1]);await this.ndk.fetchEvents({ids:o})}const r=n.getMatchingTags("a");for(const o of r){const a=o[1],c=o[2];a!=null&&a.startsWith("video/")&&c&&(n.content=n.content+`
265
+ ${c}`)}return n}async fetchFollows(e){try{return(await e.followSet()).size}catch{return 0}}async fetchFollowers(e){try{const n=await this.ndk.fetchEvents({kinds:[NDKKind.Contacts],"#p":[e.pubkey]}),s=new Set;return n.forEach(o=>s.add(o.pubkey)),s.size}catch{return 0}}async fetchNotesAndReplies(e){try{const n=await this.ndk.fetchEvents({kinds:[NDKKind.Text],authors:[e.pubkey],limit:1e3});let s=0,r=0;n.forEach(c=>{c&&(c.tags.some(u=>u[0]==="e"&&u[3]!=="mention")&&s++,r++)});const o=s;return[Math.max(0,r-s),o]}catch{return[0,0]}}async fetchZaps(e){try{return(await this.ndk.fetchEvents({kinds:[9735],"#p":[e.pubkey],limit:1e3})).size}catch{return 0}}getNDK(){return this.ndk}hasSigner(){return typeof window<"u"&&window.nostr||typeof window<"u"&&typeof localStorage<"u"&&localStorage.getItem("nostr_nsec")?!0:!!this.ndk.signer}};g(xe,"instance");let NostrService=xe;export{DEFAULT_PROFILE_IMAGE as D,MILLISATS_PER_SAT as M,NDKNip07Signer as N,SimplePool as S,nip19_exports$1 as a,NostrService as b,DEFAULT_RELAYS as c,NDKEvent as d,NDKKind as e,bytesToHex$2 as f,sha256$2 as g,nip57_exports as h,finalizeEvent as i,index$1 as j,index as k,nip21_exports as n,schnorr$1 as s};
266
+ //# sourceMappingURL=nostr-service-CA0Qx4nJ.js.map