@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.
- package/README.md +117 -2
- package/package.json +4 -2
- package/src/index.js +11 -1
package/README.md
CHANGED
|
@@ -1,5 +1,120 @@
|
|
|
1
1
|
# ChitChat React Native SDK
|
|
2
2
|
|
|
3
|
-
`
|
|
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
|
-
|
|
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.
|
|
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
|
-
"
|
|
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 };
|