export type CompatibilityMode = "legacy"; export type NetworkNode = { host: string; port: number; pk?: string; /** * True if this entry was learned from a packed-nodes record with * family = TCP_FAMILY_IPV4 (130) or TCP_FAMILY_IPV6 (138). Such nodes * should be added to the TCP relay client pool rather than treated * as UDP DHT nodes — iOS Beagle peers advertise their reachable * relays this way in DHT-PK extras. */ isTcp?: boolean; /** Express relays only: transport scheme. Defaults to HTTPS. Set `false` to * reach an express node over plain HTTP — the express payload is already * end-to-end encrypted (nacl.secretbox), so HTTP keeps CONTENT private from * on-path observers; it does expose the userIDs in the request path. Lets a * relay run on a raw IP with no TLS cert / domain / ICP filing, exactly like * a bootstrap node. */ tls?: boolean; /** Decoded 32-byte form of `pk`, cached lazily on first use so the hot * DHT-distance sort (#closestKnownNodes, run on every get_nodes we answer) * doesn't base58-decode the whole table on every call. */ pkBytes?: Uint8Array; }; export type PeerOptions = { keyFile: string; /** * Stable UDP listen port. Long-lived service peers (Dora registries, * relays/exits) should set this so friends' cached DHT endpoints remain * usable across process restarts. Omit or set 0 for an ephemeral port. */ udpPort?: number; friendStoreFile?: string; bootstrapNodes: NetworkNode[]; expressNodes?: NetworkNode[]; /** * When true, the express relay is used ONLY for friend-request * bootstrap (a one-time control-plane handshake) and NEVER as a * fallback for runtime `sendText` data. This lets a VPN-style data * plane stay fail-fast (an offline friend surfaces as offline, IP * packets don't silently pile into HTTPS store-and-forward) while * still letting the initial friend-request reach a peer whose onion * announce hasn't propagated. decentlan's daemon sets this; chat-style * apps that genuinely want offline message delivery leave it false. */ expressControlPlaneOnly?: boolean; /** * Custom packet id carrying the app's high-volume "bulk data" stream * (e.g. decentlan's IP-forwarding channel). Packets sent on this id get * the same single-transport routing as native chat (PACKET_ID_MESSAGE): * they ride the fresh direct UDP path exclusively, or bridge over the * relay when it's stale — instead of fanning out over UDP + relay + TCP * relay at once (which delivers 3-4 duplicates of every packet and backs * up the relay). Apps that put bulk traffic on a custom id (decentlan * uses 163) MUST set this so the SDK recognises it; otherwise the bulk * optimisation only applies to packet 64 and custom-id data is duplicated. */ bulkDataPacketId?: number; /** * Directory for persisting partially-received files so a dropped or * restarted transfer resumes instead of restarting (断点续传). Unset = * in-memory only (no resume). The fileId is content-addressed (sha256), so a * re-send of the same file matches its persisted partial automatically. */ fileResumeDir?: string; /** * Display name this peer advertises to friends (Carrier nickname, packet 48 + * the userinfo profile). Without it every node reports the build default * "@decentnetwork/peer" and friend lists can't tell anyone apart. decentlan * passes its node name (e.g. "mac-dev", "cn", "tokyo"). Falls back to * DECENT_PEER_NAME / the build default when unset. */ nickname?: string; /** Status/description line shown alongside the nickname. */ statusMessage?: string; /** * Client platform advertised to friends in the userinfo profile — e.g. * "js", "darwin", "linux", "ios", "android". Defaults to the Node * `process.platform` value. Native Beagle apps advertise "ios" / "android". */ platform?: string; /** OS/runtime version advertised in the profile (e.g. "node-24.2.0"). */ osVersion?: string; /** * Application/SDK version advertised in the profile (e.g. "lan-0.1.167"). * Lets peers see which build a friend is on. Defaults to the peer package * version. */ appVersion?: string; compatibilityMode?: CompatibilityMode; debugLabel?: string; }; export type FriendRequest = { pubkey: string; address?: string; userid?: string; nospam?: number; name?: string; description?: string; hello?: string; }; export type FriendConnectionStatus = "connected" | "disconnected"; export type FriendConnectionEvent = { pubkey: string; status: FriendConnectionStatus; }; export type FriendInfoEvent = { pubkey: string; userid?: string; name?: string; description?: string; /** Peer's advertised client metadata (from the userinfo profile). Present * only once the friend has sent a profile with these fields — a legacy * peer (native C SDK before the extension, or an old JS build) leaves them * undefined / protoVersion 0. */ protoVersion?: number; platform?: string; osVersion?: string; appVersion?: string; }; export type TextMessage = { pubkey: string; text: string; /** Stable id for SDK-level acknowledged delivery. Present only for messages * sent with sendTextUntilAck(). Receivers can persist this id for dedupe. */ deliveryId?: string; /** Send the delivery ACK. The SDK calls this automatically after all onText * handlers return successfully; handlers that need durable inbox semantics * should return a Promise that resolves only after the inbox write is done. */ ack?: () => Promise; /** Delivery path: "online" = live net_crypto session (direct/relay), "offline" * = express store-and-forward. Lets the UI color the two differently so a user * can see when online delivery is failing and only offline messages land. */ via?: "online" | "offline"; }; export type SendTextUntilAckOptions = { /** Stable id for retries across a caller-managed outbox. Defaults to a random id. */ deliveryId?: string; /** How long to keep retrying before rejecting. Defaults to 5 minutes. */ timeoutMs?: number; /** Delay between retransmit attempts while no ACK has arrived. Defaults to 5s. */ retryIntervalMs?: number; }; /** * An application-defined custom packet received from a friend, over the * toxcore custom packet ranges: lossless `160–191` (reliable, ordered) or * lossy `192–254` (best-effort). Apps layered on the peer (e.g. decentlan's * IP traffic on `192`) use these to multiplex their own channels without * colliding with chat (`PACKET_ID_MESSAGE = 64`). Packet IDs reserved by the * SDK itself (e.g. `160` UDP-endpoint, `254` NAT-ping) are handled internally * and never surface here. */ export type CustomPacketEvent = { pubkey: string; /** toxcore packet ID: 160–191 lossless, 192–254 lossy. */ id: number; data: Uint8Array; }; /** * A file received INLINE over the message channel — the way iOS/C Carrier * apps send images/audio online: a FileModel JSON envelope * ({data: base64, fileExtension, fileName, type}) carried as a * (bulk)message. Distinct from the toxcore file-transfer path (sendFile), * which native Carrier clients cannot see. */ export type InlineFileEvent = { pubkey: string; /** File name including extension. */ name: string; /** The sender's declared type ("image" | "audio" | "text" | …), if any. */ fileType?: string; data: Uint8Array; via: "online" | "offline"; }; /** * A Carrier friend-invite request received from a peer (PACKET_TYPE_INVITE_REQUEST). * This is the transport the iOS/Android Elastos WebRTC SDK uses for call * signaling: each RtcSignal (offer/answer/candidate/bye JSON) is sent as a * one-way invite under the "carrier" extension. `data` is the reassembled * application payload (JSON for WebRTC; NUL-terminated by native C senders). */ export type InviteEvent = { pubkey: string; /** Extension name — "carrier" for WebRTC/extension invites, undefined for a plain invite. */ ext?: string; /** Optional bundle string set by the sender (usually absent). */ bundle?: string; data: Uint8Array; }; /** * A Carrier friend-invite response (PACKET_TYPE_INVITE_RESPONSE). The iOS * WebRTC receiver never sends these (signaling is one-way invitereq both * ways), but a peer that calls reply_friend_invite produces one. status 0 = * confirmed (carries data); non-zero = refused (reason set, no data). */ export type InviteResponseEvent = { pubkey: string; ext?: string; bundle?: string; status: number; reason?: string; data: Uint8Array; }; export type LookupResult = { pubkey: string; status: "unknown"; records: []; };