@bytexbyte/nxtlinq-ai-agent-sdk 1.0.7 → 1.0.9

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.
@@ -1,13 +0,0 @@
1
- import { MetaKeep } from 'metakeep';
2
-
3
- const metakeepClient = new MetaKeep({
4
- appId: 'e7d521f7-3eea-42d7-af42-4d8b962d9a6d',
5
- chainId: 80002,
6
- /* RPC node urls map */
7
- rpcNodeUrls: {
8
- // Update with your node API key
9
- 80002: 'https://rpc-amoy.polygon.technology'
10
- }
11
- });
12
-
13
- export default metakeepClient;
@@ -1,99 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
- import { NxtlinqAITSDK } from '../index';
3
- import { AITInfo, WalletInfo } from '../types/ait-api';
4
-
5
- export function useNxtlinqAIT(sdk: NxtlinqAITSDK) {
6
- const [walletAddress, setWalletAddress] = useState<string | null>(null);
7
- const [walletInfo, setWalletInfo] = useState<WalletInfo | null>(null);
8
- const [ait, setAit] = useState<AITInfo | null>(null);
9
- const [isLoading, setIsLoading] = useState(false);
10
- const [error, setError] = useState<string | null>(null);
11
-
12
- const connectWallet = async () => {
13
- try {
14
- setIsLoading(true);
15
- setError(null);
16
- const address = await sdk.connectWallet();
17
- setWalletAddress(address);
18
- } catch (err) {
19
- setError(err instanceof Error ? err.message : 'Failed to connect wallet');
20
- } finally {
21
- setIsLoading(false);
22
- }
23
- };
24
-
25
- const verifyWallet = async (token: string, method: string) => {
26
- try {
27
- setIsLoading(true);
28
- setError(null);
29
- const info = await sdk.verifyWallet(token, method);
30
- setWalletInfo(info);
31
- return info;
32
- } catch (err) {
33
- setError(err instanceof Error ? err.message : 'Failed to verify wallet');
34
- throw err;
35
- } finally {
36
- setIsLoading(false);
37
- }
38
- };
39
-
40
- const signInWithWallet = async () => {
41
- try {
42
- setIsLoading(true);
43
- setError(null);
44
- const token = await sdk.signInWithWallet();
45
- return token;
46
- } catch (err) {
47
- setError(err instanceof Error ? err.message : 'Failed to sign in with wallet');
48
- throw err;
49
- } finally {
50
- setIsLoading(false);
51
- }
52
- };
53
-
54
- const generateAndRegisterAIT = async (permissions: string[]) => {
55
- try {
56
- setIsLoading(true);
57
- setError(null);
58
- const aitInfo = await sdk.generateAndRegisterAIT(permissions);
59
- setAit(aitInfo);
60
- return aitInfo;
61
- } catch (err) {
62
- setError(err instanceof Error ? err.message : 'Failed to generate AIT');
63
- throw err;
64
- } finally {
65
- setIsLoading(false);
66
- }
67
- };
68
-
69
- useEffect(() => {
70
- const loadData = async () => {
71
- if (walletAddress) {
72
- try {
73
- const [walletInfo, aitInfo] = await Promise.all([
74
- sdk.getWalletInfo(),
75
- sdk.getAIT()
76
- ]);
77
- setWalletInfo(walletInfo);
78
- setAit(aitInfo);
79
- } catch (err) {
80
- console.error('Failed to load wallet info or AIT:', err);
81
- }
82
- }
83
- };
84
-
85
- loadData();
86
- }, [walletAddress, sdk]);
87
-
88
- return {
89
- walletAddress,
90
- walletInfo,
91
- ait,
92
- isLoading,
93
- error,
94
- connectWallet,
95
- verifyWallet,
96
- signInWithWallet,
97
- generateAndRegisterAIT
98
- };
99
- }
package/src/index.ts DELETED
@@ -1,449 +0,0 @@
1
- import { ethers } from 'ethers';
2
- import stringify from 'json-stable-stringify';
3
- import { AITInfo, AITMetadata, PermissionGroup, PermissionOption, WalletInfo, CreateAITParams, CreateMetadataParams, VerifyWalletParams, SignInParams } from './types/ait-api';
4
- import { createNxtlinqApi } from './api/nxtlinq-api';
5
-
6
- export { ChatBot } from './components/ChatBot';
7
- export type { Message, PresetMessage, ToolUse, ChatBotProps } from './components/ChatBot';
8
-
9
- // 导出类型
10
- export type {
11
- AITInfo,
12
- AITMetadata,
13
- PermissionGroup,
14
- PermissionOption,
15
- WalletInfo,
16
- CreateAITParams,
17
- CreateMetadataParams,
18
- VerifyWalletParams,
19
- SignInParams
20
- };
21
-
22
- export interface AITPermission {
23
- hasPermission: boolean;
24
- reason?: string;
25
- permissions?: string[];
26
- }
27
-
28
- export interface AIT {
29
- aitId: string;
30
- controller: string;
31
- metadata: AITMetadata;
32
- metadataHash: string;
33
- metadataCid: string;
34
- signature: string;
35
- }
36
-
37
- export interface GenerateAITOptions {
38
- hitAddress: string;
39
- signer: ethers.Signer;
40
- permissions: string[];
41
- serviceId: string;
42
- }
43
-
44
- export interface MessageResponse {
45
- reply: string;
46
- timestamp: string;
47
- }
48
-
49
- export class NxtlinqAITSDK {
50
- private serviceId: string;
51
- private signer: ethers.Signer | null = null;
52
- private walletAddress: string | null = null;
53
- private api: AITApi;
54
-
55
- constructor(serviceId: string, apiKey: string, apiSecret: string) {
56
- this.serviceId = serviceId;
57
- this.api = createNxtlinqApi(apiKey, apiSecret);
58
- }
59
-
60
- async connectWallet(): Promise<string> {
61
- if (typeof window === 'undefined' || !window.ethereum) {
62
- throw new Error('MetaMask is not installed');
63
- }
64
-
65
- const provider = new ethers.BrowserProvider(window.ethereum);
66
- this.signer = await provider.getSigner();
67
- this.walletAddress = await this.signer.getAddress();
68
- return this.walletAddress;
69
- }
70
-
71
- async verifyWallet(token: string, method: string): Promise<WalletInfo> {
72
- if (!this.walletAddress) {
73
- throw new Error('Please connect wallet first');
74
- }
75
-
76
- const response = await this.api.wallet.verifyWallet({
77
- address: this.walletAddress,
78
- token,
79
- method,
80
- timestamp: Date.now()
81
- }, token);
82
-
83
- if ('error' in response) {
84
- throw new Error(response.error);
85
- }
86
-
87
- return response;
88
- }
89
-
90
- async signInWithWallet(): Promise<string> {
91
- if (!this.walletAddress || !this.signer) {
92
- throw new Error('Please connect wallet first');
93
- }
94
-
95
- const nonceResponse = await this.api.auth.getNonce({ address: this.walletAddress });
96
- if ('error' in nonceResponse) {
97
- throw new Error(nonceResponse.error);
98
- }
99
-
100
- const payload = {
101
- address: this.walletAddress,
102
- code: nonceResponse.code,
103
- timestamp: nonceResponse.timestamp
104
- };
105
-
106
- const stringToSign = stringify(payload);
107
- const signature = await this.signer.signMessage(stringToSign || '');
108
-
109
- const response = await this.api.auth.signIn({
110
- ...payload,
111
- signature
112
- });
113
-
114
- if ('error' in response) {
115
- throw new Error(response.error);
116
- }
117
-
118
- return response.accessToken;
119
- }
120
-
121
- async generateAndRegisterAIT(permissions: string[]): Promise<AITInfo> {
122
- if (!this.signer || !this.walletAddress) {
123
- throw new Error('Please connect wallet first');
124
- }
125
-
126
- const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
127
- if (!token) {
128
- throw new Error('未找到访问令牌');
129
- }
130
-
131
- const timestamp = Math.floor(Date.now() / 1000);
132
- const aitId = `did:polygon:ike-dashboard:${this.walletAddress}:${timestamp}`;
133
-
134
- const metadata: AITMetadata = {
135
- model: 'gpt-4',
136
- permissions,
137
- issuedBy: this.walletAddress
138
- };
139
-
140
- const metadataStr = stringify(metadata);
141
- const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr || ''));
142
-
143
- // Upload metadata
144
- const uploadResponse = await this.api.metadata.createMetadata({
145
- ...metadata,
146
- controller: this.walletAddress
147
- }, token);
148
-
149
- if ('error' in uploadResponse) {
150
- throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
151
- }
152
-
153
- const { metadataCid } = uploadResponse;
154
-
155
- // Sign the message
156
- const messageHash = ethers.solidityPackedKeccak256(
157
- ['string', 'address', 'string', 'bytes32', 'uint256'],
158
- [aitId, this.walletAddress, this.serviceId, metadataHash, timestamp]
159
- );
160
-
161
- const signature = await this.signer.signMessage(ethers.getBytes(messageHash));
162
-
163
- // Register AIT
164
- const response = await this.api.ait.createAIT({
165
- aitId,
166
- controller: this.walletAddress,
167
- serviceId: this.serviceId,
168
- metadataHash,
169
- metadataCid,
170
- timestamp,
171
- signature
172
- }, token);
173
-
174
- if ('error' in response) {
175
- throw new Error(response.error);
176
- }
177
-
178
- return response;
179
- }
180
-
181
- async getAIT(): Promise<AITInfo | null> {
182
- if (!this.walletAddress) {
183
- return null;
184
- }
185
-
186
- const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
187
- if (!token) {
188
- throw new Error('未找到访问令牌');
189
- }
190
-
191
- const response = await this.api.ait.getAITByServiceIdAndController({
192
- serviceId: this.serviceId,
193
- controller: this.walletAddress
194
- }, token);
195
-
196
- if ('error' in response) {
197
- return null;
198
- }
199
-
200
- return response;
201
- }
202
-
203
- async getWalletInfo(): Promise<WalletInfo | null> {
204
- if (!this.walletAddress) {
205
- return null;
206
- }
207
-
208
- const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
209
- if (!token) {
210
- throw new Error('未找到访问令牌');
211
- }
212
-
213
- const response = await this.api.wallet.getWallet({ address: this.walletAddress }, token);
214
- if ('error' in response) {
215
- return null;
216
- }
217
-
218
- return response;
219
- }
220
-
221
- createPermissionForm(permissionGroups: PermissionGroup[]): PermissionGroup[] {
222
- return permissionGroups.map(group => ({
223
- label: group.label,
224
- options: group.options.map((option: PermissionOption) => ({
225
- ...option,
226
- isChecked: false,
227
- }))
228
- }));
229
- }
230
-
231
- getSelectedPermissions(form: PermissionGroup[]): string[] {
232
- return form.flatMap(group =>
233
- group.options.filter((opt: PermissionOption) => opt.isChecked).map((opt: PermissionOption) => opt.value)
234
- );
235
- }
236
- }
237
-
238
- export class NxtlinqAIAgent {
239
- private projectId: string;
240
- private apiKey?: string;
241
- private ait?: AIT;
242
- private permissions: string[] = [];
243
- private signer?: ethers.Signer;
244
- private api: AITApi;
245
-
246
- constructor(projectId: string, apiKey: string, apiSecret: string) {
247
- this.projectId = projectId;
248
- this.apiKey = apiKey;
249
- this.api = createNxtlinqApi(apiKey, apiSecret);
250
- }
251
-
252
- setAIT(ait: AIT, signer?: ethers.Signer) {
253
- this.ait = ait;
254
- this.permissions = ait.metadata.permissions;
255
- if (signer) {
256
- this.signer = signer;
257
- }
258
- }
259
-
260
- private async hasPermission(toolName: string): Promise<boolean> {
261
- if (!this.ait) {
262
- throw new Error('请先连接钱包以访问权限');
263
- }
264
- return this.permissions.includes(toolName);
265
- }
266
-
267
- private async checkAITPermission(toolName?: string): Promise<AITPermission> {
268
- try {
269
- if (!this.ait) {
270
- return {
271
- hasPermission: false,
272
- reason: '请先连接钱包以访问权限'
273
- };
274
- }
275
-
276
- if (!toolName) {
277
- return {
278
- hasPermission: true,
279
- permissions: this.permissions
280
- };
281
- }
282
-
283
- const hasPermission = await this.hasPermission(toolName);
284
- return {
285
- hasPermission,
286
- reason: hasPermission ? undefined : '没有权限使用该工具',
287
- permissions: this.permissions
288
- };
289
- } catch (error) {
290
- return {
291
- hasPermission: false,
292
- reason: error instanceof Error ? error.message : '未知错误',
293
- permissions: this.permissions
294
- };
295
- }
296
- }
297
-
298
- async generateAIT(options: GenerateAITOptions): Promise<AIT> {
299
- const { hitAddress, signer, permissions, serviceId } = options;
300
- const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
301
- if (!token) {
302
- throw new Error('未找到访问令牌');
303
- }
304
-
305
- const timestamp = Math.floor(Date.now() / 1000);
306
- const aitId = `did:polygon:ike-dashboard:${hitAddress}:${timestamp}`;
307
-
308
- const metadata: AITMetadata = {
309
- model: 'gpt-4',
310
- permissions,
311
- issuedBy: hitAddress
312
- };
313
-
314
- const metadataStr = stringify(metadata);
315
- const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr || ''));
316
-
317
- // Upload metadata
318
- const uploadResponse = await this.api.metadata.createMetadata({
319
- ...metadata,
320
- controller: hitAddress
321
- }, token);
322
-
323
- if ('error' in uploadResponse) {
324
- throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
325
- }
326
-
327
- const { metadataCid } = uploadResponse;
328
-
329
- // Sign the message
330
- const messageHash = ethers.solidityPackedKeccak256(
331
- ['string', 'address', 'string', 'bytes32', 'uint256'],
332
- [aitId, hitAddress, serviceId, metadataHash, timestamp]
333
- );
334
-
335
- const signature = await signer.signMessage(ethers.getBytes(messageHash));
336
-
337
- // Register AIT
338
- const response = await this.api.ait.createAIT({
339
- aitId,
340
- controller: hitAddress,
341
- serviceId,
342
- metadataHash,
343
- metadataCid,
344
- timestamp,
345
- signature
346
- }, token);
347
-
348
- if ('error' in response) {
349
- throw new Error(response.error);
350
- }
351
-
352
- return {
353
- aitId: response.aitId,
354
- controller: response.controller,
355
- metadata: response.metadata,
356
- metadataHash: response.metadataHash,
357
- metadataCid: response.metadataCid,
358
- signature: response.signature
359
- };
360
- }
361
-
362
- async getAITInfo(serviceId: string, controller: string, signer?: ethers.Signer): Promise<AIT | null> {
363
- const token = localStorage.getItem('nxtlinqAITServiceAccessToken');
364
- if (!token) {
365
- throw new Error('未找到访问令牌');
366
- }
367
-
368
- const response = await this.api.ait.getAITByServiceIdAndController({
369
- serviceId,
370
- controller
371
- }, token);
372
-
373
- if ('error' in response) {
374
- return null;
375
- }
376
-
377
- if (signer) {
378
- this.signer = signer;
379
- }
380
-
381
- return {
382
- aitId: response.aitId,
383
- controller: response.controller,
384
- metadata: response.metadata,
385
- metadataHash: response.metadataHash,
386
- metadataCid: response.metadataCid,
387
- signature: response.signature
388
- };
389
- }
390
-
391
- async sendMessage(message: string, toolName?: string): Promise<MessageResponse> {
392
- const permission = await this.checkAITPermission(toolName);
393
- if (!permission.hasPermission) {
394
- throw new Error(permission.reason || '没有权限使用该工具');
395
- }
396
-
397
- if (!this.ait || !this.signer) {
398
- throw new Error('请先连接钱包以访问权限');
399
- }
400
-
401
- const timestamp = Math.floor(Date.now() / 1000);
402
- const stringToSign = stringify({
403
- message,
404
- aitId: this.ait.aitId,
405
- controller: this.ait.controller,
406
- metadata: this.ait.metadata,
407
- metadataHash: this.ait.metadataHash,
408
- serviceId: this.projectId,
409
- timestamp
410
- }) || '';
411
-
412
- const signature = await this.signer.signMessage(stringToSign);
413
-
414
- const response = await this.api.agent.sendMessage({
415
- message,
416
- serviceId: this.projectId,
417
- });
418
-
419
- if ('error' in response) {
420
- throw new Error(response.error);
421
- }
422
-
423
- return {
424
- reply: response.reply,
425
- timestamp: new Date().toISOString()
426
- };
427
- }
428
- }
429
-
430
- export interface AITApi {
431
- ait: {
432
- getAITByServiceIdAndController: (params: { serviceId: string; controller: string }, token: string) => Promise<AITInfo | { error: string }>;
433
- createAIT: (params: CreateAITParams, token: string) => Promise<AITInfo | { error: string }>;
434
- };
435
- wallet: {
436
- verifyWallet: (params: VerifyWalletParams, token: string) => Promise<WalletInfo | { error: string }>;
437
- getWallet: (params: { address: string }, token: string) => Promise<WalletInfo | { error: string }>;
438
- };
439
- metadata: {
440
- createMetadata: (metadata: CreateMetadataParams, token: string) => Promise<{ metadataCid: string } | { error: string }>;
441
- };
442
- auth: {
443
- getNonce: (params: { address: string }) => Promise<{ code: string; timestamp: number } | { error: string }>;
444
- signIn: (params: SignInParams) => Promise<{ accessToken: string } | { error: string }>;
445
- };
446
- agent: {
447
- sendMessage: (params: { message: string; serviceId: string }) => Promise<{ reply: string } | { error: string }>;
448
- };
449
- }
@@ -1,103 +0,0 @@
1
- export interface AIT {
2
- aitId: string;
3
- controller: string;
4
- metadata: AITMetadata;
5
- metadataHash: string;
6
- metadataCid: string;
7
- signature: string;
8
- }
9
-
10
- export interface AITMetadata {
11
- model: string;
12
- permissions: string[];
13
- issuedBy: string;
14
- serviceId?: string;
15
- }
16
-
17
- export interface AITInfo {
18
- aitId: string;
19
- controller: string;
20
- metadata: AITMetadata;
21
- metadataHash: string;
22
- metadataCid: string;
23
- signature: string;
24
- }
25
-
26
- export interface WalletInfo {
27
- id: string;
28
- address: string;
29
- verified: boolean;
30
- method?: string;
31
- }
32
-
33
- export interface PermissionGroup {
34
- label: string;
35
- options: PermissionOption[];
36
- }
37
-
38
- export interface PermissionOption {
39
- label: string;
40
- value: string;
41
- isChecked: boolean;
42
- }
43
-
44
- export interface CreateAITParams {
45
- aitId: string;
46
- controller: string;
47
- serviceId: string;
48
- metadataHash: string;
49
- metadataCid: string;
50
- timestamp: number;
51
- signature: string;
52
- }
53
-
54
- export interface CreateMetadataParams extends AITMetadata {
55
- controller: string;
56
- }
57
-
58
- export interface VerifyWalletParams {
59
- address: string;
60
- token: string;
61
- method: string;
62
- timestamp: number;
63
- }
64
-
65
- export interface SignInParams {
66
- address: string;
67
- code: string;
68
- timestamp: number;
69
- signature: string;
70
- }
71
-
72
- export interface MessageContext {
73
- aitId?: string;
74
- walletAddress?: string | null;
75
- }
76
-
77
- export interface SendMessageParams {
78
- message: string;
79
- projectId?: string;
80
- serviceId: string;
81
- context: MessageContext;
82
- }
83
-
84
- export interface AITApi {
85
- ait: {
86
- getAITByServiceIdAndController: (params: { serviceId: string; controller: string }, token: string) => Promise<AITInfo | { error: string }>;
87
- createAIT: (params: CreateAITParams, token: string) => Promise<AITInfo | { error: string }>;
88
- };
89
- wallet: {
90
- verifyWallet: (params: VerifyWalletParams, token: string) => Promise<WalletInfo | { error: string }>;
91
- getWallet: (params: { address: string }, token: string) => Promise<WalletInfo | { error: string }>;
92
- };
93
- metadata: {
94
- createMetadata: (metadata: CreateMetadataParams, token: string) => Promise<{ metadataCid: string } | { error: string }>;
95
- };
96
- auth: {
97
- getNonce: (params: { address: string }) => Promise<{ code: string; timestamp: number } | { error: string }>;
98
- signIn: (params: SignInParams) => Promise<{ accessToken: string } | { error: string }>;
99
- };
100
- agent: {
101
- sendMessage: (params: { message: string; serviceId: string }) => Promise<{ reply: string } | { error: string }>;
102
- };
103
- }
@@ -1,9 +0,0 @@
1
- import { Eip1193Provider } from 'ethers';
2
-
3
- declare global {
4
- interface Window {
5
- ethereum?: Eip1193Provider;
6
- }
7
- }
8
-
9
- export {};
package/tsconfig.json DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "ESNext",
5
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
- "declaration": true,
7
- "outDir": "dist",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "moduleResolution": "node",
13
- "jsx": "react-jsx",
14
- "isolatedModules": true,
15
- "composite": false,
16
- "declarationMap": true,
17
- "rootDir": "src",
18
- "baseUrl": "src",
19
- "paths": {
20
- "*": ["*"]
21
- }
22
- },
23
- "include": ["src/**/*"],
24
- "exclude": ["node_modules", "dist"]
25
- }
package/tsup.config.ts DELETED
@@ -1,15 +0,0 @@
1
- import { defineConfig } from 'tsup';
2
-
3
- export default defineConfig({
4
- entry: ['src/index.ts', 'src/components/ChatBot.tsx'],
5
- format: ['cjs', 'esm'],
6
- dts: true,
7
- splitting: false,
8
- sourcemap: true,
9
- clean: true,
10
- treeshake: true,
11
- external: ['react', 'react-dom'],
12
- esbuildOptions(options) {
13
- options.jsx = 'automatic';
14
- },
15
- });