Minimal chat SDK for Expo apps to connect to OpenClaw gateway.

A picture is worth a thousand words.
npm install expo-openclaw-chat
import { createChat } from "expo-openclaw-chat";
// Create chat instance
const chat = createChat({
gatewayUrl: "wss://your-gateway.example.com",
token: "your-auth-token", // or use password/deviceToken
});
// Wrap your app with ChatProvider
function App() {
return (
<chat.ChatProvider>
<YourApp />
</chat.ChatProvider>
);
}
// Open chat modal from anywhere
chat.open();
// Close chat modal
chat.close();
createChat({
// Required
gatewayUrl: string; // WebSocket URL (wss:// or ws://)
// Authentication (pick one)
token?: string; // Simple auth token
password?: string; // Password auth
deviceToken?: string; // Device token from pairing
// Optional
sessionKey?: string; // Chat session key (auto-generated if not provided)
title?: string; // Modal title (default: "Chat")
placeholder?: string; // Input placeholder text
showImagePicker?: boolean; // Show image picker button (requires expo-image-picker)
clientId?: string; // Client ID for gateway registration
// Callbacks
onOpen?: () => void; // Called when modal opens
onClose?: () => void; // Called when modal closes
// Storage
storage?: Storage; // Custom storage for device identity
});
Install these for additional features:
# Image attachments
npm install expo-image-picker
# Markdown rendering
npm install react-native-marked
# Secure private key storage (Keychain)
npm install expo-secure-store
# Persistent device identity (recommended)
npm install react-native-mmkv
The SDK automatically generates an Ed25519 key pair for device authentication. When expo-secure-store is installed, the private key is stored in the OS Keychain (Secure Enclave on iOS). Without it, keys are stored in memory or MMKV and regenerate on app restart.
For persistent identity across restarts, install both:
npm install expo-secure-store react-native-mmkv
Then configure MMKV as the storage backend:
import { setStorage } from "expo-openclaw-chat";
import { MMKV } from "react-native-mmkv";
const storage = new MMKV({ id: "my-app" });
setStorage(storage);
import {
GatewayClient,
ChatEngine,
ChatModal,
ChatList,
ChatBubble,
ChatInput
} from "expo-openclaw-chat";
// Create client manually
const client = new GatewayClient("wss://gateway.example.com", {
token: "your-token",
});
// Connect
await client.connect();
// Create chat engine
const engine = new ChatEngine(client, "session-key");
// Listen for updates
engine.on("update", () => {
console.log("Messages:", engine.messages);
});
// Send a message
await engine.send("Hello!");
const models = await client.modelsList();
console.log(models.models); // [{ key, name, available, ... }]
import {
GatewayClient,
GatewayError,
generateIdempotencyKey,
loadOrCreateIdentity,
} from "expo-openclaw-chat";
See the demo folder for a complete example.
https://github.com/user-attachments/assets/69316dca-5bbf-42b7-93b9-fa9bc3bbc5f5
MIT
$ claude mcp add expo-openclaw-chat \
-- python -m otcore.mcp_server <graph>