import { type VerifiedEvent } from "nostr-tools"; import { type GroupDecryptedEvent, type PairwiseSend, type PublishOuter } from "./GroupChannel"; import { type GroupData } from "./GroupMeta"; import { OneToManyChannel } from "./OneToManyChannel"; import type { SenderKeyDistribution } from "./SenderKey"; import { type StorageAdapter } from "./StorageAdapter"; import { type NostrFetch, type NostrSubscribe, type Rumor } from "./types"; export interface GroupManagerErrorContext { operation: "upsertGroup" | "sendEvent" | "sendMessage" | "rotateSenderKey" | "handleIncomingSessionEvent" | "handleOuterEvent" | "syncOuterSubscription"; groupId?: string; senderEventPubkey?: string; eventId?: string; } export interface GroupManagerOptions { ourOwnerPubkey: string; ourDevicePubkey: string; suppressLocalDeviceEcho?: boolean; storage?: StorageAdapter; oneToMany?: OneToManyChannel; nostrSubscribe?: NostrSubscribe; nostrFetch?: NostrFetch; onDecryptedEvent?: (event: GroupDecryptedEvent) => void; onError?: (error: unknown, context: GroupManagerErrorContext) => void; outerBackfillLookbackSeconds?: number; outerBackfillDurationMs?: number; outerBackfillRetryDelaysMs?: number[]; } export interface CreateGroupOptions { /** * Sends metadata rumors to group members over pairwise sessions. * Required when `fanoutMetadata` is true (default). */ sendPairwise?: PairwiseSend; /** * Controls whether createGroup should immediately fanout metadata to members. * Defaults to true. */ fanoutMetadata?: boolean; /** * Optional timestamp override in milliseconds since epoch (for deterministic tests). */ nowMs?: number; } export interface GroupMetadataFanoutResult { enabled: boolean; attempted: number; succeeded: string[]; failed: string[]; } export interface CreateGroupResult { group: GroupData; metadataRumor?: Rumor; fanout: GroupMetadataFanoutResult; } export declare class GroupManager { private readonly ourOwnerPubkey; private readonly ourDevicePubkey; private readonly storage; private readonly oneToMany; private readonly nostrSubscribe?; private readonly nostrFetch?; private readonly onDecryptedEvent?; private readonly onError?; private readonly suppressLocalDeviceEcho; private readonly outerBackfillLookbackSeconds; private readonly outerBackfillDurationMs; private readonly outerBackfillRetryDelaysMs; private readonly groups; private readonly senderEventToGroup; private readonly groupToSenderEvents; private readonly pendingOuterBySenderEvent; private readonly pendingSessionByGroup; private readonly seenOuterEventIds; private readonly seenOuterEventOrder; private outerUnsubscribe; private outerAuthorsKey; private outerAuthors; private readonly outerBackfillUnsubscribes; private readonly outerBackfillTimers; private readonly maxPendingPerSenderEvent; private readonly maxSeenOuterEventIds; private operationQueue; constructor(opts: GroupManagerOptions); private enqueueOperation; upsertGroup(data: GroupData): Promise; removeGroup(groupId: string): void; destroy(): void; /** * High-level helper for app flows: * - Creates local group data and stores it in this manager. * - By default, fans out group metadata (kind 40) to members over pairwise sessions. * * Note: `createGroupData` remains pure/local-only. Use this method when you want * creation + delivery in one step. */ createGroup(name: string, memberOwnerPubkeys: string[], opts?: CreateGroupOptions): Promise; sendMessage(groupId: string, message: string, opts: { sendPairwise: PairwiseSend; publishOuter: PublishOuter; nowMs?: number; }): Promise<{ outer: VerifiedEvent; inner: Rumor; }>; sendEvent(groupId: string, event: { kind: number; content: string; tags?: string[][]; }, opts: { sendPairwise: PairwiseSend; publishOuter: PublishOuter; nowMs?: number; }): Promise<{ outer: VerifiedEvent; inner: Rumor; }>; rotateSenderKey(groupId: string, opts: { sendPairwise: PairwiseSend; nowMs?: number; }): Promise; handleIncomingSessionEvent(event: Rumor, fromOwnerPubkey: string, fromSenderDevicePubkey?: string): Promise; handleOuterEvent(outer: VerifiedEvent): Promise; syncOuterSubscription(): Promise; managedGroupIds(): string[]; knownSenderEventPubkeys(): string[]; private startOuterBackfill; private currentBackfillAuthors; private runOuterBackfillAttempt; private fetchOuterBackfill; private openOuterBackfillSubscription; private clearOuterBackfills; private emitDecryptedEvents; private queuePendingSessionEvent; private handleIncomingMetadataEvent; private buildMetadataEvent; private drainPendingSessionEvents; private handleIncomingSessionEventForKnownGroup; private bindSenderEventToGroup; private refreshGroupSenderMappings; private queuePendingOuter; private drainPendingOuterForSenderEvent; private reportError; private shouldDropLocalEcho; private routeIncomingEvents; private listLocalSenderEventPubkeys; private normalizeRetryDelays; private hasSeenOuterEvent; private rememberOuterEvent; private sortOuterEvents; } //# sourceMappingURL=GroupManager.d.ts.map