Skip to main content
El Chat XDK se encarga de la gestión de claves, cifrado, descifrado y firma para X Chat. No llama a la HTTP API de X—combínalo con el XDK de Python o TypeScript, o con HTTPS y un token de acceso de usuario. Recorrido de la app: Primeros pasos. Bots de ejemplo: chat-xdk/examples.

Instalar

El paquete de PyPI es chatxdk; impórtalo como chat_xdk. Requiere Python 3.10+.

Inicio rápido

Descifra un backlog, cachea claves, descifra un evento y cifra una respuesta. Conecta el cuerpo de envío a POST /2/chat/conversations/{id}/messages como se explica en Primeros pasos.

Ciclo de vida y claves

Construye el SDK, guarda las claves privadas (copia de seguridad segura de claves protegida con código de acceso o un blob de claves local), registra las claves públicas con la Chat API y establece tu versión de clave pública registrada después de unlock o import. La copia de seguridad segura de claves está implementada con Juicebox, y por eso los campos de configuración relacionados llevan ese nombre. Llama a generate_keypairs una vez por identidad de dispositivo/app; envía el payload de registro con POST al endpoint de claves públicas. Usa setup / unlock (y helpers de código de acceso relacionados) para la copia de seguridad segura de claves en cada binding. export_keys / import_keys (persistencia de blob de clave en bruto para bots y servidores) están disponibles solo en los bindings nativos—Python, Go, .NET, JVM y Rust. El binding JS/WASM no expone la exportación ni importación de claves en bruto: en un navegador cualquier script que acceda a la instancia podría exfiltrar la identidad, así que JS mantiene las claves dentro de la copia de seguridad segura de claves. Un servidor JS que quiera evitar un round-trip al realm de copia de seguridad por solicitud debería reutilizar una única instancia Chat desbloqueada entre solicitudes, o ejecutar un binding nativo donde se admitan blobs de clave.
La configuración de la copia de seguridad segura de claves acepta tres formas: el objeto juicebox_config de la X API (recomendado—pasado verbatim), un wrapper completo sdk_config o un token_map desnudo. Opcional: la verificación de firma está activada por defecto (reject_unverified = true)—llama a set_reject_unverified(false) para desactivarla (no recomendado); update_config si cambia la configuración de realms de copia de seguridad; is_unlocked / has_identity_key para el estado de la UI. Las listas completas de campos están en los stubs del repo chat-xdk.

Claves de conversación

Tres métodos prepare hacen que una sola llamada haga todo lo que un cambio de clave necesita: generar una nueva clave de conversación, cifrarla para cada participante (a partir de las claves públicas que pases) y firmar el cambio. Todos devuelven la misma forma PreparedConversationChange, lista para POST—renombra el campo del SDK encrypted_key a encrypted_conversation_key en conversation_participant_keys y mapea las firmas de acción al campo de cuerpo requerido action_signatures. Conserva los bytes de la clave en bruto para encrypt_message y multimedia; nunca pases el sobre cifrado de la API a encrypt.
Verifica las claves obtenidas antes de envolverlas. Los métodos prepare cifran la nueva clave de conversación hacia cualesquiera claves públicas que pases. Antes de pasarlas, llama a verify_key_binding(identity, signing, signature) en cada registro obtenido—sus campos public_key, signing_public_key e identity_public_key_signature de la API de claves públicas—para que una clave de identidad sustituida no pueda recibir la clave de conversación.
Usa extract_conversation_keys en los payloads de eventos de cambio de clave para reconstruir { keys, latest_version }. decrypt_conversation_key desenvuelve un solo blob ECIES.
Para crear grupo y agregar miembros, pasa los params que cada método necesita (listas de ids de miembros/admins para prepare_group_create; nuevos más el roster actual para prepare_group_members_change)—consulta Grupos para ejemplos. Ambos devuelven dos firmas de acción; el POST debe incluir ambas.

Descifrar

decrypt_events es para el historial y el backlog: extrae las claves de conversación del stream, devuelve los mensajes descifrados y recolecta errores por evento en lugar de fallar el lote completo. decrypt_event es para un solo evento en vivo cuando ya tienes un caché de claves; lanza excepción/throw ante un fallo. Pasa claves de firma para que el SDK pueda verificar a los remitentes. Mapea los campos de clave pública de la API a SigningKeyEntry: public_key_versionpublic_key_version (mismo nombre), signing_public_keypublic_key, public_keyidentity_public_key, más identity_public_key_signature y user_id. La verificación es obligatoria por defecto: omitir o pasar una lista vacía de claves de firma no la salta—los eventos firmados fallan (recolectados en errors para decrypt_events, lanzados para decrypt_event). Para realmente saltar la verificación primero debes llamar a set_reject_unverified(false) (no recomendado en producción).

Helpers de cifrado y envío

encrypt_message construye el texto cifrado firmado para un mensaje de texto (entidades opcionales, adjuntos vía media_hash_key, TTL, flags de notificación). Mapea el payload devuelto al cuerpo send-message: encrypted_contentencoded_message_create_event, encoded_event_signatureencoded_message_event_signature, más tu message_id. Usa encrypt_reply, encrypt_add_reaction y encrypt_remove_reaction para respuestas y reacciones (sequence_id apunta al padre). encrypt / decrypt son para metadatos UTF-8 bajo la clave de conversación (por ejemplo, un nombre de grupo cifrado)—no sobres de mensajes. encrypt_stream / decrypt_stream cifran los bytes de los adjuntos; consulta Multimedia. Los métodos de bajo nivel sign / verify / verify_key_binding admiten flujos avanzados; los cambios de clave de conversación, creaciones de grupo y adiciones de miembros son firmados por los métodos prepare. El id de conversación pasado a encrypt_message / encrypt_reply puede ser cualquier forma que tengas—A:B de eventos, A-B de listados o rutas URL (en cualquier orden) o solo el id de usuario del destinatario—el SDK lo canonicaliza antes de firmar. Los ids de grupo (con prefijo g) pasan sin cambios.

Streams de multimedia

Cifra los bytes del archivo con la misma clave de conversación usada para el texto, sube mediante las APIs de multimedia de Chat y adjunta media_hash_key en encrypt_message. Este no es el modelo de multimedia de Posts (expansions=attachments.media_keys). Flujo completo de subida/descarga: Multimedia.

Streaming incremental para multimedia grande

Para archivos grandes, evita mantener el payload completo en memoria: stream_encryptor() / stream_decryptor() devuelven un StreamEncryptor / StreamDecryptor al que alimentas por chunks (unos 1 MB cada uno) con push(chunk), y luego llamas a finish() una vez al final. Al descifrar, finish() detecta un stream truncado (falla si la entrada terminó antes del frame final), así que no trates el texto plano acumulado como completo hasta que tenga éxito.
Solo JS/WASM: finish() consume y libera el objeto WASM subyacente—nunca llames a free() después de finish() (lanza error). Llama a free() solo para abandonar un stream antes de finalizar (por ejemplo, en una ruta de error).

Utilidades

Los helpers de Base64/hex, sniffing de MIME y dimensiones de imagen están disponibles como funciones a nivel de módulo (Python/JS/Rust/Go) o ChatXdkUtilities (C#/Java)—útiles al construir metadatos de adjuntos sin traer librerías adicionales.

Tipos importantes

Estos tipos conceptuales aparecen en varios lenguajes (los nombres exactos de los campos difieren; JS suele usar discriminadores de evento en camelCase como message):
  • SendPayload — valor de retorno de encrypt_message y helpers de cifrado relacionados; mapea al cuerpo de envío de la Chat API.
  • PublicKeyRegistrationPayload — salida de generate_keypairs / getters de claves públicas para la API add-public-key.
  • SigningKeyEntry — material público del remitente pasado a decrypt para la verificación de firma.
  • PreparedConversationChange — salida de los tres métodos prepare: el conversation_id derivado o pasado, los bytes de conversation_key en bruto, conversation_key_version, participant_keys (user_id, encrypted_key, public_key_version) y action_signatures (message_id, encoded_message_event_detail, signature, signature_version, public_key_version, signature_payload opcional—omitido en firmas de cambio de clave porque ese payload incrusta la clave en texto plano).
  • DecryptEventsResult — mensajes, errores opcionales y conversation_keys extraídas.
Para listas completas de campos, usa los stubs de lenguaje en el repo chat-xdk (docs/API.md, *.pyi, index.d.ts).

Errores

Python normalmente lanza ValueError con un mensaje descriptivo (por ejemplo, un código de acceso inválido). TypeScript/JavaScript lanza Error. Go devuelve (value, error). Prefiere decrypt_events para el historial de modo que un evento defectuoso no aborte el lote; inspecciona la colección de errores para ver fallos parciales. Algunos errores de verificación son permanentes. Las firmas son inmutables y se verifican reconstruyendo el payload firmado desde el evento en sí, así que un evento antiguo que falla con signature missing or no matching signing key o un desajuste ECDSA fallará en cada carga futura—ninguna reintentación, actualización de claves o llamada a la API puede sanarlo. Trátalos como tombstones, no como errores transitorios. Rotar la clave de conversación inicia un historial limpio y verificable desde ese punto en adelante.

Próximos pasos

Primeros pasos

Conecta el Chat XDK a la Chat API

Multimedia

Cifrado por stream y REST de multimedia

Eventos en tiempo real

Webhooks y entrega de actividad

Solución de problemas

Fallos comunes