import { EventEmitter } from "node:events"; export interface InlineFileEvent { pubkey: string; name: string; fileType?: string; data: Uint8Array; via: "online" | "offline"; } export interface InviteEvent { pubkey: string; ext?: string; bundle?: string; data: Uint8Array; } export interface FileOffer { friendId: string; fileNumber: number; fileId: string; name: string; size: number; kind: number; } export interface FileProgress { friendId: string; fileId: string; received: number; total: number; /** True when this is OUR outgoing transfer, false/absent when receiving. */ sending?: boolean; } export interface FileComplete { friendId: string; fileId: string; name: string; size: number; /** Present on the receiving side only. */ data?: Uint8Array; sending?: boolean; } export interface FileCancel { friendId: string; fileId: string; sending: boolean; } export interface CarrierNodeOptions { keyFile: string; bootstrapNodes: { host: string; port: number; pk: string; }[]; expressNodes?: { host: string; port: number; pk: string; tls?: boolean; }[]; nickname?: string; statusMessage?: string; /** Our CryptoPunks id, advertised in the userinfo `gender` field. */ punkId?: number; fileResumeDir?: string; } export interface FriendView { pubkey: string; carrierId: string; name?: string; status: "online" | "offline" | "requested"; address?: string; acceptedAt?: number; requestedAt?: number; /** Their CryptoPunks id, as advertised over Carrier. */ punkId?: number; } export declare class CarrierNode extends EventEmitter { #private; create(opts: CarrierNodeOptions): Promise; start(): Promise; /** Join the DHT and publish ourselves so peers can find us. Deliberately * fault-tolerant: a transient bootstrap timeout must not stop the app from * starting — friends on a relay path still reach us, and the retry loop * keeps trying in the background. */ join(): Promise; identity(): { pubkey: string; userid: string; address: string; }; friends(): FriendView[]; isFriendOnline(userid: string): boolean; sessionStatus(pubkey: string): unknown; dhtHealth(): unknown; sendText(userid: string, text: string): Promise<{ delivery: "acked" | "accepted" | "offline"; } | void>; sendFriendRequest(address: string, hello?: string, opts?: { force?: boolean; }): Promise; acceptFriendRequest(pubkey: string): Promise; removeFriend(userid: string): boolean; /** Decline an inbound request and clear what it created in the SDK. */ rejectFriendRequest(pubkey: string): void; setUserInfo(info: { name?: string; description?: string; punkId?: number | null; }): void; sign(message: Uint8Array): Uint8Array; sendFile(userid: string, data: Uint8Array, name: string): string | null; cancelSend(userid: string, fileId: string): boolean; acceptFile(userid: string, fileNumber: number): void; /** Returns the SDK's delivery verdict — "acked" is the only outcome that * earns a "sent" checkmark. Older SDKs resolve void: report "accepted" * (bytes out, delivery unproven) rather than inventing a confirmation. */ sendInlineFile(userid: string, data: Uint8Array, name: string): Promise<"acked" | "accepted" | "offline">; /** True when the friend is a NATIVE Carrier client (iOS/Android/C): it can * only receive files as the inline envelope — a toxcore sendFile offer is * invisible to it and would hang at "sending" until the 60s give-up. */ isNativeFriend(userid: string): boolean; /** Send on an application packet id. Used for the components channel (165); * unavailable on an SDK build without custom packets, which simply means * this peer can't offer forms — never that chat breaks. */ sendCustomPacket(userid: string, id: number, data: Uint8Array): Promise; sendCallSignal(userid: string, data: Uint8Array | string): Promise; /** Native (iOS/Android/C) friends can't see toxcore file transfer; they only * receive the inline FileModel envelope. decentlan detects this from the DHT * key signature — an internal we don't have here, so beagle probes the * capability and falls back rather than guessing wrong. */ stop(): Promise; }