@orangecheck/chat-core 0.1.0 → 0.2.0

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.
@@ -223,7 +223,7 @@ declare function verifyDescriptor(content: DescriptorContent, event: NostrEvent,
223
223
  isBound: IsBound;
224
224
  }): Promise<DescriptorVerify>;
225
225
  interface VerifyPostOpts {
226
- tipHeight: number;
226
+ tipHeight: number | 'unanswered';
227
227
  controlSig?: string;
228
228
  allowlist?: string[];
229
229
  event?: NostrEvent;
@@ -293,9 +293,14 @@ interface ChannelPost {
293
293
  postId: string;
294
294
  event: NostrEvent;
295
295
  }
296
+ interface ChannelPosts {
297
+ posts: ChannelPost[];
298
+ unchecked: number;
299
+ removalsChecked: boolean;
300
+ }
296
301
  declare function orderChannelPosts(posts: ChannelPost[]): ChannelPost[];
297
302
  declare function verifyChannelPosts(events: readonly NostrEvent[], descriptor: DescriptorContent, opts: Pick<VerifyPostOpts, 'tipHeight' | 'verifyBip322' | 'verifyOnChain'> & {
298
303
  isBound: IsBound;
299
- }): Promise<ChannelPost[]>;
304
+ }): Promise<ChannelPosts>;
300
305
 
301
- export { isBitcoinAddress as $, type AuthHostKey as A, type BindingVerifiers as B, CHANNEL_DESCRIPTOR_KIND as C, DEVICE_RECORD_RELAYS as D, type WriteProof as E, type WriteProofVerdict as F, allowlistRoot as G, answeredEvents as H, type IsBound as I, authorizedCopy as J, btcBindingLive as K, type Liveness as L, MAX_ATTACHMENT_BYTES as M, channelId as N, checkWritePolicy as O, type ParsedSessionDeviceEvent as P, type Query as Q, REVOCATION_JWS_TYP as R, type SessionRevocations as S, completeAnswers as T, UnansweredReadError as U, type VerifyBip322 as V, WRITE_QUORUM as W, descriptorDtag as X, descriptorId as Y, evaluateWriteProof as Z, hasBindingTag as _, type VersionBinding as a, isRootedPolicy as a0, isValidAttachment as a1, isValidSlug as a2, liveSessionDevices as a3, meetsReadFloor as a4, orderChannelPosts as a5, parseDescriptor as a6, parsePost as a7, parseSessionDeviceEvent as a8, policyRootedMatches as a9, postDtag as aa, postId as ab, publishToQuorum as ac, readChannelVersions as ad, readFloor as ae, readVersionBinding as af, recordBinding as ag, resolveChannelChain as ah, roleOf as ai, sessionBindingRevoked as aj, sessionDeviceDtag as ak, sessionDeviceRevoked as al, sessionKeysEverBound as am, sessionRevocations as an, verifyChannelPosts as ao, verifyDescriptor as ap, verifyHostRevocation as aq, verifyPost as ar, verifySessionVouch as as, versionDtag as at, vouchIssuedAt as au, vouchRequestStatement as av, vouchedSessionDevices as aw, AUTH_HOST_JWKS_URL as b, type Attachment as c, CHANNEL_POST_KIND as d, CHAT_RELAYS as e, type ChainReads as f, type ChannelError as g, type ChannelPost as h, type ChannelWrite as i, type CopyStanding as j, type DescriptorContent as k, type DescriptorVerify as l, type PostContent as m, type PostVerify as n, type QueryAnswer as o, type ResolvedChannel as p, type ResolvedVersion as q, type Role as r, VOUCH_JWS_TYP as s, type VerifyOnChain as t, type VerifyPostOpts as u, type VersionReads as v, type VouchSubject as w, type WriteAck as x, type WriteOutcome as y, type WritePolicy as z };
306
+ export { hasBindingTag as $, type AuthHostKey as A, type BindingVerifiers as B, CHANNEL_DESCRIPTOR_KIND as C, DEVICE_RECORD_RELAYS as D, type WritePolicy as E, type WriteProof as F, type WriteProofVerdict as G, allowlistRoot as H, type IsBound as I, answeredEvents as J, authorizedCopy as K, type Liveness as L, MAX_ATTACHMENT_BYTES as M, btcBindingLive as N, channelId as O, type ParsedSessionDeviceEvent as P, type Query as Q, REVOCATION_JWS_TYP as R, type SessionRevocations as S, checkWritePolicy as T, UnansweredReadError as U, type VerifyBip322 as V, WRITE_QUORUM as W, completeAnswers as X, descriptorDtag as Y, descriptorId as Z, evaluateWriteProof as _, type VersionBinding as a, isBitcoinAddress as a0, isRootedPolicy as a1, isValidAttachment as a2, isValidSlug as a3, liveSessionDevices as a4, meetsReadFloor as a5, orderChannelPosts as a6, parseDescriptor as a7, parsePost as a8, parseSessionDeviceEvent as a9, policyRootedMatches as aa, postDtag as ab, postId as ac, publishToQuorum as ad, readChannelVersions as ae, readFloor as af, readVersionBinding as ag, recordBinding as ah, resolveChannelChain as ai, roleOf as aj, sessionBindingRevoked as ak, sessionDeviceDtag as al, sessionDeviceRevoked as am, sessionKeysEverBound as an, sessionRevocations as ao, verifyChannelPosts as ap, verifyDescriptor as aq, verifyHostRevocation as ar, verifyPost as as, verifySessionVouch as at, versionDtag as au, vouchIssuedAt as av, vouchRequestStatement as aw, vouchedSessionDevices as ax, AUTH_HOST_JWKS_URL as b, type Attachment as c, CHANNEL_POST_KIND as d, CHAT_RELAYS as e, type ChainReads as f, type ChannelError as g, type ChannelPost as h, type ChannelPosts as i, type ChannelWrite as j, type CopyStanding as k, type DescriptorContent as l, type DescriptorVerify as m, type PostContent as n, type PostVerify as o, type QueryAnswer as p, type ResolvedChannel as q, type ResolvedVersion as r, type Role as s, VOUCH_JWS_TYP as t, type VerifyOnChain as u, type VerifyPostOpts as v, type VersionReads as w, type VouchSubject as x, type WriteAck as y, type WriteOutcome as z };
@@ -223,7 +223,7 @@ declare function verifyDescriptor(content: DescriptorContent, event: NostrEvent,
223
223
  isBound: IsBound;
224
224
  }): Promise<DescriptorVerify>;
225
225
  interface VerifyPostOpts {
226
- tipHeight: number;
226
+ tipHeight: number | 'unanswered';
227
227
  controlSig?: string;
228
228
  allowlist?: string[];
229
229
  event?: NostrEvent;
@@ -293,9 +293,14 @@ interface ChannelPost {
293
293
  postId: string;
294
294
  event: NostrEvent;
295
295
  }
296
+ interface ChannelPosts {
297
+ posts: ChannelPost[];
298
+ unchecked: number;
299
+ removalsChecked: boolean;
300
+ }
296
301
  declare function orderChannelPosts(posts: ChannelPost[]): ChannelPost[];
297
302
  declare function verifyChannelPosts(events: readonly NostrEvent[], descriptor: DescriptorContent, opts: Pick<VerifyPostOpts, 'tipHeight' | 'verifyBip322' | 'verifyOnChain'> & {
298
303
  isBound: IsBound;
299
- }): Promise<ChannelPost[]>;
304
+ }): Promise<ChannelPosts>;
300
305
 
301
- export { isBitcoinAddress as $, type AuthHostKey as A, type BindingVerifiers as B, CHANNEL_DESCRIPTOR_KIND as C, DEVICE_RECORD_RELAYS as D, type WriteProof as E, type WriteProofVerdict as F, allowlistRoot as G, answeredEvents as H, type IsBound as I, authorizedCopy as J, btcBindingLive as K, type Liveness as L, MAX_ATTACHMENT_BYTES as M, channelId as N, checkWritePolicy as O, type ParsedSessionDeviceEvent as P, type Query as Q, REVOCATION_JWS_TYP as R, type SessionRevocations as S, completeAnswers as T, UnansweredReadError as U, type VerifyBip322 as V, WRITE_QUORUM as W, descriptorDtag as X, descriptorId as Y, evaluateWriteProof as Z, hasBindingTag as _, type VersionBinding as a, isRootedPolicy as a0, isValidAttachment as a1, isValidSlug as a2, liveSessionDevices as a3, meetsReadFloor as a4, orderChannelPosts as a5, parseDescriptor as a6, parsePost as a7, parseSessionDeviceEvent as a8, policyRootedMatches as a9, postDtag as aa, postId as ab, publishToQuorum as ac, readChannelVersions as ad, readFloor as ae, readVersionBinding as af, recordBinding as ag, resolveChannelChain as ah, roleOf as ai, sessionBindingRevoked as aj, sessionDeviceDtag as ak, sessionDeviceRevoked as al, sessionKeysEverBound as am, sessionRevocations as an, verifyChannelPosts as ao, verifyDescriptor as ap, verifyHostRevocation as aq, verifyPost as ar, verifySessionVouch as as, versionDtag as at, vouchIssuedAt as au, vouchRequestStatement as av, vouchedSessionDevices as aw, AUTH_HOST_JWKS_URL as b, type Attachment as c, CHANNEL_POST_KIND as d, CHAT_RELAYS as e, type ChainReads as f, type ChannelError as g, type ChannelPost as h, type ChannelWrite as i, type CopyStanding as j, type DescriptorContent as k, type DescriptorVerify as l, type PostContent as m, type PostVerify as n, type QueryAnswer as o, type ResolvedChannel as p, type ResolvedVersion as q, type Role as r, VOUCH_JWS_TYP as s, type VerifyOnChain as t, type VerifyPostOpts as u, type VersionReads as v, type VouchSubject as w, type WriteAck as x, type WriteOutcome as y, type WritePolicy as z };
306
+ export { hasBindingTag as $, type AuthHostKey as A, type BindingVerifiers as B, CHANNEL_DESCRIPTOR_KIND as C, DEVICE_RECORD_RELAYS as D, type WritePolicy as E, type WriteProof as F, type WriteProofVerdict as G, allowlistRoot as H, type IsBound as I, answeredEvents as J, authorizedCopy as K, type Liveness as L, MAX_ATTACHMENT_BYTES as M, btcBindingLive as N, channelId as O, type ParsedSessionDeviceEvent as P, type Query as Q, REVOCATION_JWS_TYP as R, type SessionRevocations as S, checkWritePolicy as T, UnansweredReadError as U, type VerifyBip322 as V, WRITE_QUORUM as W, completeAnswers as X, descriptorDtag as Y, descriptorId as Z, evaluateWriteProof as _, type VersionBinding as a, isBitcoinAddress as a0, isRootedPolicy as a1, isValidAttachment as a2, isValidSlug as a3, liveSessionDevices as a4, meetsReadFloor as a5, orderChannelPosts as a6, parseDescriptor as a7, parsePost as a8, parseSessionDeviceEvent as a9, policyRootedMatches as aa, postDtag as ab, postId as ac, publishToQuorum as ad, readChannelVersions as ae, readFloor as af, readVersionBinding as ag, recordBinding as ah, resolveChannelChain as ai, roleOf as aj, sessionBindingRevoked as ak, sessionDeviceDtag as al, sessionDeviceRevoked as am, sessionKeysEverBound as an, sessionRevocations as ao, verifyChannelPosts as ap, verifyDescriptor as aq, verifyHostRevocation as ar, verifyPost as as, verifySessionVouch as at, versionDtag as au, vouchIssuedAt as av, vouchRequestStatement as aw, vouchedSessionDevices as ax, AUTH_HOST_JWKS_URL as b, type Attachment as c, CHANNEL_POST_KIND as d, CHAT_RELAYS as e, type ChainReads as f, type ChannelError as g, type ChannelPost as h, type ChannelPosts as i, type ChannelWrite as j, type CopyStanding as k, type DescriptorContent as l, type DescriptorVerify as m, type PostContent as n, type PostVerify as o, type QueryAnswer as p, type ResolvedChannel as q, type ResolvedVersion as r, type Role as s, VOUCH_JWS_TYP as t, type VerifyOnChain as u, type VerifyPostOpts as v, type VersionReads as w, type VouchSubject as x, type WriteAck as y, type WriteOutcome as z };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AuthHostKey, V as VerifyBip322, I as IsBound, a as VersionBinding, L as Liveness } from './channel-D8aOo4eI.mjs';
2
- export { b as AUTH_HOST_JWKS_URL, c as Attachment, B as BindingVerifiers, C as CHANNEL_DESCRIPTOR_KIND, d as CHANNEL_POST_KIND, e as CHAT_RELAYS, f as ChainReads, g as ChannelError, h as ChannelPost, i as ChannelWrite, j as CopyStanding, D as DEVICE_RECORD_RELAYS, k as DescriptorContent, l as DescriptorVerify, M as MAX_ATTACHMENT_BYTES, P as ParsedSessionDeviceEvent, m as PostContent, n as PostVerify, Q as Query, o as QueryAnswer, R as REVOCATION_JWS_TYP, p as ResolvedChannel, q as ResolvedVersion, r as Role, S as SessionRevocations, U as UnansweredReadError, s as VOUCH_JWS_TYP, t as VerifyOnChain, u as VerifyPostOpts, v as VersionReads, w as VouchSubject, W as WRITE_QUORUM, x as WriteAck, y as WriteOutcome, z as WritePolicy, E as WriteProof, F as WriteProofVerdict, G as allowlistRoot, H as answeredEvents, J as authorizedCopy, K as btcBindingLive, N as channelId, O as checkWritePolicy, T as completeAnswers, X as descriptorDtag, Y as descriptorId, Z as evaluateWriteProof, _ as hasBindingTag, $ as isBitcoinAddress, a0 as isRootedPolicy, a1 as isValidAttachment, a2 as isValidSlug, a3 as liveSessionDevices, a4 as meetsReadFloor, a5 as orderChannelPosts, a6 as parseDescriptor, a7 as parsePost, a8 as parseSessionDeviceEvent, a9 as policyRootedMatches, aa as postDtag, ab as postId, ac as publishToQuorum, ad as readChannelVersions, ae as readFloor, af as readVersionBinding, ag as recordBinding, ah as resolveChannelChain, ai as roleOf, aj as sessionBindingRevoked, ak as sessionDeviceDtag, al as sessionDeviceRevoked, am as sessionKeysEverBound, an as sessionRevocations, ao as verifyChannelPosts, ap as verifyDescriptor, aq as verifyHostRevocation, ar as verifyPost, as as verifySessionVouch, at as versionDtag, au as vouchIssuedAt, av as vouchRequestStatement, aw as vouchedSessionDevices } from './channel-D8aOo4eI.mjs';
1
+ import { A as AuthHostKey, V as VerifyBip322, I as IsBound, a as VersionBinding, L as Liveness } from './channel-ChK3AAvd.mjs';
2
+ export { b as AUTH_HOST_JWKS_URL, c as Attachment, B as BindingVerifiers, C as CHANNEL_DESCRIPTOR_KIND, d as CHANNEL_POST_KIND, e as CHAT_RELAYS, f as ChainReads, g as ChannelError, h as ChannelPost, i as ChannelPosts, j as ChannelWrite, k as CopyStanding, D as DEVICE_RECORD_RELAYS, l as DescriptorContent, m as DescriptorVerify, M as MAX_ATTACHMENT_BYTES, P as ParsedSessionDeviceEvent, n as PostContent, o as PostVerify, Q as Query, p as QueryAnswer, R as REVOCATION_JWS_TYP, q as ResolvedChannel, r as ResolvedVersion, s as Role, S as SessionRevocations, U as UnansweredReadError, t as VOUCH_JWS_TYP, u as VerifyOnChain, v as VerifyPostOpts, w as VersionReads, x as VouchSubject, W as WRITE_QUORUM, y as WriteAck, z as WriteOutcome, E as WritePolicy, F as WriteProof, G as WriteProofVerdict, H as allowlistRoot, J as answeredEvents, K as authorizedCopy, N as btcBindingLive, O as channelId, T as checkWritePolicy, X as completeAnswers, Y as descriptorDtag, Z as descriptorId, _ as evaluateWriteProof, $ as hasBindingTag, a0 as isBitcoinAddress, a1 as isRootedPolicy, a2 as isValidAttachment, a3 as isValidSlug, a4 as liveSessionDevices, a5 as meetsReadFloor, a6 as orderChannelPosts, a7 as parseDescriptor, a8 as parsePost, a9 as parseSessionDeviceEvent, aa as policyRootedMatches, ab as postDtag, ac as postId, ad as publishToQuorum, ae as readChannelVersions, af as readFloor, ag as readVersionBinding, ah as recordBinding, ai as resolveChannelChain, aj as roleOf, ak as sessionBindingRevoked, al as sessionDeviceDtag, am as sessionDeviceRevoked, an as sessionKeysEverBound, ao as sessionRevocations, ap as verifyChannelPosts, aq as verifyDescriptor, ar as verifyHostRevocation, as as verifyPost, at as verifySessionVouch, au as versionDtag, av as vouchIssuedAt, aw as vouchRequestStatement, ax as vouchedSessionDevices } from './channel-ChK3AAvd.mjs';
3
3
  import { CoinFacts, DirectoryRecord } from '@orangecheck/lock-core/directory';
4
4
  import { NostrEvent, ParsedDeviceEvent } from '@orangecheck/lock-device';
5
5
  export { NostrEvent, verifyNostrEvent } from '@orangecheck/lock-device';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AuthHostKey, V as VerifyBip322, I as IsBound, a as VersionBinding, L as Liveness } from './channel-D8aOo4eI.js';
2
- export { b as AUTH_HOST_JWKS_URL, c as Attachment, B as BindingVerifiers, C as CHANNEL_DESCRIPTOR_KIND, d as CHANNEL_POST_KIND, e as CHAT_RELAYS, f as ChainReads, g as ChannelError, h as ChannelPost, i as ChannelWrite, j as CopyStanding, D as DEVICE_RECORD_RELAYS, k as DescriptorContent, l as DescriptorVerify, M as MAX_ATTACHMENT_BYTES, P as ParsedSessionDeviceEvent, m as PostContent, n as PostVerify, Q as Query, o as QueryAnswer, R as REVOCATION_JWS_TYP, p as ResolvedChannel, q as ResolvedVersion, r as Role, S as SessionRevocations, U as UnansweredReadError, s as VOUCH_JWS_TYP, t as VerifyOnChain, u as VerifyPostOpts, v as VersionReads, w as VouchSubject, W as WRITE_QUORUM, x as WriteAck, y as WriteOutcome, z as WritePolicy, E as WriteProof, F as WriteProofVerdict, G as allowlistRoot, H as answeredEvents, J as authorizedCopy, K as btcBindingLive, N as channelId, O as checkWritePolicy, T as completeAnswers, X as descriptorDtag, Y as descriptorId, Z as evaluateWriteProof, _ as hasBindingTag, $ as isBitcoinAddress, a0 as isRootedPolicy, a1 as isValidAttachment, a2 as isValidSlug, a3 as liveSessionDevices, a4 as meetsReadFloor, a5 as orderChannelPosts, a6 as parseDescriptor, a7 as parsePost, a8 as parseSessionDeviceEvent, a9 as policyRootedMatches, aa as postDtag, ab as postId, ac as publishToQuorum, ad as readChannelVersions, ae as readFloor, af as readVersionBinding, ag as recordBinding, ah as resolveChannelChain, ai as roleOf, aj as sessionBindingRevoked, ak as sessionDeviceDtag, al as sessionDeviceRevoked, am as sessionKeysEverBound, an as sessionRevocations, ao as verifyChannelPosts, ap as verifyDescriptor, aq as verifyHostRevocation, ar as verifyPost, as as verifySessionVouch, at as versionDtag, au as vouchIssuedAt, av as vouchRequestStatement, aw as vouchedSessionDevices } from './channel-D8aOo4eI.js';
1
+ import { A as AuthHostKey, V as VerifyBip322, I as IsBound, a as VersionBinding, L as Liveness } from './channel-ChK3AAvd.js';
2
+ export { b as AUTH_HOST_JWKS_URL, c as Attachment, B as BindingVerifiers, C as CHANNEL_DESCRIPTOR_KIND, d as CHANNEL_POST_KIND, e as CHAT_RELAYS, f as ChainReads, g as ChannelError, h as ChannelPost, i as ChannelPosts, j as ChannelWrite, k as CopyStanding, D as DEVICE_RECORD_RELAYS, l as DescriptorContent, m as DescriptorVerify, M as MAX_ATTACHMENT_BYTES, P as ParsedSessionDeviceEvent, n as PostContent, o as PostVerify, Q as Query, p as QueryAnswer, R as REVOCATION_JWS_TYP, q as ResolvedChannel, r as ResolvedVersion, s as Role, S as SessionRevocations, U as UnansweredReadError, t as VOUCH_JWS_TYP, u as VerifyOnChain, v as VerifyPostOpts, w as VersionReads, x as VouchSubject, W as WRITE_QUORUM, y as WriteAck, z as WriteOutcome, E as WritePolicy, F as WriteProof, G as WriteProofVerdict, H as allowlistRoot, J as answeredEvents, K as authorizedCopy, N as btcBindingLive, O as channelId, T as checkWritePolicy, X as completeAnswers, Y as descriptorDtag, Z as descriptorId, _ as evaluateWriteProof, $ as hasBindingTag, a0 as isBitcoinAddress, a1 as isRootedPolicy, a2 as isValidAttachment, a3 as isValidSlug, a4 as liveSessionDevices, a5 as meetsReadFloor, a6 as orderChannelPosts, a7 as parseDescriptor, a8 as parsePost, a9 as parseSessionDeviceEvent, aa as policyRootedMatches, ab as postDtag, ac as postId, ad as publishToQuorum, ae as readChannelVersions, af as readFloor, ag as readVersionBinding, ah as recordBinding, ai as resolveChannelChain, aj as roleOf, ak as sessionBindingRevoked, al as sessionDeviceDtag, am as sessionDeviceRevoked, an as sessionKeysEverBound, ao as sessionRevocations, ap as verifyChannelPosts, aq as verifyDescriptor, ar as verifyHostRevocation, as as verifyPost, at as verifySessionVouch, au as versionDtag, av as vouchIssuedAt, aw as vouchRequestStatement, ax as vouchedSessionDevices } from './channel-ChK3AAvd.js';
3
3
  import { CoinFacts, DirectoryRecord } from '@orangecheck/lock-core/directory';
4
4
  import { NostrEvent, ParsedDeviceEvent } from '@orangecheck/lock-device';
5
5
  export { NostrEvent, verifyNostrEvent } from '@orangecheck/lock-device';
package/dist/index.js CHANGED
@@ -513,6 +513,9 @@ async function checkWritePermission(content, descriptor, role, pid, opts, verify
513
513
  if (!content.write_proof) return "E_CHAN_FLOOR";
514
514
  if (!opts.controlSig) return "E_CHAN_FLOOR";
515
515
  if (!isBitcoinAddress(content.author_address)) return "E_CHAN_FLOOR";
516
+ if (opts.tipHeight === "unanswered") {
517
+ throw new chunkGFFQSF75_js.UnansweredReadError("the chain tip could not be read");
518
+ }
516
519
  const v = evaluateWriteProof(content.write_proof, w, opts.tipHeight);
517
520
  if (v.verdict !== "accept") return "E_CHAN_FLOOR";
518
521
  const sigOk = await verify({
@@ -753,8 +756,11 @@ async function readChannelVersions(cid, reads, founderHint) {
753
756
  });
754
757
  const fresh = add(res);
755
758
  for (const e of res.events ?? []) until = Math.min(until ?? Infinity, e.created_at);
756
- if ((res.events ?? []).length < VERSION_PAGE_LIMIT || fresh === 0) break;
757
- if (page === VERSION_MAX_PAGES - 1) truncated = true;
759
+ if ((res.events ?? []).length < VERSION_PAGE_LIMIT) break;
760
+ if (fresh === 0 || page === VERSION_MAX_PAGES - 1) {
761
+ truncated = true;
762
+ break;
763
+ }
758
764
  }
759
765
  add(await legacy);
760
766
  let incomplete = false;
@@ -851,15 +857,25 @@ function orderChannelPosts(posts) {
851
857
  async function verifyChannelPosts(events, descriptor, opts) {
852
858
  const removed = /* @__PURE__ */ new Set();
853
859
  const byPostId = /* @__PURE__ */ new Map();
860
+ const unchecked = /* @__PURE__ */ new Set();
861
+ let removalsUnread = false;
854
862
  for (const ev of events) {
855
863
  const content = parsePost(ev);
856
864
  if (!content || content.channel_id !== descriptor.channel_id) continue;
857
865
  const controlSig = ev.tags.find((t) => t[0] === "control_sig")?.[1];
858
- const v = await verifyPost(content, descriptor, {
859
- ...opts,
860
- event: ev,
861
- ...controlSig ? { controlSig } : {}
862
- });
866
+ let v;
867
+ try {
868
+ v = await verifyPost(content, descriptor, {
869
+ ...opts,
870
+ event: ev,
871
+ ...controlSig ? { controlSig } : {}
872
+ });
873
+ } catch (e) {
874
+ if (!(e instanceof chunkGFFQSF75_js.UnansweredReadError)) throw e;
875
+ unchecked.add(postId(content));
876
+ if (typeof content.removes === "string") removalsUnread = true;
877
+ continue;
878
+ }
863
879
  if (!v.ok) continue;
864
880
  if (v.isTombstone && content.removes) {
865
881
  removed.add(content.removes);
@@ -870,7 +886,11 @@ async function verifyChannelPosts(events, descriptor, opts) {
870
886
  byPostId.set(v.postId, { post: content, postId: v.postId, event: ev });
871
887
  }
872
888
  }
873
- return orderChannelPosts([...byPostId.values()].filter((a) => !removed.has(a.postId)));
889
+ return {
890
+ posts: orderChannelPosts([...byPostId.values()].filter((a) => !removed.has(a.postId))),
891
+ unchecked: [...unchecked].filter((id) => !byPostId.has(id)).length,
892
+ removalsChecked: !removalsUnread
893
+ };
874
894
  }
875
895
 
876
896
  // src/directory-legacy.json