/** * Max attachments rendered from one envelope — a room peer's plaintext body * is untrusted input; without a cap a hostile message claiming hundreds of * attachment entries would force MessageList to render that many bubbles * (each triggering an authenticated fetchAttachmentBlob call) per message. * Exported so tests can assert against it without hardcoding the number. */ export declare const MAX_ATTACHMENTS = 10; export interface EnvelopeAttachment { id: string; mime: string; filename: string; sizeBytes: number; width?: number; height?: number; durationMs?: number; /** Downsampled waveform peaks (float[0,1], length ≤ MAX_VOICE_PEAKS). * Additive-optional like durationMs: no envelope version bump, decoder * tolerates absence (flat fallback waveform), sanitizePeaks clamps on * decode — a room peer's plaintext body is untrusted input. */ peaks?: number[]; } export interface AttachmentEnvelope { body: string; attachments: EnvelopeAttachment[]; } /** Encode a caption + attachment list as the UTF-8 `sealed` bytes for client.send(). */ export declare function encodeAttachmentEnvelope(body: string, attachments: readonly EnvelopeAttachment[]): ArrayBuffer; /** * Decode a plaintext message body as an attachment envelope. * Returns null when the string is not a well-formed envelope of OUR shape — * callers must fall back to treating the original string as the plain body. * This is the read-side inverse of encodeAttachmentEnvelope(), applied to * every room member's message stream (not just the sender's own optimistic UI). */ export declare function decodeAttachmentEnvelope(plaintext: string): AttachmentEnvelope | null; /** * Build the GET /api/sdk/attachments/{id} download URL (server: JWT-authenticated — * callers must fetch with an Authorization header, not assign this directly to * ``; see MessageListClient.fetchAttachmentBlob). */ export declare function attachmentUrl(baseUrl: string, attachmentId: string): string; //# sourceMappingURL=attachment-envelope.d.ts.map