Read the shared private collections guide. Signatures below come from the published SDK declarations. Access SDK services through db; use their constructors only when integrating at a lower level.
GroupsOptions
/** Encrypted device-local storage. Reuse the device id and adapter across restarts. */
interface GroupsOptions {
deviceId?: string;
adapter?: GroupStateAdapter;
}
CreatePrivateGroupOptions
interface CreatePrivateGroupOptions {
name: string;
description?: string;
}
PrivateGroupInfo
interface PrivateGroupInfo {
id: string;
name: string;
description: string;
members: string[];
admins: string[];
status: "active" | "removed" | "disbanded";
epoch: bigint;
}
PrivateGroupInvite
interface PrivateGroupInvite {
id: string;
author: string;
name: string | null;
description: string | null;
joinable: boolean;
}
GroupChangePayload
type GroupChangePayload<T extends object> = ChangePayload<T> & {
groupId: string;
};
NostrbaseGroups
/** Shared private collections using the pinned Marmot engine. */
declare class NostrbaseGroups<DB extends SchemaShape<DB> = DefaultSchema> {}
Properties
readonly host: NostrbaseClient<DB>;
readonly deviceId: string;
constructor
constructor(host: NostrbaseClient<DB>, options?: GroupsOptions);
create
create(options: CreatePrivateGroupOptions): Promise<Result<NostrbaseGroup<DB>>>;
get
get(id: string): Promise<Result<NostrbaseGroup<DB>>>;
list
list(): Promise<Result<PrivateGroupInfo[]>>;
exportStateBackup
/** Export encrypted MLS/device state for this account and stable device ID. */
exportStateBackup(): Promise<Result<GroupStateBackup>>;
importStateBackup
/** Import encrypted MLS/device state. Use the same account and stable device ID. */
importStateBackup(
archive: GroupStateBackup | string,
): Promise<Result<GroupStateBackupImport>>;
publishKeyPackage
/** Publish the public device KeyPackage and discovery lists on configured relays. */
publishKeyPackage(): Promise<Result<WriteReceipt[]>>;
invites
invites(): Promise<Result<PrivateGroupInvite[]>>;
join
join(inviteId: string): Promise<Result<NostrbaseGroup<DB>>>;
flush
/** Retry exact envelopes and outstanding Welcomes; no new ciphertext is made. */
flush(options?: { signal?: AbortSignal }): Promise<Result<WriteReceipt[]>>;
runExclusive
/** @internal Serialize SDK mutations with device recovery. */
runExclusive<T>(callback: () => Promise<T>): Promise<T>;
hasReplayPending
/** Inspect only this account/device's durable obligations before loading Marmot. */
hasReplayPending(): Promise<boolean>;
replayQueued
/** Automatic replay reloads handles after recovering exact publication obligations. */
replayQueued(options?: { signal?: AbortSignal }): Promise<Result<WriteReceipt[]>>;
close
close(): void;
closeAsync
closeAsync(): Promise<void>;
NostrbaseGroup
/** A private Marmot scope with the same awaitable query builder as public tables. */
declare class NostrbaseGroup<
DB extends SchemaShape<DB> = DefaultSchema,
> implements QueryHost {}
Properties
readonly id: string;
get info(): PrivateGroupInfo;
constructor
constructor(
host: NostrbaseClient<DB>,
context: GroupContext<DB>,
group: MarmotGroup,
journal: GroupRecordJournal,
);
ready
/** Complete any encrypted receive journal left by an interrupted ingress. */
ready(): Promise<void>;
from
from<K extends keyof DB & string>(table: K): QueryBuilder<DB[K]>;
sync
sync(): Promise<Result<PrivateGroupInfo>>;
invite
invite(pubkey: string): Promise<Result<WriteReceipt[]>>;
remove
remove(pubkey: string): Promise<Result<WriteReceipt[]>>;
rotate
rotate(): Promise<Result<WriteReceipt[]>>;
leave
leave(): Promise<Result<WriteReceipt[]>>;
subscribe
subscribe<K extends keyof DB & string>(
table: K,
callback: (change: GroupChangePayload<DB[K]>) => void,
onError?: (error: NostrbaseError) => void,
): {
unsubscribe(): void;
};
executeInGroup
/** A group handle can only select its own encrypted scope. */
executeInGroup<T extends object>(
groupId: string,
table: string,
state: QueryState,
): Promise<Result<Row<T>[]>>;
execute
execute<T extends object>(
table: string,
state: QueryState,
): Promise<Result<Row<T>[]>>;
flush
/** Catch up membership, then encrypt queued signed record intents for the current epoch. */
flush(options?: { signal?: AbortSignal }): Promise<Result<WriteReceipt[]>>;
dispose
dispose(): void;
Supporting declarations
These types appear in public signatures but are not package exports.
SignedGroupIntent
interface SignedGroupIntent {
groupId: string;
table: string;
recordId: string;
rumor: GroupRecordRumor;
proof: NostrEvent;
createdAt: number;
envelopeId?: string;
}
GroupContext
interface GroupContext<DB extends SchemaShape<DB>> {
account: string;
revision: number;
engine: MarmotClient<undefined, undefined>;
network: GroupNetwork;
durability: GroupDurability;
intents: EncryptedGroupStore<SignedGroupIntent>;
ingress: EncryptedGroupStore<GroupRecordEntry>;
welcomes: EncryptedGroupStore<NostrEvent>;
projections: Map<string, GroupRecordJournal>;
handles: Map<string, NostrbaseGroup<DB>>;
pendingApplication: Map<string, GroupRecordRumor>;
pendingSignals: Map<string, AbortSignal>;
publicationSignals: Map<string, AbortSignal>;
envelopes: Map<string, string>;
receipts: Map<string, WriteReceipt>;
welcomeAttempts: {
groupId: string;
eventId: string;
}[];
guard(): Promise<void>;
projection(groupId: string): Promise<GroupRecordJournal>;
closed: boolean;
}