feat(xchat): add XChat encrypted messaging adapter - #745
Conversation
New @chat-adapter/xchat package for XChat, X's encrypted messaging. All cryptography is handled inside the adapter via @xdevplatform/chat-xdk (wasm) and all REST goes through the typed @xdevplatform/xdk client. The adapter implements the standard Adapter interface only — no core changes.
|
@santiagomed is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Only one changeset file is needed, please combine both of them. The content can be trimmed as well.
| "@xdevplatform/chat-xdk": "^0.4.3", | ||
| "@xdevplatform/xdk": "^0.6.6", | ||
| "chat": "workspace:*", | ||
| "juicebox-sdk": "^0.3.6" |
There was a problem hiding this comment.
Is Juicebox SDK strictly required? The package appears to have minimal traction, posing a potential security risk for users who integrate this adapter with their Chat SDK app.
There was a problem hiding this comment.
Yes, the X Chat integration will not work without it as it's part of the protocol unfortunately. It's what we use to manage private keys securely. Our native clients also rely on it
There was a problem hiding this comment.
While a README is included, the adapter is missing other documentation, including for the website. Additionally, catalog files will need to be updated so this adapter is surfaced in the create-chat-sdk CLI.
- Rename exported identifiers to Xchat casing (XchatAdapter, createXchatAdapter, XchatAdapterConfig, and secondary types) so the konsistent check passes; the factory now takes the exported XchatAdapterConfig like the other adapters - Normalize the conversation id to the dash-joined form on the media upload initialize/append/finalize bodies - Combine the two changesets into one
Adds the official docs page with OG image, the adapters.json registry entry, the chat/adapters catalog entry, and the create-chat-sdk scaffold spec, modeled on the x adapter's registration.
…ured userId (and XCHAT_USER_ID / X_USER_ID) becomes optional: initialize() resolves the id and @handle from a single GET /2/users/me call when either is missing, so the only required credentials are the token and the PIN.
The bot's identity is fully determined by the token, so the userId config field and the XCHAT_USER_ID / X_USER_ID env vars are gone; initialize() always resolves the id and @handle from GET /2/users/me. The only required credentials are the bot token and the Juicebox PIN. Also relabels the OG image row as X Chat.
The adapter prepends chat-sdk-xchat/<version> to the xdk client's User-Agent (which already carries xdk-typescript/<version>), so X API request logs can distinguish Chat SDK traffic from other xdk usage. A User-Agent supplied via apiHeaders takes precedence and is left untouched.
summary
new
@chat-adapter/xchatadapter for XChat, X's encrypted messaging. write bot logic once and hold encrypted 1:1 and group conversations like the other Chat SDK adapters — all crypto handled inside the adapter via@xdevplatform/chat-xdk(wasm), all REST via the typed@xdevplatform/xdkclient.background: chat-xdk
@xdevplatform/chat-xdkis the official XChat cryptography SDK — a Rust core compiled to WebAssembly that implements the XChat encryption protocol. it handles per-conversation symmetric keys and key exchange, message encryption/decryption, event signing and signature verification, and encrypted media (secretstream). the bot's private keys live in a PIN-protected Juicebox store (secret-shared across independent realms), so no key material sits in env vars or on disk — the adapter unlocks with a PIN at startup. this adapter is the glue: chat-xdk produces and consumes the encrypted envelopes, the typed@xdevplatform/xdkclient moves them over the X API, and everything is normalized to the Chat SDK'sThread/Messagemodel.what it supports:
@handlefallback; group replies go out as quoted replies with TTL propagatedopenDM(userId): starts (or reuses) an encrypted 1:1 — cached/history-recovered conversation key, else a full key exchange so the bot can message firstsendReadReceipts, default on)label: urllines, primary link as a URL preview attachment with optional encrypted bannerkey design decisions:
xchat:{conversationId}(groupsg…, 1:1s the sorted participant pair)editSafetyDelayMs, default 5000ms): receiving clients park an edit whose original hasn't arrived, leaving the message permanently invisible — the gate prevents that raceAdapterinterface onlyalso includes the
chat/adapterscatalog entry, docs page (with OG image),adapters.jsonregistry entry, andcreate-chat-sdkscaffold spec, modeled on thexadapter's registration.usage
testing: 109 unit tests, including real-wasm-crypto round trips against vendored fixture vectors (decrypt + signature verification, webhook delivery, read receipts, edit age-gating, signed deletes). verified live against production XChat: DMs, group mentions, media, reactions, edits, deletes, openDM, cards.
note on the lockfile:
@xdevplatform/xdk@0.6.6was published <48h ago, so it was resolved with a one-shot--config.minimumReleaseAge=0override; the locked integrity hash was verified against the npm registry. the repo policy file is untouched.