npm package: @notmeta/chat-sdk
Description: TITO Chat SDK - Secure messaging for your apps
Latest version: 0.1.1

# @notmeta/chat-sdk

Secure, cross-app messaging SDK with end-to-end encryption.

## Features

- **E2EE** - End-to-end encryption using Olm/Megolm (Signal Protocol compatible)
- **Cross-App** - Users can discover and message across Gigalicious, Our Resistance, and Tru Local
- **Drop-in Replacement** - Hooks mirror Supabase chat interface for easy migration
- **Real-time** - Live updates for messages, typing indicators, and presence

## Installation

```bash
npm install @notmeta/chat-sdk
# or
yarn add @notmeta/chat-sdk
```

## Quick Start

### 1. Wrap your app with TitoProvider

```tsx
import { TitoProvider } from '@notmeta/chat-sdk';

function App() {
  return (
    <TitoProvider
      config={{
        homeserver: 'https://thisistheother.chat',
        appNamespace: 'giga', // or 'or', 'trulocal'
      }}
      credentials={titoCredentials} // Get from auth bridge
    >
      <YourApp />
    </TitoProvider>
  );
}
```

### 2. Use hooks in your components

```tsx
import { useTitoRoom } from '@notmeta/chat-sdk';

function GigChat({ gigId }) {
  const {
    messages,
    sendMessage,
    typingUsers,
    setTyping,
    isLoading,
  } = useTitoRoom(gigId);

  // Same interface as your Supabase hooks!
  return (
    <div>
      {messages.map((msg) => (
        <Message key={msg.id} message={msg} />
      ))}
    </div>
  );
}
```

## Migration from Supabase

### Before (Supabase)

```tsx
import { useGigChat } from './hooks/useGigChat';

function Chat({ gigId }) {
  const { messages, sendMessage } = useGigChat(gigId);
  // ...
}
```

### After (TITO)

```tsx
import { useTitoRoom } from '@notmeta/chat-sdk';

function Chat({ gigId }) {
  const { messages, sendMessage } = useTitoRoom(gigId);
  // Same interface - just swap the import!
}
```

## Auth Bridge

Connect your existing auth system to TITO:

```tsx
// In your auth flow (after Supabase login)
import { getTitoCredentials } from '@notmeta/chat-sdk';

async function onLogin(supabaseUser) {
  const titoCredentials = await getTitoCredentials(
    supabaseUser.id,
    supabaseUser.access_token,
    {
      homeserver: 'https://thisistheother.chat',
      appNamespace: 'giga',
    }
  );

  // Store credentials and pass to TitoProvider
  localStorage.setItem('tito_credentials', JSON.stringify(titoCredentials));
}
```

## Hooks Reference

### useTitoRoom(roomId)

Group chat functionality.

```tsx
const {
  messages,        // ChatMessage[]
  isLoading,       // boolean
  error,           // Error | null
  sendMessage,     // (content, imageUrl?, replyToId?) => Promise<void>
  deleteMessage,   // (messageId) => Promise<void>
  typingUsers,     // TypingUser[]
  setTyping,       // (isTyping) => void
  markAsRead,      // () => void
  loadMore,        // () => Promise<void>
  hasMore,         // boolean
} = useTitoRoom(roomId);
```

### useTitoDM()

Direct messages.

```tsx
const {
  conversations,      // DMConversation[]
  isLoading,          // boolean
  error,              // Error | null
  startConversation,  // (userId) => Promise<roomId>
  deleteConversation, // (conversationId) => Promise<void>
} = useTitoDM();
```

### useTitoReactions(roomId)

Message reactions.

```tsx
const {
  addReaction,    // (messageId, emoji) => Promise<void>
  removeReaction, // (messageId, reactionEventId) => Promise<void>
} = useTitoReactions(roomId);
```

### useTitoSearch()

Cross-app user search.

```tsx
const {
  searchUsers, // (query) => Promise<ChatUser[]>
  isSearching, // boolean
} = useTitoSearch();

// Find users across all apps!
const results = await searchUsers('kelly');
// Returns users from Giga, OR, Tru Local, etc.
```

## Cross-App Discovery

Users can discover each other across apps:

```tsx
import { parseUserId, getAppBadge } from '@notmeta/chat-sdk';

function UserCard({ userId }) {
  const { username, app } = parseUserId(userId);
  const badge = getAppBadge(userId);

  return (
    <div>
      <span>{username}</span>
      {badge && (
        <span style={{ color: badge.color }}>
          {badge.name}
        </span>
      )}
    </div>
  );
}

// @kelly:giga.thisistheother.chat -> "kelly" with "Gigalicious" badge
// @sam:or.thisistheother.chat -> "sam" with "Our Resistance" badge
```

## Types

```tsx
interface ChatMessage {
  id: string;
  room_id: string;
  sender_id: string;
  sender: ChatUser;
  content: string;
  image_url: string | null;
  reply_to_id: string | null;
  reply_to: ChatMessage | null;
  is_deleted: boolean;
  created_at: string;
  reactions: MessageReaction[];
}

interface ChatUser {
  id: string;
  username: string;
  display_name: string | null;
  avatar_url: string | null;
}
```

## Security

- All messages are encrypted end-to-end using Olm/Megolm
- Based on the Signal Protocol (same as WhatsApp)
- Keys are stored locally on each device
- Server never sees message content