@bytexbyte/nxtlinq-ai-agent-sdk 1.2.1 → 1.2.3

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 (43) hide show
  1. package/README.md +175 -207
  2. package/dist/api/nxtlinq-api.d.ts.map +1 -1
  3. package/dist/api/nxtlinq-api.js +121 -142
  4. package/dist/components/ChatBot.d.ts +2 -44
  5. package/dist/components/ChatBot.d.ts.map +1 -1
  6. package/dist/components/ChatBot.js +5 -1143
  7. package/dist/components/context/ChatBotContext.d.ts +5 -0
  8. package/dist/components/context/ChatBotContext.d.ts.map +1 -0
  9. package/dist/components/context/ChatBotContext.js +737 -0
  10. package/dist/components/types/ChatBotTypes.d.ts +98 -0
  11. package/dist/components/types/ChatBotTypes.d.ts.map +1 -0
  12. package/dist/components/types/ChatBotTypes.js +1 -0
  13. package/dist/components/ui/ChatBotUI.d.ts +3 -0
  14. package/dist/components/ui/ChatBotUI.d.ts.map +1 -0
  15. package/dist/components/ui/ChatBotUI.js +146 -0
  16. package/dist/components/ui/MessageInput.d.ts +3 -0
  17. package/dist/components/ui/MessageInput.d.ts.map +1 -0
  18. package/dist/components/ui/MessageInput.js +46 -0
  19. package/dist/components/ui/MessageList.d.ts +3 -0
  20. package/dist/components/ui/MessageList.d.ts.map +1 -0
  21. package/dist/components/ui/MessageList.js +54 -0
  22. package/dist/components/ui/NotificationModal.d.ts +14 -0
  23. package/dist/components/ui/NotificationModal.d.ts.map +1 -0
  24. package/dist/components/ui/NotificationModal.js +79 -0
  25. package/dist/components/ui/PermissionForm.d.ts +8 -0
  26. package/dist/components/ui/PermissionForm.d.ts.map +1 -0
  27. package/dist/components/ui/PermissionForm.js +299 -0
  28. package/dist/components/ui/PresetMessages.d.ts +3 -0
  29. package/dist/components/ui/PresetMessages.d.ts.map +1 -0
  30. package/dist/components/ui/PresetMessages.js +35 -0
  31. package/dist/core/utils/aitUtils.d.ts +28 -0
  32. package/dist/core/utils/aitUtils.d.ts.map +1 -0
  33. package/dist/core/utils/aitUtils.js +34 -0
  34. package/dist/core/utils/notificationUtils.d.ts +29 -0
  35. package/dist/core/utils/notificationUtils.d.ts.map +1 -0
  36. package/dist/core/utils/notificationUtils.js +47 -0
  37. package/dist/core/utils/walletUtils.d.ts +10 -0
  38. package/dist/core/utils/walletUtils.d.ts.map +1 -0
  39. package/dist/core/utils/walletUtils.js +38 -0
  40. package/dist/index.d.ts +13 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +17 -0
  43. package/package.json +1 -1
@@ -1,1144 +1,6 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import * as React from 'react';
3
- import { ethers } from 'ethers';
4
- import { createNxtlinqApi } from '../api/nxtlinq-api';
5
- import stringify from 'fast-json-stable-stringify';
6
- import metakeepClient from '../core/metakeepClient';
7
- import useLocalStorage from '../core/lib/useLocalStorage';
8
- const PermissionForm = ({ hitAddress, permissions, setPermissions, setIsDisabled, onClose, onSave, onConnectWallet, onSignIn, isNeedSignInWithWallet, walletInfo, onVerifyWallet, serviceId, nxtlinqApi, permissionGroup, isAITLoading, isWalletLoading = false }) => {
9
- const [availablePermissions, setAvailablePermissions] = React.useState([]);
10
- const [isSaving, setIsSaving] = React.useState(false);
11
- const fetchAvailablePermissions = async () => {
12
- if (!serviceId)
13
- return;
14
- try {
15
- const result = await nxtlinqApi.permissions.getServicePermissions({
16
- serviceId,
17
- ...(permissionGroup && { groupName: permissionGroup })
18
- });
19
- if ('error' in result) {
20
- console.error('Failed to fetch permissions:', result.error);
21
- return;
22
- }
23
- setAvailablePermissions(result.permissions);
24
- }
25
- catch (error) {
26
- console.error('Error fetching permissions:', error);
27
- }
28
- };
29
- React.useEffect(() => {
30
- fetchAvailablePermissions();
31
- }, [serviceId, nxtlinqApi, permissionGroup]);
32
- const isWalletVerified = Boolean(walletInfo?.id);
33
- const handleSave = async () => {
34
- setIsSaving(true);
35
- try {
36
- await onSave();
37
- }
38
- finally {
39
- setIsSaving(false);
40
- }
41
- };
42
- // Show loading state while checking wallet status
43
- if (isWalletLoading) {
44
- return (_jsxs("div", { style: {
45
- backgroundColor: 'white',
46
- padding: '24px',
47
- borderRadius: '12px',
48
- width: '480px',
49
- maxWidth: '90%',
50
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
51
- }, children: [_jsxs("div", { style: {
52
- display: 'flex',
53
- justifyContent: 'space-between',
54
- alignItems: 'center',
55
- marginBottom: '24px'
56
- }, children: [_jsx("h3", { style: {
57
- margin: 0,
58
- fontSize: '20px',
59
- fontWeight: '600',
60
- color: '#1a1a1a'
61
- }, children: "AIT Settings" }), _jsx("button", { onClick: onClose, style: {
62
- background: 'none',
63
- border: 'none',
64
- fontSize: '24px',
65
- cursor: 'pointer',
66
- color: '#666',
67
- padding: '4px',
68
- display: 'flex',
69
- alignItems: 'center',
70
- justifyContent: 'center'
71
- }, children: "\u00D7" })] }), _jsxs("div", { style: { textAlign: 'center', padding: '32px 0' }, children: [_jsx("div", { style: {
72
- width: '64px',
73
- height: '64px',
74
- margin: '0 auto 16px',
75
- backgroundColor: '#f5f5f5',
76
- borderRadius: '50%',
77
- display: 'flex',
78
- alignItems: 'center',
79
- justifyContent: 'center'
80
- }, children: _jsx("div", { style: {
81
- width: '32px',
82
- height: '32px',
83
- border: '3px solid #e3e3e3',
84
- borderTop: '3px solid #007bff',
85
- borderRadius: '50%',
86
- animation: 'spin 1s linear infinite'
87
- } }) }), _jsx("p", { style: {
88
- marginBottom: '24px',
89
- fontSize: '16px',
90
- color: '#666'
91
- }, children: "Checking wallet status..." })] }), _jsx("style", { children: `
92
- @keyframes spin {
93
- 0% { transform: rotate(0deg); }
94
- 100% { transform: rotate(360deg); }
95
- }
96
- ` })] }));
97
- }
98
- return (_jsxs("div", { style: {
99
- backgroundColor: 'white',
100
- padding: '24px',
101
- borderRadius: '12px',
102
- width: '480px',
103
- maxWidth: '90%',
104
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
105
- }, children: [_jsxs("div", { style: {
106
- display: 'flex',
107
- justifyContent: 'space-between',
108
- alignItems: 'center',
109
- marginBottom: '24px'
110
- }, children: [_jsx("h3", { style: {
111
- margin: 0,
112
- fontSize: '20px',
113
- fontWeight: '600',
114
- color: '#1a1a1a'
115
- }, children: "AIT Settings" }), _jsx("button", { onClick: onClose, style: {
116
- background: 'none',
117
- border: 'none',
118
- fontSize: '24px',
119
- cursor: 'pointer',
120
- color: '#666',
121
- padding: '4px',
122
- display: 'flex',
123
- alignItems: 'center',
124
- justifyContent: 'center'
125
- }, children: "\u00D7" })] }), !hitAddress ? (_jsxs("div", { style: { textAlign: 'center', padding: '32px 0' }, children: [_jsx("div", { style: {
126
- width: '64px',
127
- height: '64px',
128
- margin: '0 auto 16px',
129
- backgroundColor: '#f5f5f5',
130
- borderRadius: '50%',
131
- display: 'flex',
132
- alignItems: 'center',
133
- justifyContent: 'center'
134
- }, children: _jsx("span", { style: { fontSize: '32px' }, children: "\uD83D\uDC5B" }) }), _jsx("p", { style: {
135
- marginBottom: '24px',
136
- fontSize: '16px',
137
- color: '#666'
138
- }, children: "Please connect your wallet first" }), _jsx("button", { onClick: onConnectWallet, style: {
139
- padding: '12px 24px',
140
- backgroundColor: '#007bff',
141
- color: 'white',
142
- border: 'none',
143
- borderRadius: '8px',
144
- cursor: 'pointer',
145
- fontSize: '16px',
146
- fontWeight: '500',
147
- transition: 'background-color 0.2s'
148
- }, onMouseOver: (e) => e.currentTarget.style.backgroundColor = '#0056b3', onMouseOut: (e) => e.currentTarget.style.backgroundColor = '#007bff', children: "Connect Wallet" })] })) : isNeedSignInWithWallet ? (_jsxs("div", { style: { textAlign: 'center', padding: '32px 0' }, children: [_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h4", { style: {
149
- marginBottom: '12px',
150
- fontSize: '16px',
151
- color: '#666'
152
- }, children: "Connected Wallet" }), _jsx("p", { style: {
153
- wordBreak: 'break-all',
154
- backgroundColor: '#f8f9fa',
155
- padding: '12px',
156
- borderRadius: '8px',
157
- fontSize: '14px',
158
- color: '#333',
159
- border: '1px solid #e9ecef'
160
- }, children: hitAddress })] }), _jsx("p", { style: {
161
- marginBottom: '24px',
162
- fontSize: '16px',
163
- color: '#666'
164
- }, children: "Please sign in to continue" }), _jsx("button", { onClick: onSignIn, style: {
165
- padding: '12px 24px',
166
- backgroundColor: '#007bff',
167
- color: 'white',
168
- border: 'none',
169
- borderRadius: '8px',
170
- cursor: 'pointer',
171
- fontSize: '16px',
172
- fontWeight: '500',
173
- transition: 'background-color 0.2s'
174
- }, onMouseOver: (e) => e.currentTarget.style.backgroundColor = '#0056b3', onMouseOut: (e) => e.currentTarget.style.backgroundColor = '#007bff', children: "Sign In" })] })) : !isWalletVerified ? (_jsxs("div", { style: { textAlign: 'center', padding: '32px 0' }, children: [_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h4", { style: {
175
- marginBottom: '12px',
176
- fontSize: '16px',
177
- color: '#666'
178
- }, children: "Connected Wallet" }), _jsx("p", { style: {
179
- wordBreak: 'break-all',
180
- backgroundColor: '#f8f9fa',
181
- padding: '12px',
182
- borderRadius: '8px',
183
- fontSize: '14px',
184
- color: '#333',
185
- border: '1px solid #e9ecef'
186
- }, children: hitAddress })] }), _jsx("p", { style: {
187
- marginBottom: '24px',
188
- fontSize: '16px',
189
- color: '#666'
190
- }, children: "Please verify your wallet to continue" }), _jsx("button", { onClick: onVerifyWallet, style: {
191
- padding: '12px 24px',
192
- backgroundColor: '#007bff',
193
- color: 'white',
194
- border: 'none',
195
- borderRadius: '8px',
196
- cursor: 'pointer',
197
- fontSize: '16px',
198
- fontWeight: '500',
199
- transition: 'background-color 0.2s'
200
- }, onMouseOver: (e) => e.currentTarget.style.backgroundColor = '#0056b3', onMouseOut: (e) => e.currentTarget.style.backgroundColor = '#007bff', children: "Verify your wallet" })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h4", { style: {
201
- marginBottom: '12px',
202
- fontSize: '16px',
203
- color: '#666'
204
- }, children: "Connected Wallet" }), _jsx("p", { style: {
205
- wordBreak: 'break-all',
206
- backgroundColor: '#f8f9fa',
207
- padding: '12px',
208
- borderRadius: '8px',
209
- fontSize: '14px',
210
- color: '#333',
211
- border: '1px solid #e9ecef'
212
- }, children: hitAddress })] }), _jsxs("div", { style: { marginBottom: '24px' }, children: [_jsx("h4", { style: {
213
- marginBottom: '12px',
214
- fontSize: '16px',
215
- color: '#666'
216
- }, children: "Permissions" }), isAITLoading ? (_jsx("div", { style: {
217
- backgroundColor: '#f8f9fa',
218
- padding: '16px',
219
- borderRadius: '8px',
220
- border: '1px solid #e9ecef',
221
- textAlign: 'center',
222
- color: '#666'
223
- }, children: "Loading permissions..." })) : (_jsx("div", { style: {
224
- backgroundColor: '#f8f9fa',
225
- padding: '16px',
226
- borderRadius: '8px',
227
- border: '1px solid #e9ecef'
228
- }, children: availablePermissions.map((permission) => (_jsx("div", { style: { marginBottom: '12px' }, children: _jsxs("label", { style: {
229
- display: 'flex',
230
- alignItems: 'center',
231
- gap: '12px',
232
- cursor: isAITLoading ? 'not-allowed' : 'pointer',
233
- padding: '8px',
234
- borderRadius: '6px',
235
- transition: 'background-color 0.2s',
236
- opacity: isAITLoading ? 0.6 : 1
237
- }, onMouseOver: (e) => {
238
- if (!isAITLoading) {
239
- e.currentTarget.style.backgroundColor = '#e9ecef';
240
- }
241
- }, onMouseOut: (e) => {
242
- if (!isAITLoading) {
243
- e.currentTarget.style.backgroundColor = 'transparent';
244
- }
245
- }, children: [_jsx("input", { type: "checkbox", checked: permissions.includes(permission.label), onChange: () => {
246
- if (!isAITLoading) {
247
- const newPermissions = permissions.includes(permission.label)
248
- ? permissions.filter(p => p !== permission.label)
249
- : [...permissions, permission.label].sort();
250
- setPermissions(newPermissions);
251
- setIsDisabled(false);
252
- }
253
- }, disabled: isAITLoading, style: {
254
- margin: 0,
255
- width: '18px',
256
- height: '18px',
257
- cursor: isAITLoading ? 'not-allowed' : 'pointer'
258
- } }), _jsx("span", { style: {
259
- fontSize: '14px',
260
- color: '#333'
261
- }, children: permission.label })] }) }, permission.id))) }))] }), _jsxs("div", { style: {
262
- display: 'flex',
263
- justifyContent: 'flex-end',
264
- gap: '12px',
265
- borderTop: '1px solid #e9ecef',
266
- paddingTop: '24px'
267
- }, children: [_jsx("button", { onClick: onClose, style: {
268
- padding: '10px 20px',
269
- backgroundColor: '#f8f9fa',
270
- color: '#666',
271
- border: '1px solid #dee2e6',
272
- borderRadius: '8px',
273
- cursor: 'pointer',
274
- fontSize: '14px',
275
- fontWeight: '500',
276
- transition: 'all 0.2s'
277
- }, onMouseOver: (e) => {
278
- e.currentTarget.style.backgroundColor = '#e9ecef';
279
- e.currentTarget.style.borderColor = '#ced4da';
280
- }, onMouseOut: (e) => {
281
- e.currentTarget.style.backgroundColor = '#f8f9fa';
282
- e.currentTarget.style.borderColor = '#dee2e6';
283
- }, children: "Cancel" }), _jsx("button", { onClick: handleSave, disabled: permissions.length === 0 || isSaving || isAITLoading, style: {
284
- padding: '10px 20px',
285
- backgroundColor: permissions.length === 0 || isSaving || isAITLoading ? '#e9ecef' : '#007bff',
286
- color: permissions.length === 0 || isSaving || isAITLoading ? '#6c757d' : 'white',
287
- border: 'none',
288
- borderRadius: '8px',
289
- cursor: permissions.length === 0 || isSaving || isAITLoading ? 'not-allowed' : 'pointer',
290
- fontSize: '14px',
291
- fontWeight: '500',
292
- transition: 'background-color 0.2s'
293
- }, onMouseOver: (e) => {
294
- if (permissions.length > 0 && !isSaving && !isAITLoading) {
295
- e.currentTarget.style.backgroundColor = '#0056b3';
296
- }
297
- }, onMouseOut: (e) => {
298
- if (permissions.length > 0 && !isSaving && !isAITLoading) {
299
- e.currentTarget.style.backgroundColor = '#007bff';
300
- }
301
- }, children: isSaving ? 'Saving...' : 'Save' })] })] }))] }));
302
- };
303
- export const ChatBot = ({ onMessage, onError, onToolUse, presetMessages = [], placeholder = 'Type a message...', className = '', maxRetries = 3, retryDelay = 1000, serviceId, apiKey, apiSecret, onVerifyWallet, permissionGroup }) => {
304
- const [messages, setMessages] = React.useState([]);
305
- const [inputValue, setInputValue] = React.useState('');
306
- const [isLoading, setIsLoading] = React.useState(false);
307
- const [isOpen, setIsOpen] = React.useState(false);
308
- const [hitAddress, setHitAddress] = React.useState(null);
309
- const [ait, setAit] = React.useState(null);
310
- const [permissions, setPermissions] = React.useState([]);
311
- const [availablePermissions, setAvailablePermissions] = React.useState([]);
312
- const [showPermissionForm, setShowPermissionForm] = React.useState(false);
313
- const [success, setSuccess] = React.useState(false);
314
- const [isPermissionFormOpen, setIsPermissionFormOpen] = React.useState(false);
315
- const [isAITLoading, setIsAITLoading] = React.useState(false);
316
- const messagesEndRef = React.useRef(null);
317
- const [isDisabled, setIsDisabled] = React.useState(true);
318
- const [signer, setSigner] = React.useState(null);
319
- const [walletInfo, setWalletInfo] = React.useState(null);
320
- const verifyWalletBtnRef = React.useRef(null);
321
- const [nxtlinqAITServiceAccessToken, setNxtlinqAITServiceAccessToken] = useLocalStorage('nxtlinqAITServiceAccessToken', '');
322
- const [isWalletLoading, setIsWalletLoading] = React.useState(false);
323
- const nxtlinqApi = React.useMemo(() => createNxtlinqApi(apiKey, apiSecret), [apiKey, apiSecret]);
324
- const fetchAvailablePermissions = async () => {
325
- if (!serviceId)
326
- return;
327
- try {
328
- const result = await nxtlinqApi.permissions.getServicePermissions({
329
- serviceId,
330
- ...(permissionGroup && { groupName: permissionGroup })
331
- });
332
- if ('error' in result) {
333
- console.error('Failed to fetch permissions:', result.error);
334
- return;
335
- }
336
- setAvailablePermissions(result.permissions);
337
- }
338
- catch (error) {
339
- console.error('Error fetching permissions:', error);
340
- }
341
- };
342
- const refreshAIT = async (forceUpdatePermissions = false) => {
343
- console.log('refreshAIT called');
344
- console.log('hitAddress:', hitAddress);
345
- console.log('nxtlinqAITServiceAccessToken:', nxtlinqAITServiceAccessToken);
346
- if (!hitAddress) {
347
- setAit(null);
348
- setPermissions([]);
349
- return;
350
- }
351
- setIsAITLoading(true);
352
- try {
353
- const response = await nxtlinqApi.ait.getAITByServiceIdAndController({
354
- serviceId,
355
- controller: hitAddress
356
- }, nxtlinqAITServiceAccessToken || '');
357
- if ('error' in response) {
358
- console.error('Failed to fetch AIT:', response.error);
359
- setAit(null);
360
- setPermissions([]);
361
- return;
362
- }
363
- console.log('AIT response:', response);
364
- setAit(response);
365
- // Update permissions if form is not open OR if force update is requested
366
- if (!isPermissionFormOpen || forceUpdatePermissions) {
367
- setPermissions(response.metadata?.permissions || []);
368
- }
369
- }
370
- catch (error) {
371
- console.error('Failed to fetch AIT:', error);
372
- setAit(null);
373
- setPermissions([]);
374
- }
375
- finally {
376
- setIsAITLoading(false);
377
- }
378
- };
379
- React.useEffect(() => {
380
- console.log('hitAddress:', hitAddress);
381
- console.log('nxtlinqAITServiceAccessToken:', nxtlinqAITServiceAccessToken);
382
- if (hitAddress && nxtlinqAITServiceAccessToken) {
383
- refreshAIT();
384
- }
385
- }, [hitAddress, nxtlinqAITServiceAccessToken]);
386
- // Fetch available permissions when permissionGroup changes
387
- React.useEffect(() => {
388
- fetchAvailablePermissions();
389
- }, [serviceId, permissionGroup]);
390
- const isNeedSignInWithWallet = React.useMemo(() => {
391
- if (!hitAddress) {
392
- return false;
393
- }
394
- if (!nxtlinqAITServiceAccessToken) {
395
- return true;
396
- }
397
- try {
398
- // Check if the token is expired
399
- const payload = JSON.parse(atob(nxtlinqAITServiceAccessToken.split('.')[1]));
400
- const exp = payload.exp * 1000; // Convert to milliseconds
401
- const now = Date.now();
402
- if (exp < now) {
403
- return true;
404
- }
405
- // Check if the token's payload has the same address as the wallet address
406
- const address = payload.address;
407
- if (address !== hitAddress) {
408
- return true;
409
- }
410
- // If user has valid token but no AIT, they don't need to sign in again
411
- // They just need to generate AIT through the permission form
412
- return false;
413
- }
414
- catch (error) {
415
- console.error('Error parsing token:', error);
416
- return true;
417
- }
418
- }, [hitAddress, nxtlinqAITServiceAccessToken]);
419
- const handleVerifySuccess = (address) => {
420
- localStorage.setItem(`wallet_verified_${address}`, 'true');
421
- const getWalletInfo = async () => {
422
- setIsWalletLoading(true);
423
- try {
424
- const token = JSON.parse(localStorage.getItem('nxtlinqAITServiceAccessToken') || '');
425
- const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
426
- console.log('Wallet response:', walletResponse);
427
- if (!('error' in walletResponse)) {
428
- setWalletInfo(walletResponse);
429
- const aitResponse = await nxtlinqApi.ait.getAITByServiceIdAndController({
430
- serviceId,
431
- controller: address
432
- }, token);
433
- console.log('AIT response:', aitResponse);
434
- if (!('error' in aitResponse)) {
435
- setAit(aitResponse);
436
- }
437
- }
438
- }
439
- catch (error) {
440
- console.error('Failed to update wallet info after verification:', error);
441
- }
442
- finally {
443
- setIsWalletLoading(false);
444
- }
445
- };
446
- getWalletInfo();
447
- };
448
- React.useEffect(() => {
449
- const getWalletInfo = async () => {
450
- if (!hitAddress) {
451
- return;
452
- }
453
- if (isNeedSignInWithWallet) {
454
- return;
455
- }
456
- setIsWalletLoading(true);
457
- try {
458
- const getWalletResponse = await nxtlinqApi.wallet.getWallet({ address: hitAddress }, nxtlinqAITServiceAccessToken);
459
- if ('error' in getWalletResponse) {
460
- if (getWalletResponse.error === 'Wallet not found') {
461
- console.log('Wallet not found - this is expected for new users');
462
- return;
463
- }
464
- console.error(getWalletResponse.error);
465
- return;
466
- }
467
- setWalletInfo(getWalletResponse);
468
- }
469
- catch (error) {
470
- console.error('Error getting wallet info:', error);
471
- }
472
- finally {
473
- setIsWalletLoading(false);
474
- }
475
- };
476
- getWalletInfo();
477
- }, [hitAddress, isNeedSignInWithWallet]);
478
- const handleVerifyWalletClick = async () => {
479
- console.log('handleVerifyWalletClick called');
480
- console.log('Current states:', {
481
- hitAddress,
482
- isNeedSignInWithWallet,
483
- walletInfo,
484
- signer: !!signer
485
- });
486
- if (!hitAddress) {
487
- alert('Please connect your wallet first.');
488
- return;
489
- }
490
- try {
491
- if (onVerifyWallet) {
492
- setIsLoading(true);
493
- const result = await onVerifyWallet();
494
- console.log('Verify wallet response:', result);
495
- if (!result) {
496
- setIsLoading(false);
497
- return;
498
- }
499
- const { token } = result;
500
- const address = hitAddress;
501
- if (token && address) {
502
- const payload = {
503
- address: hitAddress,
504
- token,
505
- timestamp: Date.now(),
506
- method: 'berifyme'
507
- };
508
- try {
509
- const verifyWalletResponse = await nxtlinqApi.wallet.verifyWallet({ ...payload }, token);
510
- if ('error' in verifyWalletResponse) {
511
- if (verifyWalletResponse.error === 'Wallet already exists') {
512
- // If wallet exists, get wallet info directly
513
- setIsWalletLoading(true);
514
- try {
515
- const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
516
- if (!('error' in walletResponse)) {
517
- setWalletInfo(walletResponse);
518
- const aitResponse = await nxtlinqApi.ait.getAITByServiceIdAndController({ serviceId, controller: address }, token);
519
- if (!('error' in aitResponse)) {
520
- setAit(aitResponse);
521
- }
522
- }
523
- }
524
- finally {
525
- setIsWalletLoading(false);
526
- }
527
- // Clean up URL parameters after wallet verification
528
- if (typeof window !== 'undefined') {
529
- try {
530
- const url = new URL(window.location.href);
531
- // Clean up all Berify.me related parameters
532
- url.searchParams.delete('token');
533
- url.searchParams.delete('isAutoConnect');
534
- url.searchParams.delete('method');
535
- url.searchParams.delete('returnUrl');
536
- window.history.replaceState({}, '', url.toString());
537
- }
538
- catch (e) {
539
- console.error('Failed to clean URL:', e);
540
- }
541
- }
542
- setIsLoading(false);
543
- // Refresh AIT after wallet verification
544
- refreshAIT();
545
- return { token, hitAddress: address };
546
- }
547
- alert(verifyWalletResponse.error);
548
- setIsLoading(false);
549
- return;
550
- }
551
- // Verification successful, get wallet info
552
- setIsWalletLoading(true);
553
- try {
554
- const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
555
- if (!('error' in walletResponse)) {
556
- setWalletInfo(walletResponse);
557
- const aitResponse = await nxtlinqApi.ait.getAITByServiceIdAndController({ serviceId, controller: address }, token);
558
- if (!('error' in aitResponse)) {
559
- setAit(aitResponse);
560
- }
561
- }
562
- }
563
- finally {
564
- setIsWalletLoading(false);
565
- }
566
- // Clean up URL parameters after wallet verification
567
- if (typeof window !== 'undefined') {
568
- try {
569
- const url = new URL(window.location.href);
570
- // Clean up all Berify.me related parameters
571
- url.searchParams.delete('token');
572
- url.searchParams.delete('isAutoConnect');
573
- url.searchParams.delete('method');
574
- url.searchParams.delete('returnUrl');
575
- window.history.replaceState({}, '', url.toString());
576
- }
577
- catch (e) {
578
- console.error('Failed to clean URL:', e);
579
- }
580
- }
581
- setIsLoading(false);
582
- // Refresh AIT after wallet verification
583
- refreshAIT();
584
- return { token, hitAddress: address };
585
- }
586
- catch (error) {
587
- let msg = 'Verification failed';
588
- if (typeof error === 'object' && error !== null && 'response' in error) {
589
- // @ts-ignore
590
- msg = error.response?.data?.error || error.message || msg;
591
- }
592
- else if (error instanceof Error) {
593
- msg = error.message;
594
- }
595
- console.error('Wallet verification failed:', error);
596
- alert(msg);
597
- setIsLoading(false);
598
- throw error;
599
- }
600
- }
601
- setIsLoading(false);
602
- return { token, hitAddress: address };
603
- }
604
- }
605
- catch (error) {
606
- console.error('Failed to verify wallet:', error);
607
- setIsLoading(false);
608
- alert('Failed to verify wallet. Please try again.');
609
- throw error;
610
- }
611
- };
612
- // Add useEffect to handle URL parameters
613
- React.useEffect(() => {
614
- if (typeof window !== 'undefined') {
615
- try {
616
- const urlParams = new URLSearchParams(window.location.search);
617
- const token = urlParams.get('token');
618
- if (token && hitAddress) {
619
- handleVerifyWalletClick();
620
- }
621
- }
622
- catch (e) {
623
- console.error('Failed to get URL params:', e);
624
- }
625
- }
626
- }, [hitAddress]);
627
- React.useEffect(() => {
628
- console.log('Wallet states changed:', {
629
- hitAddress,
630
- isNeedSignInWithWallet,
631
- walletInfo,
632
- signer: !!signer
633
- });
634
- }, [hitAddress, isNeedSignInWithWallet, walletInfo, signer]);
635
- const scrollToBottom = () => {
636
- messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
637
- };
638
- React.useEffect(() => {
639
- scrollToBottom();
640
- }, [messages]);
641
- React.useEffect(() => {
642
- if (!hitAddress) {
643
- setAit(null);
644
- }
645
- }, [hitAddress]);
646
- React.useEffect(() => {
647
- if (!ait) {
648
- return;
649
- }
650
- const aitPermissions = ait.metadata?.permissions || [];
651
- setPermissions(aitPermissions);
652
- }, [ait]);
653
- const connectWallet = React.useCallback(async (autoShowSignInMessage = true) => {
654
- if (typeof window === 'undefined') {
655
- console.error('Web3 is not available in server-side rendering');
656
- return;
657
- }
658
- try {
659
- const web3Provider = await metakeepClient.ethereum;
660
- if (!web3Provider) {
661
- throw new Error('Web3 provider not available');
662
- }
663
- await web3Provider.enable();
664
- const ethersProvider = new ethers.providers.Web3Provider(web3Provider);
665
- const userSigner = await ethersProvider.getSigner();
666
- const userAddress = await userSigner.getAddress();
667
- localStorage.setItem('walletAddress', userAddress);
668
- setHitAddress(userAddress);
669
- setSigner(userSigner);
670
- // Refresh AIT after connecting wallet and wait for completion
671
- if (nxtlinqAITServiceAccessToken) {
672
- await refreshAIT();
673
- }
674
- // Auto-show appropriate message after connecting wallet and AIT refresh
675
- if (autoShowSignInMessage) {
676
- // Check state after refreshAIT has completed
677
- if (isNeedSignInWithWallet) {
678
- // User needs to sign in
679
- setMessages(prev => [...prev, {
680
- id: Date.now().toString(),
681
- content: 'Please sign in with your wallet to continue.',
682
- role: 'assistant',
683
- timestamp: new Date().toISOString(),
684
- button: 'signIn'
685
- }]);
686
- }
687
- else {
688
- // User is already signed in
689
- setMessages(prev => [...prev, {
690
- id: Date.now().toString(),
691
- content: 'Successfully connected your HIT wallet. You are already signed in and can use the AI agent.',
692
- role: 'assistant',
693
- timestamp: new Date().toISOString()
694
- }]);
695
- }
696
- }
697
- return userAddress;
698
- }
699
- catch (error) {
700
- console.error('Failed to connect wallet:', error);
701
- localStorage.removeItem('walletAddress');
702
- setHitAddress(null);
703
- setSigner(null);
704
- throw error;
705
- }
706
- }, [nxtlinqAITServiceAccessToken, refreshAIT, isNeedSignInWithWallet]);
707
- const signInWallet = async (autoShowSuccessMessage = true) => {
708
- if (!hitAddress) {
709
- alert('Please connect your wallet first.');
710
- return;
711
- }
712
- if (!signer) {
713
- alert('Please connect your wallet first.');
714
- return;
715
- }
716
- try {
717
- const nonceResponse = await nxtlinqApi.auth.getNonce({ address: hitAddress });
718
- if ('error' in nonceResponse) {
719
- alert(nonceResponse.error);
720
- return;
721
- }
722
- const payload = {
723
- address: hitAddress,
724
- code: nonceResponse.code,
725
- timestamp: nonceResponse.timestamp
726
- };
727
- const stringToSign = stringify(payload);
728
- const signature = await signer.signMessage(stringToSign || '');
729
- const response = await nxtlinqApi.auth.signIn({
730
- ...payload,
731
- signature
732
- });
733
- if ('error' in response) {
734
- alert(response.error);
735
- return;
736
- }
737
- const { accessToken } = response;
738
- setNxtlinqAITServiceAccessToken(accessToken);
739
- // Auto-show connected message after signing in
740
- if (autoShowSuccessMessage) {
741
- setMessages(prev => [...prev, {
742
- id: Date.now().toString(),
743
- content: 'Successfully signed in with your HIT wallet. You can now use the AI agent.',
744
- role: 'assistant',
745
- timestamp: new Date().toISOString()
746
- }]);
747
- }
748
- // Refresh AIT after signing in
749
- refreshAIT();
750
- }
751
- catch (error) {
752
- console.error('Failed to sign in:', error);
753
- alert('Failed to sign in. Please try again.');
754
- }
755
- };
756
- const hasPermission = async (toolName) => {
757
- if (!hitAddress) {
758
- setMessages(prev => [...prev, {
759
- id: Date.now().toString(),
760
- content: 'Please connect your HIT wallet to continue.',
761
- role: 'assistant',
762
- timestamp: new Date().toISOString(),
763
- button: 'connect'
764
- }]);
765
- return false;
766
- }
767
- // Check if user has signed in with wallet
768
- if (!nxtlinqAITServiceAccessToken) {
769
- setMessages(prev => [...prev, {
770
- id: Date.now().toString(),
771
- content: 'Please sign in with your HIT wallet to continue.',
772
- role: 'assistant',
773
- timestamp: new Date().toISOString(),
774
- button: 'signIn'
775
- }]);
776
- return false;
777
- }
778
- if (!ait) {
779
- setMessages(prev => [...prev, {
780
- id: Date.now().toString(),
781
- content: 'No AIT found for your wallet. Please click the settings button (⚙️) to configure your AIT permissions.',
782
- role: 'assistant',
783
- timestamp: new Date().toISOString()
784
- }]);
785
- return false;
786
- }
787
- // Check if the tool permission is available for current identity provider
788
- const availablePermissionLabels = availablePermissions.map(p => p.label);
789
- if (!availablePermissionLabels.includes(toolName)) {
790
- setMessages(prev => [...prev, {
791
- id: Date.now().toString(),
792
- content: `This tool (${toolName}) is not available for your current identity provider.`,
793
- role: 'assistant',
794
- timestamp: new Date().toISOString()
795
- }]);
796
- return false;
797
- }
798
- // Check if the tool permission is included in AIT permissions
799
- if (!permissions.includes(toolName)) {
800
- setMessages(prev => [...prev, {
801
- id: Date.now().toString(),
802
- content: `You do not have the required AIT permission: ${toolName}. Please click the settings button (⚙️) to update your permissions.`,
803
- role: 'assistant',
804
- timestamp: new Date().toISOString()
805
- }]);
806
- return false;
807
- }
808
- return true;
809
- };
810
- const sendMessage = async (content, retryCount = 0) => {
811
- try {
812
- setIsLoading(true);
813
- const response = await nxtlinqApi.agent.sendMessage({
814
- message: content,
815
- apiKey,
816
- apiSecret,
817
- });
818
- if ('error' in response) {
819
- throw new Error(response.error);
820
- }
821
- const novaResponse = response;
822
- if (novaResponse.toolCall?.toolUse && novaResponse.result !== 'Authentication data retrieved') {
823
- if (onToolUse) {
824
- const isToolAllowed = await hasPermission(novaResponse.toolCall.toolUse.name);
825
- if (!isToolAllowed) {
826
- return;
827
- }
828
- const toolUseResult = await onToolUse(novaResponse.toolCall.toolUse);
829
- if (toolUseResult) {
830
- setMessages(prev => [...prev, toolUseResult]);
831
- return;
832
- }
833
- }
834
- }
835
- if (!novaResponse.toolCall?.toolUse && novaResponse.reply) {
836
- const replyText = novaResponse.reply
837
- .map(item => item.text.replace(/<thinking>/g, '').replace(/<\/thinking>/g, ''))
838
- .join(' ') || '';
839
- if (replyText) {
840
- const message = {
841
- id: Date.now().toString(),
842
- content: replyText,
843
- role: 'assistant',
844
- timestamp: new Date().toISOString()
845
- };
846
- setMessages(prev => [...prev, message]);
847
- return;
848
- }
849
- }
850
- return;
851
- }
852
- catch (error) {
853
- if (retryCount < maxRetries) {
854
- await new Promise(resolve => setTimeout(resolve, retryDelay));
855
- return sendMessage(content, retryCount + 1);
856
- }
857
- throw error;
858
- }
859
- finally {
860
- setIsLoading(false);
861
- }
862
- };
863
- const handleSubmit = async (e) => {
864
- e.preventDefault();
865
- if (!inputValue.trim() || isLoading)
866
- return;
867
- const userMessage = {
868
- id: Date.now().toString(),
869
- content: inputValue,
870
- role: 'user',
871
- timestamp: new Date().toISOString()
872
- };
873
- setMessages(prev => [...prev, userMessage]);
874
- setInputValue('');
875
- setIsLoading(true);
876
- try {
877
- await sendMessage(inputValue);
878
- }
879
- catch (error) {
880
- console.error('Failed to send message:', error);
881
- onError?.(error instanceof Error ? error : new Error('Failed to send message'));
882
- const errorMessage = {
883
- id: Date.now().toString(),
884
- content: 'Sorry, there was an error processing your message. Please try again.',
885
- role: 'assistant',
886
- timestamp: new Date().toISOString()
887
- };
888
- setMessages(prev => [...prev, errorMessage]);
889
- }
890
- finally {
891
- setIsLoading(false);
892
- }
893
- };
894
- const handlePresetMessage = (message) => {
895
- if (message.autoSend) {
896
- setMessages(prev => [...prev, {
897
- id: Date.now().toString(),
898
- content: message.text,
899
- role: 'user',
900
- timestamp: new Date().toISOString()
901
- }]);
902
- sendMessage(message.text);
903
- }
904
- else {
905
- setInputValue(message.text);
906
- }
907
- };
908
- const generateAndRegisterAIT = async () => {
909
- if (!signer || !hitAddress)
910
- return;
911
- const timestamp = Math.floor(Date.now() / 1000);
912
- const aitId = `did:polygon:ike-dashboard:${hitAddress}:${timestamp}`;
913
- const metadata = {
914
- model: 'gpt-4',
915
- permissions,
916
- issuedBy: hitAddress,
917
- };
918
- const metadataStr = stringify(metadata);
919
- const metadataHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(metadataStr));
920
- // 1️⃣ Upload metadata to Pinata, get CID
921
- const uploadResponse = await nxtlinqApi.metadata.createMetadata(metadata, nxtlinqAITServiceAccessToken || '');
922
- if ('error' in uploadResponse) {
923
- throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
924
- }
925
- const { metadataCid } = uploadResponse;
926
- await nxtlinqApi.ait.createAIT({
927
- aitId,
928
- controller: hitAddress,
929
- serviceId,
930
- metadataHash,
931
- metadataCid,
932
- }, nxtlinqAITServiceAccessToken || '');
933
- const aitInfo = {
934
- aitId,
935
- controller: hitAddress,
936
- metadata,
937
- metadataHash,
938
- metadataCid,
939
- };
940
- setAit(aitInfo);
941
- };
942
- const savePermissions = async () => {
943
- setIsDisabled(true);
944
- try {
945
- await generateAndRegisterAIT();
946
- setSuccess(true);
947
- setShowPermissionForm(false);
948
- setIsPermissionFormOpen(false);
949
- }
950
- catch (error) {
951
- console.error('Failed to generate AIT:', error);
952
- setIsDisabled(false);
953
- if (error instanceof Error) {
954
- alert(error.message);
955
- }
956
- }
957
- };
958
- // Add state change listener
959
- React.useEffect(() => {
960
- console.log('States updated:', {
961
- hitAddress,
962
- isNeedSignInWithWallet,
963
- walletInfo,
964
- isOpen
965
- });
966
- }, [hitAddress, isNeedSignInWithWallet, walletInfo, isOpen]);
967
- // Add useEffect to monitor message changes
968
- React.useEffect(() => {
969
- if (messages.length > 0) {
970
- const lastMessage = messages[messages.length - 1];
971
- onMessage?.(lastMessage);
972
- }
973
- }, [messages, onMessage]);
974
- // Auto hide success message after 3 seconds
975
- React.useEffect(() => {
976
- if (success) {
977
- const timer = setTimeout(() => {
978
- setSuccess(false);
979
- }, 3000);
980
- return () => clearTimeout(timer);
981
- }
982
- }, [success]);
983
- return (_jsxs("div", { style: {
984
- position: 'fixed',
985
- bottom: '20px',
986
- right: '20px',
987
- zIndex: 1000,
988
- display: 'flex',
989
- flexDirection: 'column',
990
- alignItems: 'flex-end',
991
- gap: '10px'
992
- }, children: [isOpen && (_jsxs("div", { className: `nxtlinq-chatbot ${className}`, style: {
993
- width: '350px',
994
- height: '500px',
995
- backgroundColor: 'white',
996
- borderRadius: '10px',
997
- boxShadow: '0 5px 15px rgba(0, 0, 0, 0.2)',
998
- display: 'flex',
999
- flexDirection: 'column',
1000
- overflow: 'hidden'
1001
- }, children: [_jsxs("div", { style: {
1002
- padding: '15px',
1003
- backgroundColor: '#007bff',
1004
- color: 'white',
1005
- borderRadius: '10px 10px 0 0',
1006
- display: 'flex',
1007
- justifyContent: 'space-between',
1008
- alignItems: 'center'
1009
- }, children: [_jsx("h3", { style: { margin: 0 }, children: "AI Agent" }), _jsxs("div", { style: { display: 'flex', gap: '10px' }, children: [_jsx("button", { onClick: async () => {
1010
- setShowPermissionForm(true);
1011
- setIsPermissionFormOpen(true);
1012
- // Force refresh AIT data when opening the form to show latest permissions
1013
- await refreshAIT(true);
1014
- }, style: {
1015
- background: 'none',
1016
- border: 'none',
1017
- color: 'white',
1018
- fontSize: '20px',
1019
- cursor: 'pointer',
1020
- padding: '0 5px'
1021
- }, children: "\u2699\uFE0F" }), _jsx("button", { onClick: () => setIsOpen(false), style: {
1022
- background: 'none',
1023
- border: 'none',
1024
- color: 'white',
1025
- fontSize: '24px',
1026
- cursor: 'pointer',
1027
- padding: '0 5px'
1028
- }, children: "\u00D7" })] })] }), _jsxs("div", { style: {
1029
- flex: 1,
1030
- overflowY: 'auto',
1031
- padding: '15px',
1032
- display: 'flex',
1033
- flexDirection: 'column',
1034
- gap: '10px'
1035
- }, children: [messages.map((message, index) => (_jsxs("div", { style: {
1036
- alignSelf: message.role === 'user' ? 'flex-end' : 'flex-start',
1037
- backgroundColor: message.role === 'user' ? '#007bff' : '#f0f0f0',
1038
- color: message.role === 'user' ? 'white' : 'black',
1039
- padding: '8px 12px',
1040
- borderRadius: '15px',
1041
- maxWidth: '80%',
1042
- wordBreak: 'break-word'
1043
- }, children: [message.content, message.button && (_jsx("button", { onClick: message.button === 'signIn' ? () => signInWallet(true) : () => connectWallet(true), disabled: message.button === 'signIn' ? (!hitAddress || !!ait) : !!hitAddress, style: {
1044
- display: 'block',
1045
- marginTop: '8px',
1046
- padding: '5px 10px',
1047
- backgroundColor: message.button === 'signIn' ? (hitAddress && !ait ? '#28a745' : '#ccc') : (hitAddress ? '#ccc' : '#28a745'),
1048
- color: 'white',
1049
- border: 'none',
1050
- borderRadius: '5px',
1051
- cursor: message.button === 'signIn' ? (hitAddress && !ait ? 'pointer' : 'not-allowed') : (hitAddress ? 'not-allowed' : 'pointer')
1052
- }, children: message.button === 'signIn' ? (!!ait ? 'Signed In' : 'Sign in HIT wallet') : (hitAddress ? 'Connected' : 'Connect HIT wallet') }))] }, index))), isLoading && (_jsx("div", { style: {
1053
- alignSelf: 'flex-start',
1054
- backgroundColor: '#f0f0f0',
1055
- padding: '8px 12px',
1056
- borderRadius: '15px',
1057
- maxWidth: '80%'
1058
- }, children: "Thinking..." })), _jsx("div", { ref: messagesEndRef })] }), _jsxs("div", { style: {
1059
- padding: '10px',
1060
- borderTop: '1px solid #eee',
1061
- display: 'flex',
1062
- flexDirection: 'column',
1063
- gap: '10px'
1064
- }, children: [_jsx("div", { style: {
1065
- display: 'flex',
1066
- gap: '5px',
1067
- overflowX: 'auto',
1068
- padding: '5px 0'
1069
- }, children: presetMessages.map((message, index) => (_jsx("button", { onClick: () => handlePresetMessage(message), style: {
1070
- padding: '5px 10px',
1071
- backgroundColor: '#f0f0f0',
1072
- border: 'none',
1073
- borderRadius: '15px',
1074
- cursor: 'pointer',
1075
- whiteSpace: 'nowrap',
1076
- fontSize: '12px'
1077
- }, children: message.text }, index))) }), _jsxs("form", { onSubmit: handleSubmit, style: {
1078
- display: 'flex',
1079
- gap: '10px'
1080
- }, children: [_jsx("input", { type: "text", value: inputValue, onChange: (e) => setInputValue(e.target.value), placeholder: placeholder, style: {
1081
- flex: 1,
1082
- padding: '8px 12px',
1083
- border: '1px solid #ddd',
1084
- borderRadius: '20px',
1085
- fontSize: '14px',
1086
- outline: 'none'
1087
- } }), _jsx("button", { type: "submit", disabled: isLoading, style: {
1088
- backgroundColor: '#007bff',
1089
- color: 'white',
1090
- border: 'none',
1091
- borderRadius: '20px',
1092
- padding: '8px 20px',
1093
- cursor: isLoading ? 'not-allowed' : 'pointer',
1094
- fontSize: '14px',
1095
- opacity: isLoading ? 0.7 : 1
1096
- }, children: "Send" })] })] })] })), _jsx("button", { onClick: () => setIsOpen(!isOpen), style: {
1097
- width: '120px',
1098
- height: '40px',
1099
- borderRadius: '20px',
1100
- backgroundColor: '#007bff',
1101
- color: '#ffffff',
1102
- border: 'none',
1103
- cursor: 'pointer',
1104
- display: 'flex',
1105
- alignItems: 'center',
1106
- justifyContent: 'center',
1107
- fontSize: '14px',
1108
- fontWeight: 'bold',
1109
- boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
1110
- transition: 'all 0.3s ease-in-out',
1111
- padding: '0 20px'
1112
- }, children: "AI Agent" }), showPermissionForm && (_jsx("div", { style: {
1113
- position: 'fixed',
1114
- top: 0,
1115
- left: 0,
1116
- right: 0,
1117
- bottom: 0,
1118
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
1119
- display: 'flex',
1120
- alignItems: 'center',
1121
- justifyContent: 'center',
1122
- zIndex: 2000
1123
- }, children: _jsx(PermissionForm, { hitAddress: hitAddress, permissions: permissions, setPermissions: setPermissions, setIsDisabled: setIsDisabled, onClose: () => {
1124
- setShowPermissionForm(false);
1125
- setIsPermissionFormOpen(false);
1126
- }, onConnectWallet: () => connectWallet(false), onSignIn: () => signInWallet(false), onSave: savePermissions, isNeedSignInWithWallet: isNeedSignInWithWallet, walletInfo: walletInfo, onVerifyWallet: handleVerifyWalletClick, serviceId: serviceId, nxtlinqApi: nxtlinqApi, permissionGroup: permissionGroup, isAITLoading: isAITLoading, isWalletLoading: isWalletLoading }) })), success && (_jsxs("div", { style: {
1127
- position: 'fixed',
1128
- bottom: 100,
1129
- right: 40,
1130
- background: '#4caf50',
1131
- color: 'white',
1132
- padding: '12px 24px',
1133
- borderRadius: 8,
1134
- zIndex: 2000,
1135
- fontWeight: 600,
1136
- }, children: ["Saved successfully!", _jsx("button", { style: {
1137
- background: 'none',
1138
- border: 'none',
1139
- color: 'white',
1140
- marginLeft: 16,
1141
- fontSize: 18,
1142
- cursor: 'pointer'
1143
- }, onClick: () => setSuccess(false), children: "\u00D7" })] }))] }));
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ChatBotProvider } from './context/ChatBotContext';
3
+ import { ChatBotUI } from './ui/ChatBotUI';
4
+ export const ChatBot = (props) => {
5
+ return (_jsx(ChatBotProvider, { ...props, children: _jsx(ChatBotUI, {}) }));
1144
6
  };