@ethora/chat-component 25.12.2 → 26.1.1

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 (49) hide show
  1. package/README.md +587 -145
  2. package/dist/components/MainComponents/MessageContainer.d.ts +1 -0
  3. package/dist/components/MessageBubble/MessageReply.d.ts +2 -2
  4. package/dist/components/MessageNotification/MessageNotificationToast.d.ts +17 -0
  5. package/dist/components/MessageNotification/index.d.ts +2 -0
  6. package/dist/components/Modals/SettingsModals/SharedStyledComponents.d.ts +22 -0
  7. package/dist/components/Modals/styledModalComponents.d.ts +28 -0
  8. package/dist/components/styled/Button.d.ts +2 -2
  9. package/dist/components/styled/DateLabel.d.ts +2 -2
  10. package/dist/components/styled/StyledComponents.d.ts +10 -10
  11. package/dist/components/styled/StyledInputComponents/StyledInputComponents.d.ts +6 -6
  12. package/dist/context/MessageNotificationContext.d.ts +12 -0
  13. package/dist/firebase-config.d.ts +6 -2
  14. package/dist/firebase-messaging-sw.js +351 -0
  15. package/dist/helpers/getDataFromXml.d.ts +1 -0
  16. package/dist/helpers/initRoomsPresence.d.ts +1 -1
  17. package/dist/helpers/storeConsole.d.ts +6 -0
  18. package/dist/hooks/useInAppNotifications.d.ts +18 -0
  19. package/dist/hooks/usePushNotifications.d.ts +45 -0
  20. package/dist/hooks/useTabVisibility.d.ts +1 -0
  21. package/dist/main.css +1 -1
  22. package/dist/main.d.ts +5 -0
  23. package/dist/main.js +14686 -11893
  24. package/dist/main.js.map +1 -1
  25. package/dist/networking/api-requests/push.api.d.ts +18 -0
  26. package/dist/networking/stanzaHandlers.d.ts +4 -2
  27. package/dist/networking/xmpp/allRoomPresences.xmpp.d.ts +11 -1
  28. package/dist/networking/xmpp/presenceInRoom.xmpp.d.ts +1 -1
  29. package/dist/networking/xmpp/sendTextMessage.xmpp.d.ts +1 -1
  30. package/dist/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +1 -1
  31. package/dist/networking/xmpp/subscribeToRoomMessages.xmpp.d.ts +9 -0
  32. package/dist/networking/xmppClient.d.ts +13 -3
  33. package/dist/roomStore/chatSettingsSlice.d.ts +1 -0
  34. package/dist/roomStore/index.d.ts +28 -0
  35. package/dist/roomStore/roomHeapSlice.d.ts +1 -1
  36. package/dist/roomStore/roomsSlice.d.ts +11 -1
  37. package/dist/types/models/config.model.d.ts +35 -1
  38. package/dist/types/models/room.model.d.ts +4 -1
  39. package/dist/types/models/xmpp.model.d.ts +3 -1
  40. package/dist/utils/firebasePushNotifications.d.ts +34 -0
  41. package/dist/utils/formatError.d.ts +1 -0
  42. package/dist/utils/messageNotificationManager.d.ts +16 -0
  43. package/dist/utils/notificationPolicy.d.ts +45 -0
  44. package/dist/utils/notificationUtils.d.ts +22 -0
  45. package/dist/utils/pushSubscriptionService.d.ts +12 -0
  46. package/dist/version.d.ts +1 -1
  47. package/package.json +7 -4
  48. package/public/firebase-messaging-sw.js +351 -0
  49. package/scripts/init-push.js +48 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Ethora Chat Component: a single npm for your React chat
1
+ # Ethora Chat Component (`@ethora/chat-component`)
2
2
 
3
3
  ![GitHub watchers](https://img.shields.io/github/watchers/dappros/ethora-chat-component) ![GitHub forks](https://img.shields.io/github/forks/dappros/ethora-chat-component) ![GitHub Repo stars](https://img.shields.io/github/stars/dappros/ethora-chat-component) ![GitHub repo size](https://img.shields.io/github/repo-size/dappros/ethora-chat-component) ![GitHub language count](https://img.shields.io/github/languages/count/dappros/ethora-chat-component) ![GitHub top language](https://img.shields.io/github/languages/top/dappros/ethora-chat-component) <a href="https://codeclimate.com/github/dappros/ethora-chat-component/maintainability"><img src="https://api.codeclimate.com/v1/badges/715c6f3ffb08de5ca621/maintainability" /></a> ![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/dappros/ethora-chat-component/main) ![GitHub issues](https://img.shields.io/github/issues/dappros/ethora-chat-component) ![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/dappros/ethora-chat-component) ![GitHub](https://img.shields.io/github/license/dappros/ethora-chat-component) ![GitHub contributors](https://img.shields.io/github/contributors/dappros/ethora-chat-component)
4
4
 
@@ -7,221 +7,663 @@
7
7
 
8
8
  [![Discord](https://img.shields.io/badge/%3Cethora%3E-%237289DA.svg?style=flat&logo=discord&logoColor=white)](https://discord.gg/Sm6bAHA3ZC) [![Twitter URL](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2Fdappros%2Fethora)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fdappros%2Fethora%2F&via=tarasfilatov&text=check%20out%20Ethora%20%23web3%20%23social%20app%20engine&hashtags=lowcode%2Creactnative%2Copensource%2Cnocode) [![Website](https://img.shields.io/website?url=https%3A%2F%2Fethora.com%2F)](https://ethora.com/) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCRvrXwMOU0WBkRZyFlU7V_g)](https://www.youtube.com/channel/UCRvrXwMOU0WBkRZyFlU7V_g)
9
9
 
10
- ## About Chat Component
10
+ React + TypeScript chat UI component powered by Ethora backend APIs and XMPP.
11
+ Use it as a standalone chat page, as an embedded widget in your existing app, or as a customizable chat foundation with your own auth and UI.
12
+
13
+ ## Table of Contents
14
+
15
+ - [Overview](#overview)
16
+ - [Why Ethora](#why-ethora)
17
+ - [Quick Start](#quick-start)
18
+ - [Integration Modes](#integration-modes)
19
+ - [Behavior Notes and Legacy Quirks](#behavior-notes-and-legacy-quirks)
20
+ - [Chat Props Reference](#chat-props-reference)
21
+ - [Full Config Reference (`IConfig`)](#full-config-reference-iconfig)
22
+ - [Custom Widgets and Overrides](#custom-widgets-and-overrides)
23
+ - [Push Notifications](#push-notifications)
24
+ - [Auth Strategies](#auth-strategies)
25
+ - [Hooks and API Exports](#hooks-and-api-exports)
26
+ - [Use Cases and Feature Coverage](#use-cases-and-feature-coverage)
27
+ - [Hosted vs Self-Host Guidance](#hosted-vs-self-host-guidance)
28
+ - [Security Notes](#security-notes)
29
+ - [Reference Architectures](#reference-architectures)
30
+ - [Use-Case Templates](#use-case-templates)
31
+ - [Feature Roadmap Snapshot](#feature-roadmap-snapshot)
32
+ - [Troubleshooting](#troubleshooting)
33
+ - [Ethora Links and Support](#ethora-links-and-support)
34
+
35
+ ## Overview
36
+
37
+ `@ethora/chat-component` gives you a production-oriented chat interface with:
38
+
39
+ - Room list and room chat UI
40
+ - Message history, replies, reactions, edits, deletes
41
+ - Typing indicators
42
+ - In-app notifications + Web Push integration
43
+ - Configurable auth modes (default/login form/google/jwt/custom user)
44
+ - Custom render components for message/input/scroll/day separator/new-message label
45
+
46
+ The package exports:
47
+
48
+ - `Chat` (main component)
49
+ - `XmppProvider`
50
+ - `useUnread`
51
+ - `logoutService`
52
+ - `useQRCodeChat`, `handleQRChatId`
53
+ - `useInAppNotifications`
54
+ - `usePushNotifications`
55
+ - `resendMessage`
56
+
57
+ ## Why Ethora
58
+
59
+ Ethora provides hosted and customizable messaging infrastructure plus a wider product ecosystem.
60
+
61
+ | Dimension | Ethora Chat Component | Full Ethora Platform |
62
+ | --- | --- | --- |
63
+ | Primary goal | Embed chat quickly in a React app | End-to-end product stack (chat, profiles, wallets, AI, admin) |
64
+ | Time to first chat | Minutes | Higher initial setup, broader capabilities |
65
+ | Frontend scope | Focused web chat UI package | Multi-product ecosystem and broader SDK/tooling |
66
+ | Custom UI control | High via props + custom components | High, with additional platform-specific tooling |
67
+ | Best fit | Support chat, portal messaging, embedded chat widget | Full social/messaging app platforms with extended modules |
68
+
69
+ ## Quick Start
70
+
71
+ ### 1. Install
72
+
73
+ | Tool | Command |
74
+ | --- | --- |
75
+ | npm | `npm i @ethora/chat-component` |
76
+ | yarn | `yarn add @ethora/chat-component` |
77
+ | pnpm | `pnpm add @ethora/chat-component` |
78
+ | bun | `bun add @ethora/chat-component` |
79
+
80
+ ### 2. Render the chat
81
+
82
+ ```tsx
83
+ import { Chat, XmppProvider } from '@ethora/chat-component';
84
+ import './App.css';
85
+
86
+ export default function App() {
87
+ return (
88
+ <XmppProvider>
89
+ <Chat />
90
+ </XmppProvider>
91
+ );
92
+ }
93
+ ```
11
94
 
12
- Ethora Chat Component allows you to build a functioning chat room super quickly.
13
- Sounds simple and is easy to build your app with.
14
- Uses XMPP chat protocol and ejabberd chat server to provide your users with a seamless instant messaging experience.
95
+ ### Required wrapper (`XmppProvider`)
15
96
 
16
- Once you need more functionality however you will be pleasantly surprised. Our Ethora platform behind the chat component offers a plethora of functionalities around chat/social, user profiles, digital wallets, business documents exchange, digital collectables, web3 and AI bots. The history behind Chat Component is following. First, we have built a low-code “super app” engine called Ethora: https://github.com/dappros/ethora/ which we used to drastically speed up app development for our clients. Afterwards, we have open-sourced it for the benefit of other developers. Later on, we realized that whilst developers love what Ethora can do, many of them don’t need such a complex engine with all bells and whistles but a steep learning curver. In most cases you’re after a certain functionality (like a simple chat room) and you need it quick.
97
+ `Chat` relies on internals that use `useXmppClient()`. In real integrations, wrap `Chat` (or your entire app shell) with `XmppProvider`:
17
98
 
18
- Enter Ethora Chat Component which allows you to quickly implement your chat room experience!
99
+ ```tsx
100
+ import { Chat, XmppProvider } from '@ethora/chat-component';
19
101
 
20
- If / once you need additional functionalities you will have options like: (a) build them yourself on top of chat component; (b) peek into or use code from Ethora open-source monorepo https://github.com/dappros/ethora/ or (c) seek help from Ethora team or other developers at our forum: https://forum.ethora.com/ or Discord server: https://discord.gg/Sm6bAHA3ZC
102
+ export default function App() {
103
+ return (
104
+ <XmppProvider>
105
+ <Chat config={{ baseUrl: 'https://api.ethoradev.com/v1' }} />
106
+ </XmppProvider>
107
+ );
108
+ }
109
+ ```
21
110
 
22
- Note: scroll below for use cases and functionality break down of this Chat Component.
111
+ ### 3. Run
23
112
 
24
- ## How to build your chat room in 5 minutes
113
+ ```bash
114
+ npm run dev
115
+ ```
25
116
 
26
- 1. npm create vite@latest
27
- 2. specify a name for your project (e.g. "vite-project")
28
- 3. select framework and variant (for example, React -> Typescript but may be different depending on your project requirements, it will work with plain Javascript too)
117
+ Open `http://localhost:5173`.
29
118
 
30
- <img src="https://github.com/dappros/ethora-chat-component/blob/main/img/readme01.png" width="500" />
119
+ Static reference screenshots:
31
120
 
32
- <img src="https://github.com/dappros/ethora-chat-component/blob/main/img/readme02.png" width="500" />
121
+ ![Quick setup step 1](./img/readme01.png)
122
+ ![Quick setup step 2](./img/readme02.png)
123
+ ![Chat initial view](./img/readme03.png)
33
124
 
34
- 4. cd vite-project _(use your name instead of "vite-project")_
35
- 5. npm i
36
- 6. npm i @ethora/chat-component
37
- 7. go to file src/App.tsx and replace it with the below code
125
+ ### GIF placeholders (manual replacement)
38
126
 
39
- ```
40
- import { Chat } from "@ethora/chat-component";
41
- import "./App.css";
127
+ Replace each path with your recorded GIF file.
42
128
 
43
- function App() {
44
- return (
45
- <Chat />
46
- );
47
- }
129
+ 1. Install + first render
130
+ Target file: `img/placeholder-01-install-first-render.gif`
131
+ ![GIF Placeholder: Install + first render](./img/placeholder-01-install-first-render.gif)
48
132
 
49
- export default App;
50
- ```
133
+ 2. Login/auth flow
134
+ Target file: `img/placeholder-02-login-auth-flow.gif`
135
+ ![GIF Placeholder: Login/auth flow](./img/placeholder-02-login-auth-flow.gif)
51
136
 
52
- 7. run like this
137
+ 3. Room switching + messaging
138
+ Target file: `img/placeholder-03-room-switching-messaging.gif`
139
+ ![GIF Placeholder: Room switching + messaging](./img/placeholder-03-room-switching-messaging.gif)
53
140
 
54
- ```
55
- npm run dev
56
- ```
141
+ 4. Push prompt + receive flow
142
+ Target file: `img/placeholder-04-push-flow.gif`
143
+ ![GIF Placeholder: Push notification flow](./img/placeholder-04-push-flow.gif)
57
144
 
58
- you should see something like this:
59
- <br /><img src="https://github.com/dappros/ethora-chat-component/blob/main/img/readme03.png" width="350" />
145
+ 5. Widget customization before/after
146
+ Target file: `img/placeholder-05-widget-customization.gif`
147
+ ![GIF Placeholder: Widget customization](./img/placeholder-05-widget-customization.gif)
60
148
 
61
- 8. Open http://localhost:5173/ in your browser
149
+ 6. Mobile responsive behavior
150
+ Target file: `img/placeholder-06-mobile-responsive.gif`
151
+ ![GIF Placeholder: Mobile responsive behavior](./img/placeholder-06-mobile-responsive.gif)
62
152
 
63
- Voilà - your chat app should work like so:
153
+ ## Integration Modes
64
154
 
65
- <img src="https://github.com/dappros/ethora-chat-component/blob/main/img/readme_animation.gif" width="860" />
155
+ All modes below assume `XmppProvider` wraps `Chat`.
66
156
 
67
- ℹ️ Note: your Ethora App, User and Chat credentials are hard-coded and login screen is bypassed. This is done so that you can scaffold and test the functionality quickly.
68
- Leave this as is if you only need to demo or validate the chat functionality as part of your project.
69
- If you need to have your own private chats, be able to login multiple users etc then go to https://www.ethora.com/, sign up in the top right which gives you a free account with Ethora backend where you can create your own App, manage your Users and Chats, view stats etc. Copy App ID & App Secret to your chat component code which will then switch to your own App context on the server side. The free tier is generous but should you need extra you can later build your own backend, upgrade to a paid tier from Ethora or use a self-hosted AWS marketplace image from Ethora.
157
+ ### A) Minimal demo mode (provider + chat)
70
158
 
71
- ## Extra options (styling etc)
159
+ ```tsx
160
+ <XmppProvider>
161
+ <Chat />
162
+ </XmppProvider>
163
+ ```
72
164
 
73
- To create custom chat room styles in **App.tsx**:
165
+ Useful for local proof-of-concept and quick UI validation.
74
166
 
75
- replace
167
+ ### B) Auto default credential fallback (legacy behavior)
76
168
 
77
- ```
78
- <Chat />
169
+ If no `googleLogin`, no `jwtLogin`, no `userLogin`, and no `defaultLogin`, `LoginWrapper` currently triggers internal email/password fallback logic.
170
+
171
+ ```tsx
172
+ <XmppProvider>
173
+ <Chat config={{ colors: { primary: '#2563eb', secondary: '#dbeafe' } }} />
174
+ </XmppProvider>
79
175
  ```
80
176
 
81
- with:
177
+ ### C) Explicit email/password via `user` prop
82
178
 
179
+ ```tsx
180
+ <XmppProvider>
181
+ <Chat
182
+ user={{
183
+ email: 'user@example.com',
184
+ password: 'PLACEHOLDER_PASSWORD',
185
+ }}
186
+ />
187
+ </XmppProvider>
83
188
  ```
84
- <Chat
189
+
190
+ ### D) Injected logged-in user (`userLogin`)
191
+
192
+ ```tsx
193
+ <XmppProvider>
194
+ <Chat
85
195
  config={{
86
- disableHeader: true,
87
- disableMedia: true,
88
- colors: { primary: "#4287f5", secondary: "#42f5e9" },
89
- defaultLogin=true
90
- googleLogin: {
91
- firebaseConfig: config, //Ethora app config
92
- enabled: true,
93
- },
196
+ userLogin: {
197
+ enabled: true,
198
+ user: {
199
+ _id: 'PLACEHOLDER_USER_ID',
200
+ appId: 'PLACEHOLDER_APP_ID',
201
+ walletAddress: 'PLACEHOLDER_WALLET_ADDRESS',
202
+ defaultWallet: { walletAddress: 'PLACEHOLDER_WALLET_ADDRESS' },
203
+ firstName: 'Jane',
204
+ lastName: 'Doe',
205
+ xmppPassword: 'PLACEHOLDER_XMPP_PASSWORD',
206
+ token: 'PLACEHOLDER_ACCESS_TOKEN',
207
+ refreshToken: 'PLACEHOLDER_REFRESH_TOKEN',
208
+ username: 'PLACEHOLDER_USERNAME',
209
+ },
210
+ },
94
211
  }}
95
- MainComponentStyles={{
96
- width: "100%",
97
- height: "500px",
98
- borderRadius: "16px",
99
- border: "1px solid #42f5e9",
212
+ />
213
+ </XmppProvider>
214
+ ```
215
+
216
+ ### E) JWT login
217
+
218
+ ```tsx
219
+ <XmppProvider>
220
+ <Chat
221
+ config={{
222
+ jwtLogin: {
223
+ enabled: true,
224
+ token: 'PLACEHOLDER_JWT_TOKEN',
225
+ },
100
226
  }}
101
- roomJID=""
102
- user={{ email: "", password: "" }}
103
- disableHeader?: boolean;
104
-
105
- disableRooms: boolean;
106
- defaultLogin: boolean;
107
- disableInteractions: boolean; //disable interactions
108
- chatHeaderBurgerMenu: boolean; // disable burger menu in room header
109
- roomListStyles: React.CSSProperties; // used to change room List styles (left)
110
- chatRoomStyles: React.CSSProperties; // used to change room styles (right)
111
- setRoomJidInPath: boolean; // used to set RoomId to url
112
227
  />
228
+ </XmppProvider>
113
229
  ```
114
230
 
115
- ℹ️ Note: Add room and user which are registered at Ethora. After these changes - the pre-written user & room will be changed to yours.
231
+ ### F) Google login
116
232
 
117
- ℹ️ Note:
118
- There is also a prop CustomMessageComponent: React.ComponentType<MessageProps>
119
- This prop is used to fully change styles of messageBubble.
120
- You can find an example here: https://github.com/dappros/ethora-chat-component/blob/main/src/components/ExampleComponents/CustomMessage.tsx
233
+ ```tsx
234
+ <XmppProvider>
235
+ <Chat
236
+ config={{
237
+ googleLogin: {
238
+ enabled: true,
239
+ firebaseConfig: {
240
+ apiKey: 'PLACEHOLDER_API_KEY',
241
+ authDomain: 'PLACEHOLDER_AUTH_DOMAIN',
242
+ projectId: 'PLACEHOLDER_PROJECT_ID',
243
+ storageBucket: 'PLACEHOLDER_STORAGE_BUCKET',
244
+ messagingSenderId: 'PLACEHOLDER_MESSAGING_SENDER_ID',
245
+ appId: 'PLACEHOLDER_APP_ID',
246
+ },
247
+ },
248
+ }}
249
+ />
250
+ </XmppProvider>
251
+ ```
121
252
 
122
- For styling you can alter **App.css**:
253
+ ### G) Single-room entry + URL/QR behavior
123
254
 
255
+ ```tsx
256
+ <XmppProvider>
257
+ <Chat
258
+ roomJID="ROOM_JID@conference.xmpp.ethoradev.com"
259
+ config={{
260
+ setRoomJidInPath: true,
261
+ qrUrl: 'https://your-app.example/chat/?qrChatId=',
262
+ }}
263
+ />
264
+ </XmppProvider>
124
265
  ```
125
- #root {
126
- width: 100%;
127
- margin: 0 auto;
128
- text-align: center;
266
+
267
+ `roomJID` forces entry room.
268
+ `setRoomJidInPath` syncs room identity to URL path.
269
+ `useQRCodeChat` / `handleQRChatId` support QR/deep-link room opening.
270
+
271
+ ## Behavior Notes and Legacy Quirks
272
+
273
+ - `newArch` is now default-on. If omitted, runtime uses new architecture paths.
274
+ - Old architecture is used only when you explicitly set `config.newArch = false`.
275
+ - `defaultLogin` currently has legacy inverted behavior in `LoginWrapper`:
276
+ - internal fallback login runs when login modes are not configured and `defaultLogin` is not set.
277
+ - keep this in mind when migrating; prefer explicit `userLogin` / `jwtLogin` / `googleLogin`.
278
+
279
+ ## Chat Props Reference
280
+
281
+ These are the top-level props accepted by `Chat` (exported from `ReduxWrapper`).
282
+
283
+ | Prop | Type | Required | Notes |
284
+ | --- | --- | --- | --- |
285
+ | `config` | `IConfig` | No | Main behavior/configuration object. |
286
+ | `roomJID` | `string` | No | Force specific room JID on load. |
287
+ | `user` | `{ email: string; password: string }` | No | Credentials for email/password login helper path. |
288
+ | `loginData` | `{ email: string; password: string }` | No | Optional login payload. |
289
+ | `MainComponentStyles` | `React.CSSProperties` | No | Outer container style override. |
290
+ | `token` | `string` | No | Optional token input (legacy/integration-specific usage). |
291
+ | `CustomMessageComponent` | `React.ComponentType<MessageProps>` | No | Replace message bubble rendering. |
292
+ | `CustomInputComponent` | `React.ComponentType<SendInputProps & { onSendMessage?; onSendMedia?; placeholderText?; }>` | No | Replace chat input area. |
293
+ | `CustomScrollableArea` | `React.ComponentType<CustomScrollableAreaProps>` | No | Replace list/scroll wrapper behavior. |
294
+ | `CustomDaySeparator` | `React.ComponentType<DaySeparatorProps>` | No | Replace day separator node. |
295
+ | `CustomNewMessageLabel` | `React.ComponentType<NewMessageLabelProps>` | No | Replace "new message" marker. |
296
+
297
+ ## Full Config Reference (`IConfig`)
298
+
299
+ Below is a grouped reference for all `config` options.
300
+
301
+ ### Core
302
+
303
+ | Option | Type | Description |
304
+ | --- | --- | --- |
305
+ | `appId` | `string` | App identifier for backend context. |
306
+ | `baseUrl` | `string` | API base URL (default project uses `https://api.ethoradev.com/v1`). |
307
+ | `customAppToken` | `string` | Custom app token for API initialization. |
308
+ | `xmppSettings` | `{ devServer; host; conference?; xmppPingOnSendEnabled? }` | XMPP connectivity settings. |
309
+ | `initBeforeLoad` | `boolean` | Initialize XMPP before normal chat load flow. |
310
+ | `clearStoreBeforeInit` | `boolean` | Clear local store before initialization. |
311
+ | `newArch` | `boolean` | Defaults to `true`; set `false` to explicitly force legacy/old architecture paths. |
312
+ | `useStoreConsoleEnabled` | `boolean` | Enable verbose internal logging in console. |
313
+
314
+ ### UI and Layout
315
+
316
+ | Option | Type | Description |
317
+ | --- | --- | --- |
318
+ | `disableHeader` | `boolean` | Hide chat header. |
319
+ | `disableMedia` | `boolean` | Disable media sending/processing paths. |
320
+ | `disableRooms` | `boolean` | Hide/disable room list area. |
321
+ | `disableRoomMenu` | `boolean` | Disable room menu controls. |
322
+ | `disableRoomConfig` | `boolean` | Disable room configuration actions. |
323
+ | `disableNewChatButton` | `boolean` | Hide new chat/create room action. |
324
+ | `disableUserCount` | `boolean` | Hide user count in header/UI. |
325
+ | `disableChatInfo` | `{ disableHeader?; disableDescription?; disableType?; disableMembers?; hideMembers?; disableChatHeaderMenu? }` | Fine-grained chat info panel toggles. |
326
+ | `chatHeaderBurgerMenu` | `boolean` | Toggle burger menu in chat header. |
327
+ | `chatHeaderSettings` | `{ hide?; disableCreate?; disableMenu?; hideSearch? }` | Additional header-level controls. |
328
+ | `chatHeaderAdditional` | `{ enabled: boolean; element: any }` | Inject custom element into header area. |
329
+ | `headerLogo` | `string \| React.ReactElement` | Custom logo in header. |
330
+ | `headerMenu` | `() => void` | Custom menu handler. |
331
+ | `headerChatMenu` | `() => void` | Custom room header menu handler. |
332
+ | `colors` | `{ primary: string; secondary: string }` | Theme colors for component UI. |
333
+ | `roomListStyles` | `React.CSSProperties` | Styles for room list pane. |
334
+ | `chatRoomStyles` | `React.CSSProperties` | Styles for chat pane. |
335
+ | `backgroundChat` | `{ color?: string; image?: string \| File }` | Chat background customization. |
336
+ | `bubleMessage` | `MessageBubble` | Bubble-level style overrides (as defined in types). |
337
+ | `setRoomJidInPath` | `boolean` | Sync room JID to URL path. |
338
+ | `qrUrl` | `string` | Base URL for QR deep link behavior. |
339
+
340
+ ### Auth and Identity
341
+
342
+ | Option | Type | Description |
343
+ | --- | --- | --- |
344
+ | `defaultLogin` | `boolean` | Legacy quirk: current runtime fallback behavior is inverted; see Behavior Notes section. |
345
+ | `googleLogin` | `{ enabled: boolean; firebaseConfig: FBConfig }` | Google login support via Firebase config. |
346
+ | `jwtLogin` | `{ token: string; enabled: boolean; handleBadlogin?: React.ReactElement }` | Log user in using JWT exchange flow. |
347
+ | `userLogin` | `{ enabled: boolean; user: User \| null }` | Inject already-authenticated user directly. |
348
+ | `customLogin` | `{ enabled: boolean; loginFunction: () => Promise<User \| null> }` | Provide your custom async login function. |
349
+ | `refreshTokens` | `{ enabled: boolean; refreshFunction?: () => Promise<{ accessToken: string; refreshToken?: string } \| null> }` | Token refresh strategy. |
350
+
351
+ ### Rooms and Data
352
+
353
+ | Option | Type | Description |
354
+ | --- | --- | --- |
355
+ | `defaultRooms` | `ConfigRoom[]` | Seed/default rooms. |
356
+ | `customRooms` | `{ rooms: PartialRoomWithMandatoryKeys[]; disableGetRooms?: boolean; singleRoom: boolean }` | Fully controlled room source. |
357
+ | `forceSetRoom` | `boolean` | Force room setup path in init flow. |
358
+ | `enableRoomsRetry` | `{ enabled: boolean; helperText: string }` | Enable retry UX when rooms fail to load. |
359
+
360
+ ### Messaging and Interactions
361
+
362
+ | Option | Type | Description |
363
+ | --- | --- | --- |
364
+ | `disableInteractions` | `boolean` | Disable message interaction menu/actions. |
365
+ | `disableProfilesInteractions` | `boolean` | Disable profile interactions from chat UI. |
366
+ | `disableSentLogic` | `boolean` | Disable default sent-state logic when needed. |
367
+ | `secondarySendButton` | `{ enabled: boolean; messageEdit: string; label?: React.ReactNode; buttonStyles?: React.CSSProperties; hideInputSendButton?: boolean; overwriteEnterClick?: true }` | Extra send action/button config. |
368
+ | `botMessageAutoScroll` | `boolean` | Force auto-scroll behavior on bot messages. |
369
+ | `messageTextFilter` | `{ enabled: boolean; filterFunction: (text: string) => string }` | Transform/filter outgoing message text. |
370
+ | `eventHandlers` | `{ onMessageSent?; onMessageFailed?; onMessageEdited? }` | Lifecycle callbacks for message operations. |
371
+ | `translates` | `{ enabled: boolean; translations?: Iso639_1Codes }` | Message translation-related options. |
372
+ | `whitelistSystemMessage` | `string[]` | Restrict/render only selected system message types. |
373
+ | `customSystemMessage` | `React.ComponentType<MessageProps>` | Replace system message component renderer. |
374
+
375
+ ### Typing and Sending Control
376
+
377
+ | Option | Type | Description |
378
+ | --- | --- | --- |
379
+ | `disableTypingIndicator` | `boolean` | Disable typing indicator UI logic. |
380
+ | `customTypingIndicator` | `{ enabled: boolean; text?: string \| ((usersTyping: string[]) => string); position?: 'bottom' \| 'top' \| 'overlay' \| 'floating'; styles?: React.CSSProperties; customComponent?: React.ComponentType<{ usersTyping: string[]; text: string; isVisible: boolean; }> }` | Customize typing indicator content and rendering. |
381
+ | `blockMessageSendingWhenProcessing` | `boolean \| { enabled: boolean; timeout?: number; onTimeout?: (roomJID: string) => void }` | Gate sends while processing in-flight state. |
382
+
383
+ ### Notifications
384
+
385
+ | Option | Type | Description |
386
+ | --- | --- | --- |
387
+ | `inAppNotifications` | `{ enabled?; showInContext?; position?; maxNotifications?; duration?; onClick?; customComponent? }` | In-app toast notification behavior and custom rendering. |
388
+
389
+ ### Push
390
+
391
+ | Option | Type | Description |
392
+ | --- | --- | --- |
393
+ | `pushNotifications.enabled` | `boolean` | Enable browser push subscription flow. |
394
+ | `pushNotifications.vapidPublicKey` | `string` | VAPID public key for push registration. |
395
+ | `pushNotifications.firebaseConfig` | `FBConfig` | Firebase app config for push messaging. |
396
+ | `pushNotifications.serviceWorkerPath` | `string` | Service worker path, default `/firebase-messaging-sw.js`. |
397
+ | `pushNotifications.serviceWorkerScope` | `string` | Service worker scope, default `/`. |
398
+ | `pushNotifications.softAsk` | `boolean` | Do not immediately trigger browser permission prompt. |
399
+
400
+ ## Custom Widgets and Overrides
401
+
402
+ You can replace key UI parts without forking the package.
403
+
404
+ | Override prop | Purpose |
405
+ | --- | --- |
406
+ | `CustomMessageComponent` | Fully custom message bubble/row rendering. |
407
+ | `CustomInputComponent` | Custom composer and send controls. |
408
+ | `CustomScrollableArea` | Custom scroll/list container (virtualized or custom behavior). |
409
+ | `CustomDaySeparator` | Custom date separator component. |
410
+ | `CustomNewMessageLabel` | Custom "new message" divider label. |
411
+
412
+ Example:
413
+
414
+ ```tsx
415
+ import { Chat } from '@ethora/chat-component';
416
+ import CustomMessageBubble from './CustomMessageBubble';
417
+ import CustomChatInput from './CustomChatInput';
418
+ import CustomScrollableArea from './CustomScrollableArea';
419
+ import CustomDaySeparator from './CustomDaySeparator';
420
+ import CustomNewMessageLabel from './CustomNewMessageLabel';
421
+
422
+ export default function App() {
423
+ return (
424
+ <Chat
425
+ CustomMessageComponent={CustomMessageBubble}
426
+ CustomInputComponent={CustomChatInput}
427
+ CustomScrollableArea={CustomScrollableArea}
428
+ CustomDaySeparator={CustomDaySeparator}
429
+ CustomNewMessageLabel={CustomNewMessageLabel}
430
+ config={{
431
+ colors: { primary: '#1d4ed8', secondary: '#dbeafe' },
432
+ }}
433
+ />
434
+ );
129
435
  }
130
436
  ```
131
437
 
132
- and **index.css**:
438
+ Reference example components in repository:
439
+
440
+ - `src/examples/customComponents/CustomMessageBubble.tsx`
441
+ - `src/examples/customComponents/CustomChatInput.tsx`
442
+ - `src/examples/customComponents/CustomScrollableArea.tsx`
443
+ - `src/examples/customComponents/CustomDaySeparator.tsx`
444
+ - `src/examples/customComponents/CustomNewMessageLabel.tsx`
445
+
446
+ ## Push Notifications
447
+
448
+ ### Prerequisites
449
+
450
+ | Requirement | Why |
451
+ | --- | --- |
452
+ | HTTPS origin (or localhost) | Browser push APIs require secure contexts. |
453
+ | Firebase project | FCM token + push transport setup. |
454
+ | VAPID public key | Required for web push subscription. |
455
+ | Service worker file | Required for background notification handling. |
456
+
457
+ ### Setup steps
133
458
 
459
+ 1. Copy service worker into your app's public assets:
460
+
461
+ ```bash
462
+ npx @ethora/chat-component ethora-chat
134
463
  ```
135
- body {
136
- margin: 0;
137
- display: flex;
138
- place-items: center;
139
- min-width: 320px;
140
- min-height: 100vh;
141
- width: 100%;
142
- }
464
+
465
+ 2. Configure push in `config`:
466
+
467
+ ```tsx
468
+ <Chat
469
+ config={{
470
+ pushNotifications: {
471
+ enabled: true,
472
+ vapidPublicKey: 'PLACEHOLDER_VAPID_PUBLIC_KEY',
473
+ firebaseConfig: {
474
+ apiKey: 'PLACEHOLDER_API_KEY',
475
+ authDomain: 'PLACEHOLDER_AUTH_DOMAIN',
476
+ projectId: 'PLACEHOLDER_PROJECT_ID',
477
+ storageBucket: 'PLACEHOLDER_STORAGE_BUCKET',
478
+ messagingSenderId: 'PLACEHOLDER_MESSAGING_SENDER_ID',
479
+ appId: 'PLACEHOLDER_APP_ID',
480
+ },
481
+ serviceWorkerPath: '/firebase-messaging-sw.js',
482
+ serviceWorkerScope: '/',
483
+ softAsk: false,
484
+ },
485
+ }}
486
+ />
143
487
  ```
144
488
 
145
- After these changes you can modify **MainComponentStyles** for your chat.
489
+ 3. Optional: use hook directly for controlled permission flow:
146
490
 
147
- ## Architecture Diagram
491
+ ```tsx
492
+ import { usePushNotifications } from '@ethora/chat-component';
148
493
 
149
- ![CleanShot 2025-01-09 at 13 14 37@2x](https://github.com/user-attachments/assets/4d187bbb-6697-4e96-97d3-3a4a4b7e8adf)
494
+ function PushPermissionButton() {
495
+ const { requestPermission } = usePushNotifications({
496
+ enabled: true,
497
+ softAsk: true,
498
+ vapidPublicKey: 'PLACEHOLDER_VAPID_PUBLIC_KEY',
499
+ });
150
500
 
151
- ## Use cases and functionalities details
501
+ return <button onClick={() => requestPermission()}>Enable Push</button>;
502
+ }
503
+ ```
152
504
 
153
- ### LOGIN FUNCTIONALITY
505
+ ## Auth Strategies
154
506
 
155
- Chat component includes an optional Login / Sign-on screen that allows you to login existing users or sign up new users.
156
- In cases where chat component is embedded into your existing web or app experience, you would likely want to disable and bypass the login screen.
507
+ | Strategy | Config shape | Best for |
508
+ | --- | --- | --- |
509
+ | Default fallback (legacy quirk) | no auth block / `defaultLogin` | Legacy/demo flows; prefer explicit auth modes in production |
510
+ | Injected user | `userLogin: { enabled: true, user }` | App already has authenticated user/session |
511
+ | JWT login | `jwtLogin: { enabled: true, token }` | Token-based backend auth flow |
512
+ | Google login | `googleLogin: { enabled: true, firebaseConfig }` | Google SSO using Firebase |
513
+ | Custom login function | `customLogin: { enabled: true, loginFunction }` | Fully custom identity provider |
157
514
 
158
- Supported out of the box:
515
+ ### Example: injected user (bypass login screen)
159
516
 
160
- - **Login bypass** (user credentials are passed from your existing backend) ✅
161
- - **E-mail + password** ✅
162
- - **Google SSO** ✅
517
+ ```tsx
518
+ <Chat
519
+ config={{
520
+ userLogin: {
521
+ enabled: true,
522
+ user: {
523
+ _id: 'PLACEHOLDER_USER_ID',
524
+ appId: 'PLACEHOLDER_APP_ID',
525
+ walletAddress: 'PLACEHOLDER_WALLET_ADDRESS',
526
+ defaultWallet: { walletAddress: 'PLACEHOLDER_WALLET_ADDRESS' },
527
+ firstName: 'Jane',
528
+ lastName: 'Doe',
529
+ xmppPassword: 'PLACEHOLDER_XMPP_PASSWORD',
530
+ token: 'PLACEHOLDER_ACCESS_TOKEN',
531
+ refreshToken: 'PLACEHOLDER_REFRESH_TOKEN',
532
+ username: 'PLACEHOLDER_USERNAME',
533
+ },
534
+ },
535
+ }}
536
+ />
537
+ ```
163
538
 
164
- Supported by Ethora platform but not implemented into Chat Component yet:
539
+ ### Example: JWT login
165
540
 
166
- - **Custom set of credentials** ✅
167
- - **Apple SSO** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub>
168
- - **Facebook SSO** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub>
169
- - **Metamask SSO** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub>
541
+ ```tsx
542
+ <Chat
543
+ config={{
544
+ jwtLogin: {
545
+ enabled: true,
546
+ token: 'PLACEHOLDER_JWT_TOKEN',
547
+ },
548
+ refreshTokens: {
549
+ enabled: true,
550
+ refreshFunction: async () => {
551
+ return {
552
+ accessToken: 'PLACEHOLDER_NEW_ACCESS_TOKEN',
553
+ refreshToken: 'PLACEHOLDER_NEW_REFRESH_TOKEN',
554
+ };
555
+ },
556
+ },
557
+ }}
558
+ />
559
+ ```
170
560
 
171
- ### CHAT FUNCTIONALITY
561
+ ## Hooks and API Exports
562
+
563
+ | Export | Type | Purpose |
564
+ | --- | --- | --- |
565
+ | `Chat` | React component | Main chat component. |
566
+ | `XmppProvider` | React provider | Provides XMPP client context for internal hooks/state. |
567
+ | `useUnread` | hook | Returns unread counters. |
568
+ | `logoutService` | service | Programmatic logout utility. |
569
+ | `useQRCodeChat` | hook | Handle QR-based room links. |
570
+ | `handleQRChatId` | function | Parse/process QR chat ID from URL. |
571
+ | `useInAppNotifications` | hook | Enables and handles in-app notifications. |
572
+ | `usePushNotifications` | hook | Push subscription + foreground handling workflow. |
573
+ | `resendMessage` | function | Retry sending failed/pending messages. |
574
+
575
+ Basic hook usage:
576
+
577
+ ```tsx
578
+ import { useUnread, logoutService } from '@ethora/chat-component';
579
+
580
+ function HeaderActions() {
581
+ const { totalCount } = useUnread();
582
+
583
+ return (
584
+ <div>
585
+ <span>Unread: {totalCount}</span>
586
+ <button onClick={() => logoutService.performLogout()}>Logout</button>
587
+ </div>
588
+ );
589
+ }
590
+ ```
172
591
 
173
- #### "One room at a time - chat session"
592
+ `logoutService.performLogout()` behavior:
174
593
 
175
- - Use Case 1: **One global chat room for all users** ✅ - (e.g. chat lobby for all of your website / app users). Simply create a chat room manually and hardcode the UUID into your chat component code.
176
- - Use Case 2: **One chat room per case** ✅ - (e.g. customer support session, AI bot, a chat room for each location or department, web page specific chat etc). You have to create rooms as required by your business logic via Ethora API and then pass the corresponding chat UUID into chat component. Your end User will see the corresponding room.
594
+ - Dispatches `chatSettingStore/logout`
595
+ - Dispatches `rooms/setLogoutState`
596
+ - Dispatches `roomHeap/clearHeap`
597
+ - Triggers logout middleware, which emits `ethora-xmpp-logout`
598
+ - `XmppProvider` listens to that event and disconnects active XMPP client
177
599
 
178
- #### "Multiple rooms - messenger / social app”
600
+ ## Use Cases and Feature Coverage
179
601
 
180
- - Use Case 3: **Users can switch between Chats** ✅
181
- Similar to Use Case 2, but also allows your User to switch to the **List of Chats** where they can see chat rooms, the count of new messages and a last message for -each room etc. Users can create new Chats and invite others into Chats (depending on your App settings). This functionality is available in full Ethora app but is currently "work in progress" for Chat Component.
602
+ | Area | Status in this package |
603
+ | --- | --- |
604
+ | One-room embedded chat | Available |
605
+ | Multi-room chat UI | Available |
606
+ | Message interactions (reply/copy/edit/delete/report/reactions) | Available |
607
+ | Typing indicator | Available |
608
+ | Profile interactions in chat | Available (can be disabled) |
609
+ | File/media attachments | Available with ongoing enhancements |
610
+ | In-app notifications | Available |
611
+ | Web push notifications | Available |
612
+ | Wallet/assets and extended social modules | Primarily in full Ethora platform |
182
613
 
183
- #### Misc core chat functionalities
614
+ ## Hosted vs Self-Host Guidance
184
615
 
185
- - **Chat header** ✅ - Header with chat title and Users counter (this is optional and you can disable the header)
186
- - **Message bubbles** ✅ - Message bubbles next to user avatars with message content and timestamp
187
- - **Chat history caching and scrolling** ✅
188
- - **Chat history date divider** ✅
189
- - **Now typing** ✅ - when someone is typing, other room Users will see indication of who is typing
616
+ | Model | Best for | Pros | Tradeoffs |
617
+ | --- | --- | --- | --- |
618
+ | Hosted Ethora backend | Fast time-to-market, smaller teams, MVPs | Fast setup, managed backend operations, easier push/auth onboarding | Less infrastructure-level control |
619
+ | Self-hosted Ethora stack | Regulated environments, deep infra control | Full control over infrastructure, compliance customization, internal network deployment options | Higher DevOps/maintenance overhead |
620
+ | Hybrid | Gradual migration or split workloads | Can start fast and migrate critical paths later | More architecture complexity |
190
621
 
191
- #### Message interactions
192
622
 
193
- - **Message menu** ✅ - Long tap or right click opens message menu with "Reply", "Copy", "Edit", "Delete", "Report" options available as well as send Coin / Item options
194
- - **Emoji Reactions** ✅ - Users are able to long tap / click on the message and send Emoji reactions to the message. Reactions are displayed in the corner of the message bubble.
623
+ ## Feature Roadmap
195
624
 
196
- #### Avatars (profile photos)
625
+ This is a practical planning snapshot for cross-platform consumers. It is not a release commitment.
197
626
 
198
- - **Basic avatars** ✅ - in chat screen, users can see basic avatars next to chat bubbles. Simply default avatar icon for everyone.
199
- - **"Initials" avatars** ✅ - in Chat scree, users who don't have photos uploaded will show as "initials" avatars generated by taking the first letter of User's first name and last name
200
- - **Google SSO avatars** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - when using Google SSO, their Google profile photo will be automatically displayed as chat avatar
201
- - **Custom profile photos** ✅ - users are able to upload their custom photos when managing their Profile and the mini-photo will be displayed as a chat avatar
627
+ | Surface | Current state | Notes |
628
+ | --- | --- | --- |
629
+ | Web React (`@ethora/chat-component`) | Available now | This repository. |
630
+ | React Native | Via broader Ethora stack | Track platform-specific implementation in Ethora repos/docs. |
631
+ | Swift (iOS native) | Planned / ecosystem-level | Confirm status with Ethora team for production timelines. |
632
+ | Kotlin (Android native) | Planned / ecosystem-level | Confirm status with Ethora team for production timelines. |
633
+ | Flutter | Planned / ecosystem-level | Confirm status with Ethora team for production timelines. |
634
+ | Additional roadmap items | Ongoing | Media improvements, richer profile/wallet experiences, broader integration guides. |
202
635
 
203
- #### Notifications
636
+ ## Troubleshooting
204
637
 
205
- - **Browser and mobile push notifications** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - push notifications are useful to alert the User about new messages or transactions related to them when they are not actively using your app / chat in the browser.
638
+ | Issue | Likely cause | Fix |
639
+ | --- | --- | --- |
640
+ | `useXmppClient must be used within an XmppProvider` | Using internal XMPP-dependent logic without provider context | Wrap the app tree with `XmppProvider` where needed. |
641
+ | Chat loads but no rooms appear | Auth/app context mismatch or room fetching restrictions | Verify `appId`, user credentials/tokens, `baseUrl`, and `customRooms` settings. |
642
+ | Push permission never appears | `softAsk: true` without manual trigger, insecure origin, or missing VAPID key | Trigger `requestPermission()`, use HTTPS/localhost, set valid VAPID key. |
643
+ | Service worker not found | `firebase-messaging-sw.js` missing in public dir | Run `npx @ethora/chat-component ethora-chat` or copy file manually. |
644
+ | Login loop / auth failure | Wrong token/user object shape | Validate `jwtLogin`, `userLogin.user`, and refresh token flow. |
206
645
 
207
- ### FILE ATTACHMENTS
646
+ ## Ethora Links and Support
647
+ ### Product
208
648
 
209
- - **File attachments** ✅ - file attachments, previews, media attachments, audio/video player etc currently are work in progress for chat component
649
+ - Website: https://ethora.com/
650
+ - Try Ethora: https://app.ethora.com/register
210
651
 
211
- ### USER PROFILES AND DIGITAL WALLET FUNCTIONALITY
652
+ ### Developer Docs
212
653
 
213
- - **Profile screen** ✅ - users can see their own and other Users Profile screens by tapping their avatar in Chat. Profile includes Photo, name, description, direct message button and profile share link
214
- - **Profile Assets (Digital Wallet)** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - Users can view assets (Documents, art/collectables, Coins) within their own profile or profiles of other Users, depending on App-wide and User-specific visibility settings
215
- - **Profile Asset: Coins** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - Coins, Points, Stars (you can call this anything in your project) are a rewards system where Users and Bots can reward individual messages of other Users
216
- - **Profile Asset: Documents** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - Documents in Profiles support use cases where certain User (or bot / business page) need to display certain documents and their provenance history. E.g. business / educational / medical certificates, case-related documents, contracts etc.
217
- - **Profile Asset: Media (audio, video) files** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - Media files playable right from Profiles.
218
- - **Profile Asset: Digital Art (collectables / NFT)** 🚧 <sub><sup>(available in [Ethora git repo](https://github.com/dappros/ethora))</sup></sub> - For projects which support rewarding Users with unique digital collectables and/or allowing Users to upload/mint, distribute or trade digital art or collectables.
654
+ - Chat component docs: https://docs.ethora.com/
655
+ - Ethora GitHub hub: https://github.com/dappros/ethora
656
+ - This package repo: https://github.com/dappros/ethora-chat-component
657
+ - Ethora GitHub organization: https://github.com/dappros
658
+ - API docs (public): https://app.dappros.com/api-docs/
659
+ - API docs (environment used in this repo): https://api.ethoradev.com/api-docs
219
660
 
220
- ## Contacts, Documentation and Technical Support
661
+ ### Community and Support
221
662
 
222
- - Community support forum: https://forum.ethora.com/
663
+ - Forum: https://forum.ethora.com/
223
664
  - Discord: https://discord.gg/Sm6bAHA3ZC
224
- - Contact Ethora team: https://www.ethora.com/#contact
225
- - Documentation main: https://docs.ethora.com/
226
- - Documentation for Ethora API (Swagger): https://api.ethoradev.com/api-docs
227
- - Documentation on github including chat protocol and bots: https://github.com/dappros/ethora/tree/main/api
665
+ - Contact: https://ethora.com/#contact
666
+
667
+ ## License
668
+
669
+ AGPL. See [LICENSE.txt](./LICENSE.txt).