@bytexbyte/nxtlinq-ai-agent-sdk 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # Nxtlinq AI Agent SDK
2
+
3
+ A powerful SDK for building intelligent conversation applications with Nxtlinq AI Agent.
4
+
5
+ ## Features
6
+
7
+ - 💬 Real-time chat interface with AI Agent
8
+ - 🎯 Preset messages for quick interactions
9
+ - 🛠️ Tool integration support
10
+ - 🔄 Automatic retry mechanism for failed requests
11
+ - 📱 Responsive and modern UI design
12
+ - 🎨 Customizable styling
13
+ - 🔌 Easy integration with React applications
14
+ - 🔒 Secure authentication and API key management
15
+ - 👛 MetaMask wallet integration
16
+ - 🔐 AIT (AI Token) management
17
+ - 🔑 Permission-based access control
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @bytexbyte/nxtlinq-ai-agent-sdk
23
+ # or
24
+ yarn add @bytexbyte/nxtlinq-ai-agent-sdk
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ```tsx
30
+ import { ChatBot } from '@bytexbyte/nxtlinq-ai-agent-sdk';
31
+
32
+ function App() {
33
+ const handleMessage = (message) => {
34
+ console.log('Received new message:', message);
35
+ };
36
+
37
+ const handleToolUse = async (toolUse) => {
38
+ console.log('Tool use:', toolUse);
39
+ return {
40
+ id: Date.now().toString(),
41
+ content: 'Tool execution response',
42
+ role: 'assistant',
43
+ timestamp: new Date().toISOString()
44
+ };
45
+ };
46
+
47
+ const presetMessages = [
48
+ { text: 'Hello, how can you help me?' },
49
+ { text: 'I want to add a new member' },
50
+ { text: 'I want to view the analytics page' },
51
+ { text: 'I want to change my name' }
52
+ ];
53
+
54
+ return (
55
+ <ChatBot
56
+ serviceId="your-service-id"
57
+ apiKey="your-api-key"
58
+ apiSecret="your-api-secret"
59
+ onMessage={handleMessage}
60
+ onToolUse={handleToolUse}
61
+ presetMessages={presetMessages}
62
+ onVerifyWallet={async (address) => {
63
+ // Implement your wallet verification logic here
64
+ return { token: 'verification-token' };
65
+ }}
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## API Reference
72
+
73
+ ### NxtlinqAITSDK
74
+
75
+ | Method | Description |
76
+ |--------|-------------|
77
+ | `connectWallet()` | Connect to MetaMask wallet |
78
+ | `verifyWallet(token: string, method: string)` | Verify wallet ownership |
79
+ | `signInWithWallet()` | Sign in using wallet |
80
+ | `generateAndRegisterAIT(permissions: string[])` | Generate and register a new AIT |
81
+ | `getAIT()` | Get AIT information |
82
+ | `getWalletInfo()` | Get wallet information |
83
+
84
+ ### NxtlinqAIAgent
85
+
86
+ | Method | Description |
87
+ |--------|-------------|
88
+ | `setAIT(ait: AIT, signer?: ethers.Signer)` | Set AIT for the agent |
89
+ | `generateAIT(options: GenerateAITOptions)` | Generate a new AIT |
90
+ | `getAITInfo(serviceId: string, controller: string, signer?: ethers.Signer)` | Get AIT information |
91
+ | `sendMessage(message: string, toolName?: string)` | Send a message to the agent |
92
+
93
+ ### API Endpoints
94
+
95
+ #### AIT API
96
+ - `getAITByServiceIdAndController`: Get AIT by service ID and controller
97
+ - `createAIT`: Create a new AIT
98
+
99
+ #### Wallet API
100
+ - `verifyWallet`: Verify wallet ownership
101
+ - `getWallet`: Get wallet information
102
+
103
+ #### Metadata API
104
+ - `createMetadata`: Create metadata for AIT
105
+
106
+ #### Auth API
107
+ - `getNonce`: Get nonce for wallet sign-in
108
+ - `signIn`: Sign in with wallet
109
+
110
+ #### Agent API
111
+ - `sendMessage`: Send message to AI agent
112
+
113
+ ### ChatBot Component Props
114
+
115
+ | Prop | Type | Required | Description |
116
+ |------|------|----------|-------------|
117
+ | serviceId | string | Yes | Your Nxtlinq service ID |
118
+ | apiKey | string | Yes | Your Nxtlinq API key |
119
+ | apiSecret | string | Yes | Your Nxtlinq API secret |
120
+ | onMessage | (message: Message) => void | No | Callback when a new message is received |
121
+ | onError | (error: Error) => void | No | Callback when an error occurs |
122
+ | onToolUse | (toolUse: ToolUse) => Promise<Message \| void> | No | Callback for handling tool usage |
123
+ | onVerifyWallet | (address: string) => Promise<{ token: string }> | Yes | Callback for wallet verification |
124
+ | presetMessages | PresetMessage[] | No | Array of preset messages to display |
125
+ | placeholder | string | No | Input placeholder text (default: "Type a message...") |
126
+ | className | string | No | Additional CSS class name |
127
+ | maxRetries | number | No | Maximum number of retry attempts (default: 3) |
128
+ | retryDelay | number | No | Delay between retries in milliseconds (default: 1000) |
129
+
130
+ ## Types
131
+
132
+ ### Message
133
+ ```typescript
134
+ interface Message {
135
+ id: string;
136
+ content: string;
137
+ role: 'user' | 'assistant';
138
+ timestamp: string;
139
+ button?: boolean;
140
+ error?: string;
141
+ }
142
+ ```
143
+
144
+ ### PresetMessage
145
+ ```typescript
146
+ interface PresetMessage {
147
+ text: string;
148
+ autoSend?: boolean;
149
+ }
150
+ ```
151
+
152
+ ### ToolUse
153
+ ```typescript
154
+ interface ToolUse {
155
+ name: string;
156
+ input: Record<string, any>;
157
+ }
158
+ ```
159
+
160
+ ### AIT
161
+ ```typescript
162
+ interface AIT {
163
+ aitId: string;
164
+ controller: string;
165
+ metadata: AITMetadata;
166
+ metadataHash: string;
167
+ metadataCid: string;
168
+ signature: string;
169
+ }
170
+
171
+ interface AITMetadata {
172
+ model: string;
173
+ permissions: string[];
174
+ issuedBy: string;
175
+ serviceId?: string;
176
+ }
177
+
178
+ interface AITInfo {
179
+ aitId: string;
180
+ controller: string;
181
+ metadata: AITMetadata;
182
+ metadataHash: string;
183
+ metadataCid: string;
184
+ signature: string;
185
+ }
186
+
187
+ interface AITPermission {
188
+ hasPermission: boolean;
189
+ reason?: string;
190
+ permissions?: string[];
191
+ }
192
+
193
+ interface GenerateAITOptions {
194
+ hitAddress: string;
195
+ signer: ethers.Signer;
196
+ permissions: string[];
197
+ serviceId: string;
198
+ }
199
+
200
+ interface WalletInfo {
201
+ id: string;
202
+ address: string;
203
+ verified: boolean;
204
+ method?: string;
205
+ }
206
+
207
+ interface MessageContext {
208
+ aitId?: string;
209
+ walletAddress?: string | null;
210
+ }
211
+ ```
212
+
213
+ ## Features
214
+
215
+ ### Wallet Integration
216
+ - MetaMask wallet connection
217
+ - Wallet verification
218
+ - Wallet-based authentication
219
+ - AIT (AI Token) generation and management
220
+
221
+ ### Available Permissions
222
+ - Set User Name
223
+ - Navigate To Page
224
+ - Add Member
225
+
226
+ ### Authentication Flow
227
+ 1. Connect MetaMask wallet
228
+ 2. Verify wallet ownership
229
+ 3. Sign in with wallet
230
+ 4. Generate and register AIT with required permissions
231
+ 5. Use AIT for authenticated operations
232
+
233
+ ## Error Handling
234
+
235
+ The SDK includes built-in error handling with:
236
+ - Automatic retry mechanism for failed requests
237
+ - Error callback for custom error handling
238
+ - User-friendly error messages
239
+ - Wallet connection error handling
240
+ - Authentication error handling
241
+
242
+ ## Best Practices
243
+
244
+ 1. Implement proper wallet verification logic
245
+ 2. Handle AIT permissions appropriately
246
+ 3. Set appropriate timeout values
247
+ 4. Implement error retry mechanisms
248
+ 5. Use context management to maintain conversation coherence
249
+ 6. Handle wallet connection errors gracefully
250
+ 7. Implement proper error handling for authentication flow
251
+
252
+ ## License
253
+
254
+ Proprietary - All Rights Reserved
255
+
256
+ Copyright (c) 2025 ByteXByte. All rights reserved.
257
+
258
+ This software and associated documentation files (the "Software") are proprietary and confidential. The Software is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties.
259
+
260
+ Unauthorized copying, distribution, modification, public display, or public performance of the Software is strictly prohibited. The Software may only be used in accordance with the terms of a valid license agreement with ByteXByte.
261
+
262
+ For licensing inquiries, please contact: [Your Contact Information]
package/dist/index.js ADDED
@@ -0,0 +1,301 @@
1
+ import { ethers } from 'ethers';
2
+ import stringify from 'json-stable-stringify';
3
+ import { createNxtlinqApi } from './api/nxtlinq-api';
4
+ export { ChatBot } from './components/ChatBot';
5
+ export class NxtlinqAITSDK {
6
+ constructor(serviceId, apiKey, apiSecret) {
7
+ this.signer = null;
8
+ this.walletAddress = null;
9
+ this.serviceId = serviceId;
10
+ this.api = createNxtlinqApi(apiKey, apiSecret);
11
+ }
12
+ async connectWallet() {
13
+ if (typeof window === 'undefined' || !window.ethereum) {
14
+ throw new Error('MetaMask is not installed');
15
+ }
16
+ const provider = new ethers.BrowserProvider(window.ethereum);
17
+ this.signer = await provider.getSigner();
18
+ this.walletAddress = await this.signer.getAddress();
19
+ return this.walletAddress;
20
+ }
21
+ async verifyWallet(token, method) {
22
+ if (!this.walletAddress) {
23
+ throw new Error('Please connect wallet first');
24
+ }
25
+ const response = await this.api.wallet.verifyWallet({
26
+ address: this.walletAddress,
27
+ token,
28
+ method,
29
+ timestamp: Date.now()
30
+ }, token);
31
+ if ('error' in response) {
32
+ throw new Error(response.error);
33
+ }
34
+ return response;
35
+ }
36
+ async signInWithWallet() {
37
+ if (!this.walletAddress || !this.signer) {
38
+ throw new Error('Please connect wallet first');
39
+ }
40
+ const nonceResponse = await this.api.auth.getNonce({ address: this.walletAddress });
41
+ if ('error' in nonceResponse) {
42
+ throw new Error(nonceResponse.error);
43
+ }
44
+ const payload = {
45
+ address: this.walletAddress,
46
+ code: nonceResponse.code,
47
+ timestamp: nonceResponse.timestamp
48
+ };
49
+ const stringToSign = stringify(payload);
50
+ const signature = await this.signer.signMessage(stringToSign || '');
51
+ const response = await this.api.auth.signIn({
52
+ ...payload,
53
+ signature
54
+ });
55
+ if ('error' in response) {
56
+ throw new Error(response.error);
57
+ }
58
+ return response.accessToken;
59
+ }
60
+ async generateAndRegisterAIT(permissions) {
61
+ if (!this.signer || !this.walletAddress) {
62
+ throw new Error('Please connect wallet first');
63
+ }
64
+ const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
65
+ if (!token) {
66
+ throw new Error('未找到访问令牌');
67
+ }
68
+ const timestamp = Math.floor(Date.now() / 1000);
69
+ const aitId = `did:polygon:ike-dashboard:${this.walletAddress}:${timestamp}`;
70
+ const metadata = {
71
+ model: 'gpt-4',
72
+ permissions,
73
+ issuedBy: this.walletAddress
74
+ };
75
+ const metadataStr = stringify(metadata);
76
+ const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr || ''));
77
+ // Upload metadata
78
+ const uploadResponse = await this.api.metadata.createMetadata({
79
+ ...metadata,
80
+ controller: this.walletAddress
81
+ }, token);
82
+ if ('error' in uploadResponse) {
83
+ throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
84
+ }
85
+ const { metadataCid } = uploadResponse;
86
+ // Sign the message
87
+ const messageHash = ethers.solidityPackedKeccak256(['string', 'address', 'string', 'bytes32', 'uint256'], [aitId, this.walletAddress, this.serviceId, metadataHash, timestamp]);
88
+ const signature = await this.signer.signMessage(ethers.getBytes(messageHash));
89
+ // Register AIT
90
+ const response = await this.api.ait.createAIT({
91
+ aitId,
92
+ controller: this.walletAddress,
93
+ serviceId: this.serviceId,
94
+ metadataHash,
95
+ metadataCid,
96
+ timestamp,
97
+ signature
98
+ }, token);
99
+ if ('error' in response) {
100
+ throw new Error(response.error);
101
+ }
102
+ return response;
103
+ }
104
+ async getAIT() {
105
+ if (!this.walletAddress) {
106
+ return null;
107
+ }
108
+ const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
109
+ if (!token) {
110
+ throw new Error('未找到访问令牌');
111
+ }
112
+ const response = await this.api.ait.getAITByServiceIdAndController({
113
+ serviceId: this.serviceId,
114
+ controller: this.walletAddress
115
+ }, token);
116
+ if ('error' in response) {
117
+ return null;
118
+ }
119
+ return response;
120
+ }
121
+ async getWalletInfo() {
122
+ if (!this.walletAddress) {
123
+ return null;
124
+ }
125
+ const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
126
+ if (!token) {
127
+ throw new Error('未找到访问令牌');
128
+ }
129
+ const response = await this.api.wallet.getWallet({ address: this.walletAddress }, token);
130
+ if ('error' in response) {
131
+ return null;
132
+ }
133
+ return response;
134
+ }
135
+ createPermissionForm(permissionGroups) {
136
+ return permissionGroups.map(group => ({
137
+ label: group.label,
138
+ options: group.options.map((option) => ({
139
+ ...option,
140
+ isChecked: false,
141
+ }))
142
+ }));
143
+ }
144
+ getSelectedPermissions(form) {
145
+ return form.flatMap(group => group.options.filter((opt) => opt.isChecked).map((opt) => opt.value));
146
+ }
147
+ }
148
+ export class NxtlinqAIAgent {
149
+ constructor(projectId, apiKey, apiSecret) {
150
+ this.permissions = [];
151
+ this.projectId = projectId;
152
+ this.apiKey = apiKey;
153
+ this.api = createNxtlinqApi(apiKey, apiSecret);
154
+ }
155
+ setAIT(ait, signer) {
156
+ this.ait = ait;
157
+ this.permissions = ait.metadata.permissions;
158
+ if (signer) {
159
+ this.signer = signer;
160
+ }
161
+ }
162
+ async hasPermission(toolName) {
163
+ if (!this.ait) {
164
+ throw new Error('请先连接钱包以访问权限');
165
+ }
166
+ return this.permissions.includes(toolName);
167
+ }
168
+ async checkAITPermission(toolName) {
169
+ try {
170
+ if (!this.ait) {
171
+ return {
172
+ hasPermission: false,
173
+ reason: '请先连接钱包以访问权限'
174
+ };
175
+ }
176
+ if (!toolName) {
177
+ return {
178
+ hasPermission: true,
179
+ permissions: this.permissions
180
+ };
181
+ }
182
+ const hasPermission = await this.hasPermission(toolName);
183
+ return {
184
+ hasPermission,
185
+ reason: hasPermission ? undefined : '没有权限使用该工具',
186
+ permissions: this.permissions
187
+ };
188
+ }
189
+ catch (error) {
190
+ return {
191
+ hasPermission: false,
192
+ reason: error instanceof Error ? error.message : '未知错误',
193
+ permissions: this.permissions
194
+ };
195
+ }
196
+ }
197
+ async generateAIT(options) {
198
+ const { hitAddress, signer, permissions, serviceId } = options;
199
+ const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
200
+ if (!token) {
201
+ throw new Error('未找到访问令牌');
202
+ }
203
+ const timestamp = Math.floor(Date.now() / 1000);
204
+ const aitId = `did:polygon:ike-dashboard:${hitAddress}:${timestamp}`;
205
+ const metadata = {
206
+ model: 'gpt-4',
207
+ permissions,
208
+ issuedBy: hitAddress
209
+ };
210
+ const metadataStr = stringify(metadata);
211
+ const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr || ''));
212
+ // Upload metadata
213
+ const uploadResponse = await this.api.metadata.createMetadata({
214
+ ...metadata,
215
+ controller: hitAddress
216
+ }, token);
217
+ if ('error' in uploadResponse) {
218
+ throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
219
+ }
220
+ const { metadataCid } = uploadResponse;
221
+ // Sign the message
222
+ const messageHash = ethers.solidityPackedKeccak256(['string', 'address', 'string', 'bytes32', 'uint256'], [aitId, hitAddress, serviceId, metadataHash, timestamp]);
223
+ const signature = await signer.signMessage(ethers.getBytes(messageHash));
224
+ // Register AIT
225
+ const response = await this.api.ait.createAIT({
226
+ aitId,
227
+ controller: hitAddress,
228
+ serviceId,
229
+ metadataHash,
230
+ metadataCid,
231
+ timestamp,
232
+ signature
233
+ }, token);
234
+ if ('error' in response) {
235
+ throw new Error(response.error);
236
+ }
237
+ return {
238
+ aitId: response.aitId,
239
+ controller: response.controller,
240
+ metadata: response.metadata,
241
+ metadataHash: response.metadataHash,
242
+ metadataCid: response.metadataCid,
243
+ signature: response.signature
244
+ };
245
+ }
246
+ async getAITInfo(serviceId, controller, signer) {
247
+ const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
248
+ if (!token) {
249
+ throw new Error('未找到访问令牌');
250
+ }
251
+ const response = await this.api.ait.getAITByServiceIdAndController({
252
+ serviceId,
253
+ controller
254
+ }, token);
255
+ if ('error' in response) {
256
+ return null;
257
+ }
258
+ if (signer) {
259
+ this.signer = signer;
260
+ }
261
+ return {
262
+ aitId: response.aitId,
263
+ controller: response.controller,
264
+ metadata: response.metadata,
265
+ metadataHash: response.metadataHash,
266
+ metadataCid: response.metadataCid,
267
+ signature: response.signature
268
+ };
269
+ }
270
+ async sendMessage(message, toolName) {
271
+ const permission = await this.checkAITPermission(toolName);
272
+ if (!permission.hasPermission) {
273
+ throw new Error(permission.reason || '没有权限使用该工具');
274
+ }
275
+ if (!this.ait || !this.signer) {
276
+ throw new Error('请先连接钱包以访问权限');
277
+ }
278
+ const timestamp = Math.floor(Date.now() / 1000);
279
+ const stringToSign = stringify({
280
+ message,
281
+ aitId: this.ait.aitId,
282
+ controller: this.ait.controller,
283
+ metadata: this.ait.metadata,
284
+ metadataHash: this.ait.metadataHash,
285
+ serviceId: this.projectId,
286
+ timestamp
287
+ }) || '';
288
+ const signature = await this.signer.signMessage(stringToSign);
289
+ const response = await this.api.agent.sendMessage({
290
+ message,
291
+ serviceId: this.projectId,
292
+ });
293
+ if ('error' in response) {
294
+ throw new Error(response.error);
295
+ }
296
+ return {
297
+ reply: response.reply,
298
+ timestamp: new Date().toISOString()
299
+ };
300
+ }
301
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@bytexbyte/nxtlinq-ai-agent-sdk",
3
+ "version": "1.0.2",
4
+ "description": "Nxtlinq AI Agent SDK - Proprietary Software",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "jest"
10
+ },
11
+ "keywords": [
12
+ "nxtlinq",
13
+ "ai",
14
+ "agent",
15
+ "sdk"
16
+ ],
17
+ "author": "ByteXByte",
18
+ "license": "UNLICENSED",
19
+ "private": false,
20
+ "peerDependencies": {
21
+ "react": "^18.2.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/jest": "^29.5.12",
25
+ "@types/json-stable-stringify": "^1.0.34",
26
+ "@types/react": "^18.2.64",
27
+ "jest": "^29.7.0",
28
+ "typescript": "^5.4.2"
29
+ },
30
+ "dependencies": {
31
+ "@emotion/react": "^11.11.4",
32
+ "@emotion/styled": "^11.11.0",
33
+ "@mui/material": "^5.15.12",
34
+ "ethers": "^6.11.1",
35
+ "json-stable-stringify": "^1.0.2",
36
+ "metakeep": "^2.2.8"
37
+ }
38
+ }