@aomi-labs/react 0.0.0 → 0.2.0

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/dist/index.d.cts CHANGED
@@ -1,166 +1,148 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as react from 'react';
3
2
  import { ReactNode, SetStateAction } from 'react';
4
3
  import { ThreadMessageLike } from '@assistant-ui/react';
5
4
  import { ClassValue } from 'clsx';
6
5
 
7
- interface SessionMessage {
8
- sender?: string;
6
+ interface AomiMessage {
7
+ sender?: "user" | "agent" | "system" | string;
9
8
  content?: string;
10
9
  timestamp?: string;
11
10
  is_streaming?: boolean;
12
- tool_stream?: [string, string] | {
13
- topic?: unknown;
14
- content?: unknown;
15
- } | null;
11
+ tool_result?: [string, string] | null;
16
12
  }
17
- interface SessionResponsePayload {
18
- messages?: SessionMessage[] | null;
19
- system_events?: unknown[] | null;
13
+ /**
14
+ * GET /api/state
15
+ * Fetches current session state including messages and processing status
16
+ */
17
+ interface ApiStateResponse {
18
+ messages?: AomiMessage[] | null;
19
+ system_events?: ApiSystemEvent[] | null;
20
20
  title?: string | null;
21
21
  is_processing?: boolean;
22
- session_exists?: boolean;
23
- session_id?: string;
24
- pending_wallet_tx?: string | null;
25
22
  }
26
- type BackendSessionResponse = SessionResponsePayload;
27
- interface SystemResponsePayload {
28
- res?: SessionMessage | null;
23
+ /**
24
+ * POST /api/chat
25
+ * Sends a chat message and returns updated session state
26
+ */
27
+ interface ApiChatResponse {
28
+ messages?: AomiMessage[] | null;
29
+ system_events?: ApiSystemEvent[] | null;
30
+ title?: string | null;
31
+ is_processing?: boolean;
32
+ }
33
+ /**
34
+ * POST /api/system
35
+ * Sends a system message and returns the response message
36
+ */
37
+ interface ApiSystemResponse {
38
+ res?: AomiMessage | null;
29
39
  }
30
- interface BackendThreadMetadata {
40
+ /**
41
+ * POST /api/interrupt
42
+ * Interrupts current processing and returns updated session state
43
+ */
44
+ type ApiInterruptResponse = ApiChatResponse;
45
+ /**
46
+ * GET /api/sessions
47
+ * Returns array of ApiThread
48
+ */
49
+ interface ApiThread {
31
50
  session_id: string;
32
51
  title: string;
33
52
  is_archived?: boolean;
34
- created_at?: string;
35
- updated_at?: string;
36
- last_active_at?: string;
37
53
  }
38
- interface CreateThreadResponse {
54
+ /**
55
+ * POST /api/sessions
56
+ * Creates a new thread/session
57
+ */
58
+ interface ApiCreateThreadResponse {
39
59
  session_id: string;
40
60
  title?: string;
41
61
  }
42
- type SystemUpdate = {
43
- type: "TitleChanged";
44
- data: {
45
- session_id: string;
46
- new_title: string;
62
+ /**
63
+ * Base SSE event - all events have session_id and type
64
+ */
65
+ type ApiSSEEvent = {
66
+ type: "title_changed" | "tool_update" | "tool_complete" | "system_notice" | string;
67
+ session_id: string;
68
+ new_title?: string;
69
+ [key: string]: unknown;
70
+ };
71
+ /**
72
+ * Backend SystemEvent enum serializes as tagged JSON:
73
+ * - InlineCall: {"InlineCall": {"type": "wallet_tx_request", "payload": {...}}}
74
+ * - SystemNotice: {"SystemNotice": "message"}
75
+ * - SystemError: {"SystemError": "message"}
76
+ * - AsyncCallback: {"AsyncCallback": {...}} (not sent over HTTP)
77
+ */
78
+ type ApiSystemEvent = {
79
+ InlineCall: {
80
+ type: string;
81
+ payload?: unknown;
82
+ [key: string]: unknown;
47
83
  };
84
+ } | {
85
+ SystemNotice: string;
86
+ } | {
87
+ SystemError: string;
88
+ } | {
89
+ AsyncCallback: Record<string, unknown>;
48
90
  };
49
- type SystemUpdateNotification = {
50
- type: "event_available";
51
- session_id: string;
52
- event_id: number;
53
- event_type: string;
91
+
92
+ type UserState = {
93
+ address?: string;
94
+ chainId?: number;
95
+ isConnected: boolean;
96
+ ensName?: string;
54
97
  };
55
- type SystemEvent = Record<string, unknown> & {
56
- type: string;
57
- session_id: string;
58
- event_id: number;
98
+ declare function useUser(): {
99
+ user: UserState;
100
+ setUser: (data: Partial<UserState>) => void;
101
+ getUserState: () => UserState;
102
+ onUserStateChange: (callback: (user: UserState) => void) => () => void;
59
103
  };
104
+ declare function UserContextProvider({ children }: {
105
+ children: ReactNode;
106
+ }): react_jsx_runtime.JSX.Element;
60
107
 
61
108
  declare class BackendApi {
62
109
  private readonly backendUrl;
63
- private connectionStatus;
64
- private eventSource;
65
- private updatesEventSources;
110
+ private sseSubscriber;
66
111
  constructor(backendUrl: string);
67
- fetchState(sessionId: string, options?: {
68
- signal?: AbortSignal;
69
- }): Promise<SessionResponsePayload>;
70
- postChatMessage(sessionId: string, message: string, publicKey?: string): Promise<SessionResponsePayload>;
71
- postSystemMessage(sessionId: string, message: string): Promise<SystemResponsePayload>;
72
- postInterrupt(sessionId: string): Promise<SessionResponsePayload>;
73
- disconnectSSE(): void;
74
- setConnectionStatus(on: boolean): void;
75
- connectSSE(sessionId: string, publicKey?: string): Promise<void>;
76
- private handleConnectionError;
77
- private subscribeToUpdatesInternal;
78
- subscribeToUpdates(sessionId: string, onUpdate: (update: SystemUpdateNotification) => void, onError?: (error: unknown) => void): () => void;
79
- fetchThreads(publicKey: string): Promise<BackendThreadMetadata[]>;
80
- createThread(publicKey?: string, title?: string): Promise<CreateThreadResponse>;
112
+ fetchState(sessionId: string, userState?: UserState): Promise<ApiStateResponse>;
113
+ postChatMessage(sessionId: string, message: string, publicKey?: string): Promise<ApiChatResponse>;
114
+ postSystemMessage(sessionId: string, message: string): Promise<ApiSystemResponse>;
115
+ postInterrupt(sessionId: string): Promise<ApiInterruptResponse>;
116
+ /**
117
+ * Subscribe to SSE updates for a session.
118
+ * Uses fetch streaming and reconnects on disconnects.
119
+ * Returns an unsubscribe function.
120
+ */
121
+ subscribeSSE(sessionId: string, onUpdate: (event: ApiSSEEvent) => void, onError?: (error: unknown) => void): () => void;
122
+ fetchThreads(publicKey: string): Promise<ApiThread[]>;
123
+ fetchThread(sessionId: string): Promise<ApiThread>;
124
+ createThread(threadId: string, publicKey?: string): Promise<ApiCreateThreadResponse>;
81
125
  archiveThread(sessionId: string): Promise<void>;
82
126
  unarchiveThread(sessionId: string): Promise<void>;
83
127
  deleteThread(sessionId: string): Promise<void>;
84
128
  renameThread(sessionId: string, newTitle: string): Promise<void>;
85
- fetchEventsAfter(sessionId: string, afterId?: number, limit?: number): Promise<SystemEvent[]>;
86
- subscribeToUpdatesWithNotification(sessionId: string, onUpdate: (update: SystemUpdateNotification) => void, onError?: (error: unknown) => void): () => void;
129
+ getSystemEvents(sessionId: string, count?: number): Promise<ApiSystemEvent[]>;
87
130
  }
88
131
 
89
- type WalletButtonState = {
90
- address?: string;
91
- chainId?: number;
92
- isConnected: boolean;
93
- ensName?: string;
94
- };
95
- type WalletFooterProps = {
96
- wallet: WalletButtonState;
97
- setWallet: (data: Partial<WalletButtonState>) => void;
98
- };
99
- type WalletTxRequestPayload = {
100
- to: string;
101
- value: string;
102
- data: string;
103
- gas?: string | null;
104
- gas_limit?: string | null;
105
- description?: string;
106
- topic?: string;
107
- timestamp?: string;
108
- };
109
- type WalletTxRequestContext = {
110
- sessionId: string;
111
- threadId: string;
112
- publicKey?: string;
113
- };
114
- type WalletTxRequestHandler = (request: WalletTxRequestPayload, context: WalletTxRequestContext) => Promise<string>;
115
- type Eip1193Provider = {
116
- request: (args: {
117
- method: string;
118
- params?: unknown[];
119
- }) => Promise<unknown>;
120
- };
121
- declare const getNetworkName: (chainId: number | string | undefined) => string;
122
- declare const formatAddress: (addr?: string) => string;
123
- declare function normalizeWalletError(error: unknown): {
124
- rejected: boolean;
125
- message: string;
126
- };
127
- declare function toHexQuantity(value: string): string;
128
- declare function pickInjectedProvider(publicKey?: string): Promise<Eip1193Provider | undefined>;
129
- type WalletSystemMessageEmitterProps = {
130
- wallet: WalletButtonState;
131
- };
132
- declare function WalletSystemMessageEmitter({ wallet, }: WalletSystemMessageEmitterProps): null;
133
-
134
132
  type AomiRuntimeProviderProps = {
135
133
  children: ReactNode;
136
134
  backendUrl?: string;
137
- publicKey?: string;
138
- onWalletTxRequest?: WalletTxRequestHandler;
139
- };
140
- declare function AomiRuntimeProvider({ children, backendUrl, publicKey, onWalletTxRequest, }: Readonly<AomiRuntimeProviderProps>): react_jsx_runtime.JSX.Element;
141
- declare function AomiRuntimeProviderWithNotifications(props: Readonly<AomiRuntimeProviderProps>): react_jsx_runtime.JSX.Element;
142
-
143
- type RuntimeActions = {
144
- sendSystemMessage: (message: string) => Promise<void>;
145
- };
146
- declare const RuntimeActionsProvider: react.Provider<RuntimeActions | undefined>;
147
- declare function useRuntimeActions(): RuntimeActions;
148
-
149
- type ThreadStatus = "regular" | "archived" | "pending";
150
- type ThreadMetadata = {
151
- title: string;
152
- status: ThreadStatus;
153
- lastActiveAt?: string | number;
154
135
  };
136
+ declare function AomiRuntimeProvider({ children, backendUrl, }: Readonly<AomiRuntimeProviderProps>): react_jsx_runtime.JSX.Element;
155
137
 
156
- type ThreadContext$1 = {
138
+ type ThreadContext = {
157
139
  currentThreadId: string;
158
140
  setCurrentThreadId: (id: string) => void;
159
141
  threadViewKey: number;
160
142
  bumpThreadViewKey: () => void;
161
- threads: Map<string, ThreadMessageLike[]>;
143
+ allThreads: Map<string, ThreadMessageLike[]>;
162
144
  setThreads: (updater: SetStateAction<Map<string, ThreadMessageLike[]>>) => void;
163
- threadMetadata: Map<string, ThreadMetadata>;
145
+ allThreadsMetadata: Map<string, ThreadMetadata>;
164
146
  setThreadMetadata: (updater: SetStateAction<Map<string, ThreadMetadata>>) => void;
165
147
  threadCnt: number;
166
148
  setThreadCnt: (updater: SetStateAction<number>) => void;
@@ -169,8 +151,6 @@ type ThreadContext$1 = {
169
151
  getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;
170
152
  updateThreadMetadata: (threadId: string, updates: Partial<ThreadMetadata>) => void;
171
153
  };
172
-
173
- type ThreadContext = ThreadContext$1;
174
154
  type ThreadContextProviderProps = {
175
155
  children: ReactNode;
176
156
  initialThreadId?: string;
@@ -180,29 +160,226 @@ declare function ThreadContextProvider({ children, initialThreadId, }: ThreadCon
180
160
  declare function useCurrentThreadMessages(): ThreadMessageLike[];
181
161
  declare function useCurrentThreadMetadata(): ThreadMetadata | undefined;
182
162
 
183
- declare function toInboundMessage(msg: SessionMessage): ThreadMessageLike | null;
184
- declare function toInboundSystem(msg: SessionMessage): ThreadMessageLike | null;
163
+ type ThreadStatus = "regular" | "archived" | "pending";
164
+ type ThreadMetadata = {
165
+ title: string;
166
+ status: ThreadStatus;
167
+ lastActiveAt?: string | number;
168
+ };
185
169
 
186
- declare function cn(...inputs: ClassValue[]): string;
170
+ type InboundEvent = {
171
+ type: string;
172
+ sessionId: string;
173
+ payload?: unknown;
174
+ status: "pending" | "fetched";
175
+ timestamp: number;
176
+ };
177
+ type OutboundEvent = {
178
+ type: string;
179
+ sessionId: string;
180
+ payload: unknown;
181
+ timestamp: number;
182
+ };
183
+ type SSEStatus = "connected" | "connecting" | "disconnected";
184
+ type EventSubscriber = (event: InboundEvent) => void;
185
+ type EventBuffer = {
186
+ inboundQueue: InboundEvent[];
187
+ outboundQueue: OutboundEvent[];
188
+ sseStatus: SSEStatus;
189
+ lastEventId: string | null;
190
+ subscribers: Map<string, Set<EventSubscriber>>;
191
+ };
187
192
 
188
- type NotificationType = "error" | "notice" | "success";
189
- type NotificationIconType = "error" | "success" | "notice" | "wallet" | "transaction" | "network" | "warning";
190
- type Notification = {
193
+ type NotificationType = "notice" | "success" | "error" | "wallet";
194
+ type Notification$1 = {
191
195
  id: string;
192
196
  type: NotificationType;
193
197
  title: string;
194
- message: string;
195
- iconType?: NotificationIconType;
198
+ message?: string;
196
199
  duration?: number;
200
+ timestamp: number;
197
201
  };
198
- type NotificationContextValue = {
199
- showNotification: (notification: Omit<Notification, "id">) => void;
200
- notifications: Notification[];
202
+ type NotificationData = Omit<Notification$1, "id" | "timestamp">;
203
+ type NotificationContextApi = {
204
+ /** All active notifications */
205
+ notifications: Notification$1[];
206
+ /** Show a new notification */
207
+ showNotification: (params: NotificationData) => string;
208
+ /** Dismiss a notification by ID */
201
209
  dismissNotification: (id: string) => void;
210
+ /** Clear all notifications */
211
+ clearAll: () => void;
202
212
  };
203
- declare function useNotification(): NotificationContextValue;
204
- declare function NotificationProvider({ children }: {
213
+ declare function useNotification(): NotificationContextApi;
214
+ type NotificationContextProviderProps = {
205
215
  children: ReactNode;
206
- }): react_jsx_runtime.JSX.Element;
216
+ };
217
+ declare function NotificationContextProvider({ children, }: NotificationContextProviderProps): react_jsx_runtime.JSX.Element;
218
+
219
+ type AomiRuntimeApi = {
220
+ /** Current user state (wallet connection, address, chain, etc.) */
221
+ user: UserState;
222
+ /** Get current user state synchronously (useful in callbacks) */
223
+ getUserState: () => UserState;
224
+ /** Update user state (partial updates merged with existing state) */
225
+ setUser: (data: Partial<UserState>) => void;
226
+ /** Subscribe to user state changes. Returns unsubscribe function. */
227
+ onUserStateChange: (callback: (user: UserState) => void) => () => void;
228
+ /** ID of the currently active thread */
229
+ currentThreadId: string;
230
+ /** Key that changes when thread view should remount (use for React key prop) */
231
+ threadViewKey: number;
232
+ /** Metadata for all threads (title, status, lastActiveAt) */
233
+ threadMetadata: Map<string, ThreadMetadata>;
234
+ /** Get metadata for a specific thread */
235
+ getThreadMetadata: (threadId: string) => ThreadMetadata | undefined;
236
+ /** Create a new thread and return its ID */
237
+ createThread: () => Promise<string>;
238
+ /** Delete a thread by ID */
239
+ deleteThread: (threadId: string) => Promise<void>;
240
+ /** Rename a thread */
241
+ renameThread: (threadId: string, title: string) => Promise<void>;
242
+ /** Archive a thread */
243
+ archiveThread: (threadId: string) => Promise<void>;
244
+ /** Switch to a thread. If thread doesn't exist, creates a new one. */
245
+ selectThread: (threadId: string) => void;
246
+ /** Whether the assistant is currently generating a response */
247
+ isRunning: boolean;
248
+ /** Get messages for a thread (defaults to currentThreadId) */
249
+ getMessages: (threadId?: string) => ThreadMessageLike[];
250
+ /** Send a message to the current thread */
251
+ sendMessage: (text: string) => Promise<void>;
252
+ /** Cancel the current generation */
253
+ cancelGeneration: () => void;
254
+ /** All active notifications */
255
+ notifications: Notification$1[];
256
+ /** Show a notification. Returns the notification ID. */
257
+ showNotification: (params: NotificationData) => string;
258
+ /** Dismiss a notification by ID */
259
+ dismissNotification: (id: string) => void;
260
+ /** Clear all notifications */
261
+ clearAllNotifications: () => void;
262
+ /** Subscribe to inbound events by type. Returns unsubscribe function. */
263
+ subscribe: (type: string, callback: EventSubscriber) => () => void;
264
+ /** Send a system command to the backend */
265
+ sendSystemCommand: (event: Omit<OutboundEvent, "timestamp">) => void;
266
+ /** Current SSE connection status */
267
+ sseStatus: SSEStatus;
268
+ };
269
+ /**
270
+ * Unified hook that provides access to all Aomi runtime APIs.
271
+ *
272
+ * This is the primary way to interact with the Aomi runtime from consumer code.
273
+ * It combines user, thread, chat, notification, and event APIs into a single interface.
274
+ *
275
+ * @example
276
+ * ```tsx
277
+ * function MyComponent() {
278
+ * const aomi = useAomiRuntime();
279
+ *
280
+ * // User API
281
+ * const { user, setUser } = aomi;
282
+ *
283
+ * // Thread API
284
+ * const { currentThreadId, createThread, selectThread } = aomi;
285
+ *
286
+ * // Chat API
287
+ * const { isRunning, sendMessage, cancelGeneration } = aomi;
288
+ *
289
+ * // Notification API
290
+ * const { showNotification } = aomi;
291
+ *
292
+ * // Event API
293
+ * const { subscribe, sendSystemCommand } = aomi;
294
+ * }
295
+ * ```
296
+ */
297
+ declare function useAomiRuntime(): AomiRuntimeApi;
298
+
299
+ type EventContext = {
300
+ /** Subscribe to inbound events by type. Returns unsubscribe function. */
301
+ subscribe: (type: string, callback: EventSubscriber) => () => void;
302
+ /** Send an outbound event to backend immediately */
303
+ sendOutboundSystem: (event: Omit<OutboundEvent, "timestamp">) => void;
304
+ /** Dispatch system events from HTTP polling into the event buffer */
305
+ dispatchInboundSystem: (sessionId: string, events: ApiSystemEvent[]) => void;
306
+ /** Current SSE connection status */
307
+ sseStatus: SSEStatus;
308
+ };
309
+ declare function useEventContext(): EventContext;
310
+ type EventContextProviderProps = {
311
+ children: ReactNode;
312
+ backendApi: BackendApi;
313
+ sessionId: string;
314
+ };
315
+ declare function EventContextProvider({ children, backendApi, sessionId, }: EventContextProviderProps): react_jsx_runtime.JSX.Element;
316
+
317
+ type WalletTxRequest = {
318
+ to: string;
319
+ value?: string;
320
+ data?: string;
321
+ chainId?: number;
322
+ };
323
+ type WalletTxComplete = {
324
+ txHash: string;
325
+ status: "success" | "failed";
326
+ amount?: string;
327
+ token?: string;
328
+ };
329
+ type WalletConnectionStatus = "connected" | "disconnected";
330
+ type WalletHandlerConfig = {
331
+ sessionId: string;
332
+ onTxRequest?: (request: WalletTxRequest) => void;
333
+ };
334
+ type WalletHanderApi = {
335
+ /** Send transaction completion event to backend */
336
+ sendTxComplete: (tx: WalletTxComplete) => void;
337
+ /** Send wallet connection status change and update user state */
338
+ sendConnectionChange: (status: WalletConnectionStatus, address?: string, chainId?: number) => void;
339
+ /** Pending transaction requests from AI */
340
+ pendingTxRequests: WalletTxRequest[];
341
+ /** Clear a pending request after handling */
342
+ clearTxRequest: (index: number) => void;
343
+ };
344
+ declare function useWalletHandler({ sessionId, onTxRequest, }: WalletHandlerConfig): WalletHanderApi;
345
+
346
+ type Notification = {
347
+ id: string;
348
+ type: string;
349
+ title: string;
350
+ body?: unknown;
351
+ handled: boolean;
352
+ timestamp: number;
353
+ sessionId: string;
354
+ };
355
+ type NotificationHandlerConfig = {
356
+ /** Callback when new notification arrives */
357
+ onNotification?: (notification: Notification) => void;
358
+ };
359
+ type NotificationApi = {
360
+ /** All notifications */
361
+ notifications: Notification[];
362
+ /** Unhandled count */
363
+ unhandledCount: number;
364
+ /** Mark notification as handled */
365
+ markDone: (id: string) => void;
366
+ };
367
+ declare function useNotificationHandler({ onNotification, }?: NotificationHandlerConfig): NotificationApi;
368
+
369
+ /**
370
+ * Utility function to merge Tailwind CSS classes with conflict resolution.
371
+ * Combines clsx for conditional classes and tailwind-merge for deduplication.
372
+ */
373
+ declare function cn(...inputs: ClassValue[]): string;
374
+ /**
375
+ * User configuration props for footer components.
376
+ * Provides user state and setter from UserContext.
377
+ */
378
+ type UserConfig = {
379
+ user: UserState;
380
+ setUser: (data: Partial<UserState>) => void;
381
+ };
382
+ declare const getNetworkName: (chainId: number | string | undefined) => string;
383
+ declare const formatAddress: (addr?: string) => string;
207
384
 
208
- export { AomiRuntimeProvider, type AomiRuntimeProviderProps, AomiRuntimeProviderWithNotifications, BackendApi, type BackendSessionResponse, type BackendThreadMetadata, type CreateThreadResponse, type Eip1193Provider, type Notification, type NotificationIconType, NotificationProvider, type NotificationType, RuntimeActionsProvider, type SessionMessage, type SessionResponsePayload, type SystemEvent, type SystemResponsePayload, type SystemUpdate, type SystemUpdateNotification, ThreadContextProvider, type ThreadMetadata, type ThreadStatus, type WalletButtonState, type WalletFooterProps, WalletSystemMessageEmitter, type WalletTxRequestContext, type WalletTxRequestHandler, type WalletTxRequestPayload, cn, toInboundSystem as constructSystemMessage, toInboundMessage as constructThreadMessage, formatAddress, getNetworkName, normalizeWalletError, pickInjectedProvider, toHexQuantity, useCurrentThreadMessages, useCurrentThreadMetadata, useNotification, useRuntimeActions, useThreadContext };
385
+ export { type AomiMessage, type AomiRuntimeApi, AomiRuntimeProvider, type AomiRuntimeProviderProps, type ApiChatResponse, type ApiCreateThreadResponse, type ApiInterruptResponse, type ApiSSEEvent, type ApiStateResponse, type ApiSystemEvent, type ApiSystemResponse, type ApiThread, BackendApi, type EventBuffer, type EventContext, EventContextProvider, type EventContextProviderProps, type EventSubscriber, type Notification as HandlerNotification, type InboundEvent, type Notification$1 as Notification, type NotificationApi, NotificationContextProvider, type NotificationContextProviderProps, type NotificationContextApi as NotificationContextValue, type NotificationHandlerConfig, type NotificationType, type OutboundEvent, type SSEStatus, type NotificationData as ShowNotificationParams, type ThreadContext, ThreadContextProvider, type ThreadMetadata, type UserConfig, UserContextProvider, type UserState, type UserState as WalletButtonState, type WalletConnectionStatus, type WalletHanderApi, type WalletHandlerConfig, type WalletTxComplete, type WalletTxRequest, cn, formatAddress, getNetworkName, useAomiRuntime, useCurrentThreadMessages, useCurrentThreadMetadata, useEventContext, useNotification, useNotificationHandler, useThreadContext, useUser, useWalletHandler };