@chitchat/sdk-react-native 0.1.0-dev.0 → 0.1.0-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +117 -2
  2. package/package.json +4 -2
  3. package/src/index.js +11 -1
package/README.md CHANGED
@@ -1,5 +1,120 @@
1
1
  # ChitChat React Native SDK
2
2
 
3
- `createChitChatNativeClient` uses the official native TLS TCP bridge. The app developer supplies a session-token provider and imports the module; endpoint resolution, reconnects, durable outbox behavior, and TLS transport selection are handled by the SDK.
3
+ `@chitchat/sdk-react-native` connects a React Native application through a native TLS TCP transport and binary Protobuf frames. It is for iOS/Android native builds; it is not a browser SDK.
4
4
 
5
- The native bridge contract is deliberately small: `connect`, `onFrame`, `onClose`, `send`, and `close`. It is the location where Android/iOS certificate pinning and binary Protobuf framing are enforced.
5
+ This package is currently a **development prerelease**. Pin the version you have tested before shipping an application.
6
+
7
+ ## Read this before integrating
8
+
9
+ This JavaScript package needs a linked native bridge. You pass that bridge as `nativeModule`; the SDK does not secretly create TCP sockets in JavaScript.
10
+
11
+ For the current ChitChat app implementation, the bridge is exposed as `NativeModules.XMPPNativeModule` (with `NativeModules.XMPPNative` as a compatibility fallback). A third-party application must include the official ChitChat native bridge or implement the same documented bridge contract. The bridge must perform TLS validation, Protobuf framing, and certificate policy on iOS and Android.
12
+
13
+ **Expo Go cannot load custom native modules.** Use a development build or a prebuilt/bare React Native application, link the bridge, then rebuild iOS/Android.
14
+
15
+ ## 1. Install
16
+
17
+ ```bash
18
+ npm install @chitchat/sdk-core@development @chitchat/sdk-react-native@development
19
+
20
+ # iOS after installing native dependencies
21
+ npx pod-install ios
22
+ ```
23
+
24
+ You also need a backend session endpoint made with `@chitchat/sdk-server`. It returns a short-lived client token after authenticating the user in your own product. Do not embed a ChitChat API key in the app.
25
+
26
+ ## 2. Create the client
27
+
28
+ ```js
29
+ import { NativeModules } from 'react-native';
30
+ import { createBackendTokenProvider } from '@chitchat/sdk-core';
31
+ import { createChitChatNativeClient } from '@chitchat/sdk-react-native';
32
+
33
+ const nativeModule = NativeModules.XMPPNativeModule || NativeModules.XMPPNative;
34
+ if (!nativeModule) {
35
+ throw new Error('ChitChat native bridge is not linked; rebuild a development/native app.');
36
+ }
37
+
38
+ const tokenProvider = createBackendTokenProvider({
39
+ endpoint: 'https://api.example.com/api/chitchat/session',
40
+ getHeaders: () => ({ authorization: `Bearer ${getYourAppAccessToken()}` }),
41
+ getBody: () => ({ deviceId: getStableInstallationId() })
42
+ });
43
+
44
+ const client = createChitChatNativeClient({
45
+ // TLS TCP host and port only. It is not http://, https://, ws://, or wss://.
46
+ endpoint: 'realtime.example.com:5223',
47
+ tokenProvider,
48
+ nativeModule,
49
+ storage: durableNativeOutbox
50
+ });
51
+
52
+ client.on('connected', () => setRealtimeState('connected'));
53
+ client.on('message', (frame) => handleChitChatFrame(frame));
54
+ client.on('error', (error) => reportNonSensitiveRealtimeError(error));
55
+
56
+ await client.connect();
57
+ ```
58
+
59
+ On logout or account switch:
60
+
61
+ ```js
62
+ await client.close();
63
+ tokenProvider.invalidate();
64
+ ```
65
+
66
+ ## Native bridge contract
67
+
68
+ The supplied module must provide `connect`:
69
+
70
+ ```ts
71
+ type NativeBridge = {
72
+ connect(input: {
73
+ endpoint: string; // TLS host:port
74
+ token: string; // short-lived project-user session token
75
+ protocol: 'chitchat.protobuf.v1';
76
+ tls: true;
77
+ }): Promise<{
78
+ onFrame(listener: (frame: unknown) => void): void;
79
+ onClose(listener: (reason?: unknown) => void): void;
80
+ send(frame: unknown): Promise<void> | void;
81
+ close(): Promise<void> | void;
82
+ }>;
83
+ };
84
+ ```
85
+
86
+ The bridge must encode/decode the gateway’s actual generated Protobuf envelope and authenticate with the current protocol. Do not replace it with raw XML, JSON, or an unauthenticated TCP socket.
87
+
88
+ ## Durable outbox
89
+
90
+ The default core outbox is memory-only. To preserve queued messages when the app is restarted, pass a durable store with async `put(record)`, `remove(id)`, and `list()` methods. Use an encrypted/device-appropriate storage provider and return records sorted by `createdAt`.
91
+
92
+ ## TLS requirements
93
+
94
+ - Use a production hostname and certificate trusted by the actual iOS/Android device.
95
+ - The certificate subject/SAN must match the hostname passed in `endpoint`.
96
+ - Test on physical devices as well as simulators/emulators.
97
+ - Do not disable certificate validation to work around a development certificate error.
98
+ - For a local gateway, use a stable local hostname and install a trusted development CA in each test device. A changing LAN IP is not a production TLS identity.
99
+
100
+ ## Common problems
101
+
102
+ | Problem | Fix |
103
+ | --- | --- |
104
+ | `official ChitChat native TCP module is required` | Link/provide the native bridge and rebuild the app. Expo Go is not enough. |
105
+ | `TLS host:port endpoint is required` | Use `realtime.example.com:5223`; do not pass an HTTP or WebSocket URL. |
106
+ | iOS SSL / certificate error | Check the hostname, SAN, trusted CA, device time, and gateway certificate chain. |
107
+ | Repeated reconnects | Check token issuance/expiry, gateway reachability, bridge frame codec, and `error`/`reconnectFailed` events. |
108
+ | Queued messages disappear after restart | Provide durable `storage`; the default is memory-only. |
109
+
110
+ ## Security checklist
111
+
112
+ - Never put the ChitChat server API key in the mobile app, build configuration, or CI client logs.
113
+ - Fetch a short-lived session only from your authenticated backend over HTTPS.
114
+ - Close the realtime client on logout and account change.
115
+ - Keep the native bridge and generated Protobuf definitions versioned with the gateway protocol.
116
+ - Do not log tokens, message bodies, user identifiers, or raw binary frames.
117
+
118
+ ## Current scope
119
+
120
+ This package provides the React Native client lifecycle and native transport adapter boundary. Call UI, CallKit/ConnectionService, push wake-up, ringtone, WebRTC media, meetings, streaming, notifications, and agents are separate platform features and must be integrated and tested before release.
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@chitchat/sdk-react-native",
3
- "version": "0.1.0-dev.0",
3
+ "version": "0.1.0-dev.2",
4
4
  "main": "src/index.js",
5
+ "exports": "./src/index.js",
5
6
  "files": ["src", "README.md", "LICENSE"],
6
7
  "engines": { "node": ">=18" },
7
- "dependencies": { "@chitchat/sdk-core": "0.1.0-dev.0" },
8
+ "scripts": { "test": "node test/transport.test.js" },
9
+ "dependencies": { "@chitchat/sdk-core": "0.1.0-dev.2" },
8
10
  "license": "UNLICENSED",
9
11
  "publishConfig": { "access": "public", "tag": "development" }
10
12
  }
package/src/index.js CHANGED
@@ -3,9 +3,19 @@
3
3
  let ReliableRealtimeClient;
4
4
  try { ({ ReliableRealtimeClient } = require('@chitchat/sdk-core')); } catch (_) { ({ ReliableRealtimeClient } = require('../../chitchat-core/src')); }
5
5
 
6
+ const validateNativeTlsEndpoint = (endpoint) => {
7
+ if (typeof endpoint !== 'string' || !endpoint.trim() || /\s/.test(endpoint)) throw new Error('A TLS host:port endpoint is required');
8
+ if (/^(https?|wss?):\/\//i.test(endpoint)) throw new Error('React Native realtime requires a TLS TCP host:port endpoint, not a HTTP/WebSocket URL');
9
+ let parsed;
10
+ try { parsed = new URL(`tls://${endpoint}`); } catch (_) { throw new Error('A valid TLS host:port endpoint is required'); }
11
+ if (!parsed.hostname || !parsed.port || Number(parsed.port) < 1 || Number(parsed.port) > 65535 || parsed.username || parsed.password || (parsed.pathname && parsed.pathname !== '/')) throw new Error('A valid TLS host:port endpoint is required');
12
+ return endpoint;
13
+ };
14
+
6
15
  const createNativeTcpTransportFactory = ({ nativeModule }) => {
7
16
  if (!nativeModule || typeof nativeModule.connect !== 'function') throw new Error('The official ChitChat native TCP module is required');
8
17
  return async ({ endpoint, token, protocol }) => {
18
+ validateNativeTlsEndpoint(endpoint);
9
19
  let connection; let onMessage = () => {}; let onClose = () => {};
10
20
  return {
11
21
  onMessage: (listener) => { onMessage = listener; },
@@ -23,4 +33,4 @@ const createNativeTcpTransportFactory = ({ nativeModule }) => {
23
33
 
24
34
  const createChitChatNativeClient = ({ endpoint, tokenProvider, nativeModule, ...options }) => new ReliableRealtimeClient({ endpoint, tokenProvider, runtime: 'native', nativeTransportFactory: createNativeTcpTransportFactory({ nativeModule }), ...options });
25
35
 
26
- module.exports = { createChitChatNativeClient, createNativeTcpTransportFactory };
36
+ module.exports = { createChitChatNativeClient, createNativeTcpTransportFactory, validateNativeTlsEndpoint };