@nxcode/sdk 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +535 -0
- package/dist/nxcode.esm.js +323 -2
- package/dist/nxcode.esm.js.map +1 -1
- package/dist/nxcode.js +323 -2
- package/dist/nxcode.js.map +1 -1
- package/dist/nxcode.min.js +1 -1
- package/dist/types/ai.d.ts +124 -0
- package/dist/types/auth.test.d.ts +6 -0
- package/dist/types/index.d.ts +52 -3
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
# Nxcode SDK
|
|
2
|
+
|
|
3
|
+
A lightweight JavaScript SDK for integrating Nxcode authentication, billing, payments, and AI capabilities into web applications.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- CDN -->
|
|
9
|
+
<script src="https://sdk.nxcode.io/v1/nxcode.min.js"></script>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# npm
|
|
14
|
+
npm install @nxcode/sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
// SDK auto-initializes based on your domain
|
|
21
|
+
// For manual configuration:
|
|
22
|
+
Nxcode.configure('your-app-id');
|
|
23
|
+
|
|
24
|
+
// Login
|
|
25
|
+
const user = await Nxcode.auth.login('google');
|
|
26
|
+
console.log(user.email, user.balance);
|
|
27
|
+
|
|
28
|
+
// AI chat
|
|
29
|
+
const response = await Nxcode.ai.chat({
|
|
30
|
+
messages: [{ role: 'user', content: 'Hello!' }]
|
|
31
|
+
});
|
|
32
|
+
console.log(response.content);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Authentication
|
|
38
|
+
|
|
39
|
+
### Login
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// OAuth login (opens popup)
|
|
43
|
+
const user = await Nxcode.auth.login('google'); // or 'github'
|
|
44
|
+
|
|
45
|
+
// Returns:
|
|
46
|
+
// {
|
|
47
|
+
// id: string,
|
|
48
|
+
// email: string,
|
|
49
|
+
// name: string,
|
|
50
|
+
// image: string,
|
|
51
|
+
// balance: number
|
|
52
|
+
// }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Logout
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
await Nxcode.auth.logout();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Get Current User
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
const user = Nxcode.auth.getUser(); // null if not logged in
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Check Login Status
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
if (Nxcode.auth.isLoggedIn()) {
|
|
71
|
+
// user is authenticated
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Auth State Change Listener
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const unsubscribe = Nxcode.auth.onAuthStateChange((user) => {
|
|
79
|
+
if (user) {
|
|
80
|
+
console.log('Logged in:', user.email);
|
|
81
|
+
} else {
|
|
82
|
+
console.log('Logged out');
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Later: unsubscribe();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Get Auth Token
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
const token = Nxcode.auth.getToken(); // For custom API calls
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## AI
|
|
98
|
+
|
|
99
|
+
All AI methods support both authenticated users and anonymous users (if app allows).
|
|
100
|
+
|
|
101
|
+
### Chat (Non-streaming)
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
const response = await Nxcode.ai.chat({
|
|
105
|
+
messages: [
|
|
106
|
+
{ role: 'system', content: 'You are a helpful assistant.' },
|
|
107
|
+
{ role: 'user', content: 'What is 2+2?' }
|
|
108
|
+
],
|
|
109
|
+
model: 'fast' // optional, default: 'fast'. Options: 'fast', 'pro'
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Returns:
|
|
113
|
+
// {
|
|
114
|
+
// content: string,
|
|
115
|
+
// usage: { inputTokens: number, outputTokens: number }
|
|
116
|
+
// }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Chat (Streaming)
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
await Nxcode.ai.chatStream({
|
|
123
|
+
messages: [{ role: 'user', content: 'Tell me a story' }],
|
|
124
|
+
onChunk: (chunk) => {
|
|
125
|
+
process.stdout.write(chunk.content); // or append to DOM
|
|
126
|
+
if (chunk.done) {
|
|
127
|
+
console.log('Completed!');
|
|
128
|
+
console.log('Tokens:', chunk.usage);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// chunk: { content: string, done: boolean, usage?: { inputTokens, outputTokens } }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Generate (Simple prompt)
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// Non-streaming
|
|
140
|
+
const response = await Nxcode.ai.generate({
|
|
141
|
+
prompt: 'Write a haiku about coding'
|
|
142
|
+
});
|
|
143
|
+
console.log(response.text);
|
|
144
|
+
|
|
145
|
+
// Streaming
|
|
146
|
+
await Nxcode.ai.generateStream({
|
|
147
|
+
prompt: 'Write a poem',
|
|
148
|
+
onChunk: (chunk) => console.log(chunk.content)
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Multimodal (Images)
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
// Image from base64
|
|
156
|
+
const response = await Nxcode.ai.chat({
|
|
157
|
+
messages: [{
|
|
158
|
+
role: 'user',
|
|
159
|
+
content: [
|
|
160
|
+
{ type: 'text', text: 'What is in this image?' },
|
|
161
|
+
{ type: 'image', data: 'base64-encoded-image...', mimeType: 'image/jpeg' }
|
|
162
|
+
]
|
|
163
|
+
}]
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Image from URL
|
|
167
|
+
const response = await Nxcode.ai.chat({
|
|
168
|
+
messages: [{
|
|
169
|
+
role: 'user',
|
|
170
|
+
content: [
|
|
171
|
+
{ type: 'text', text: 'Describe this image' },
|
|
172
|
+
{ type: 'image_url', url: 'https://example.com/image.jpg' }
|
|
173
|
+
]
|
|
174
|
+
}]
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Multiple images
|
|
178
|
+
const response = await Nxcode.ai.chat({
|
|
179
|
+
messages: [{
|
|
180
|
+
role: 'user',
|
|
181
|
+
content: [
|
|
182
|
+
{ type: 'text', text: 'Compare these two images' },
|
|
183
|
+
{ type: 'image', data: image1Base64, mimeType: 'image/png' },
|
|
184
|
+
{ type: 'image', data: image2Base64, mimeType: 'image/png' }
|
|
185
|
+
]
|
|
186
|
+
}]
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Multi-turn Conversation
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const messages = [];
|
|
194
|
+
|
|
195
|
+
// First turn
|
|
196
|
+
messages.push({ role: 'user', content: 'My name is Alice' });
|
|
197
|
+
const r1 = await Nxcode.ai.chat({ messages });
|
|
198
|
+
messages.push({ role: 'assistant', content: r1.content });
|
|
199
|
+
|
|
200
|
+
// Second turn
|
|
201
|
+
messages.push({ role: 'user', content: 'What is my name?' });
|
|
202
|
+
const r2 = await Nxcode.ai.chat({ messages });
|
|
203
|
+
console.log(r2.content); // "Your name is Alice"
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Billing
|
|
209
|
+
|
|
210
|
+
### Get Balance
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
const balance = await Nxcode.billing.getBalance();
|
|
214
|
+
console.log(`Balance: ${balance} C$`);
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Top Up
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
Nxcode.billing.topUp(); // Opens top-up page in new tab
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Payments (In-App Purchases)
|
|
226
|
+
|
|
227
|
+
### Charge User
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
const result = await Nxcode.payment.charge({
|
|
231
|
+
amount: 1.99,
|
|
232
|
+
description: 'Premium feature unlock',
|
|
233
|
+
metadata: { featureId: 'premium-v2' } // optional
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Returns:
|
|
237
|
+
// {
|
|
238
|
+
// success: boolean,
|
|
239
|
+
// transactionId?: string,
|
|
240
|
+
// newBalance?: number,
|
|
241
|
+
// error?: string
|
|
242
|
+
// }
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Get Transactions
|
|
246
|
+
|
|
247
|
+
```javascript
|
|
248
|
+
const transactions = await Nxcode.payment.getTransactions(50, 0);
|
|
249
|
+
|
|
250
|
+
// Returns:
|
|
251
|
+
// [{
|
|
252
|
+
// id: string,
|
|
253
|
+
// amount: number,
|
|
254
|
+
// description: string,
|
|
255
|
+
// createdAt: string,
|
|
256
|
+
// metadata?: object
|
|
257
|
+
// }]
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Configuration
|
|
263
|
+
|
|
264
|
+
### Manual Configuration
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Configure with app ID
|
|
268
|
+
Nxcode.configure('your-app-id');
|
|
269
|
+
|
|
270
|
+
// With custom endpoint (for development)
|
|
271
|
+
Nxcode.configure('your-app-id', {
|
|
272
|
+
apiEndpoint: 'http://localhost:8001'
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Wait for SDK Ready
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
await Nxcode.ready();
|
|
280
|
+
// SDK is now initialized
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Check SDK Status
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
if (Nxcode.isReady()) {
|
|
287
|
+
// SDK is configured and ready
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const config = Nxcode.getConfig();
|
|
291
|
+
// { appId, name, billingMode, apiEndpoint }
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## TypeScript Types
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
import type {
|
|
300
|
+
NxcodeUser,
|
|
301
|
+
NxcodeConfig,
|
|
302
|
+
ChatOptions,
|
|
303
|
+
ChatResponse,
|
|
304
|
+
ChatMessage,
|
|
305
|
+
ContentPart,
|
|
306
|
+
TextPart,
|
|
307
|
+
ImagePart,
|
|
308
|
+
ImageUrlPart,
|
|
309
|
+
GenerateOptions,
|
|
310
|
+
GenerateResponse,
|
|
311
|
+
StreamChunk,
|
|
312
|
+
StreamCallback,
|
|
313
|
+
ChargeOptions,
|
|
314
|
+
ChargeResult,
|
|
315
|
+
Transaction,
|
|
316
|
+
AuthStateCallback,
|
|
317
|
+
} from '@nxcode/sdk';
|
|
318
|
+
|
|
319
|
+
// ChatMessage
|
|
320
|
+
interface ChatMessage {
|
|
321
|
+
role: 'user' | 'assistant' | 'system';
|
|
322
|
+
content: string | ContentPart[];
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// ContentPart (for multimodal)
|
|
326
|
+
type ContentPart = TextPart | ImagePart | ImageUrlPart;
|
|
327
|
+
|
|
328
|
+
interface TextPart {
|
|
329
|
+
type: 'text';
|
|
330
|
+
text: string;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
interface ImagePart {
|
|
334
|
+
type: 'image';
|
|
335
|
+
data: string; // base64
|
|
336
|
+
mimeType: string; // 'image/jpeg', 'image/png', etc.
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
interface ImageUrlPart {
|
|
340
|
+
type: 'image_url';
|
|
341
|
+
url: string;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ChatOptions
|
|
345
|
+
interface ChatOptions {
|
|
346
|
+
messages: ChatMessage[];
|
|
347
|
+
model?: string; // default: 'fast'. Options: 'fast', 'pro'
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ChatResponse
|
|
351
|
+
interface ChatResponse {
|
|
352
|
+
content: string;
|
|
353
|
+
usage?: {
|
|
354
|
+
inputTokens: number;
|
|
355
|
+
outputTokens: number;
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// StreamChunk
|
|
360
|
+
interface StreamChunk {
|
|
361
|
+
content: string;
|
|
362
|
+
done: boolean;
|
|
363
|
+
usage?: {
|
|
364
|
+
inputTokens: number;
|
|
365
|
+
outputTokens: number;
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// NxcodeUser
|
|
370
|
+
interface NxcodeUser {
|
|
371
|
+
id: string;
|
|
372
|
+
email: string;
|
|
373
|
+
name: string;
|
|
374
|
+
image: string;
|
|
375
|
+
balance: number;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// ChargeOptions
|
|
379
|
+
interface ChargeOptions {
|
|
380
|
+
amount: number;
|
|
381
|
+
description: string;
|
|
382
|
+
metadata?: Record<string, unknown>;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// ChargeResult
|
|
386
|
+
interface ChargeResult {
|
|
387
|
+
success: boolean;
|
|
388
|
+
transactionId?: string;
|
|
389
|
+
newBalance?: number;
|
|
390
|
+
error?: string;
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Error Handling
|
|
397
|
+
|
|
398
|
+
```javascript
|
|
399
|
+
try {
|
|
400
|
+
const response = await Nxcode.ai.chat({
|
|
401
|
+
messages: [{ role: 'user', content: 'Hello' }]
|
|
402
|
+
});
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (error.message.includes('401') || error.message.includes('Session expired')) {
|
|
405
|
+
// Re-authenticate
|
|
406
|
+
await Nxcode.auth.login('google');
|
|
407
|
+
} else if (error.message.includes('402') || error.message.includes('Insufficient balance')) {
|
|
408
|
+
// Prompt user to top up
|
|
409
|
+
Nxcode.billing.topUp();
|
|
410
|
+
} else if (error.message.includes('429')) {
|
|
411
|
+
// Rate limited (anonymous users)
|
|
412
|
+
console.log('Please sign in for unlimited access');
|
|
413
|
+
} else {
|
|
414
|
+
console.error('AI error:', error.message);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Complete Example
|
|
422
|
+
|
|
423
|
+
```html
|
|
424
|
+
<!DOCTYPE html>
|
|
425
|
+
<html>
|
|
426
|
+
<head>
|
|
427
|
+
<title>AI Chat App</title>
|
|
428
|
+
<script src="https://sdk.nxcode.io/v1/nxcode.min.js"></script>
|
|
429
|
+
</head>
|
|
430
|
+
<body>
|
|
431
|
+
<div id="chat"></div>
|
|
432
|
+
<input id="input" type="text" placeholder="Type a message...">
|
|
433
|
+
<button id="send">Send</button>
|
|
434
|
+
<button id="login">Login</button>
|
|
435
|
+
|
|
436
|
+
<script>
|
|
437
|
+
const chat = document.getElementById('chat');
|
|
438
|
+
const input = document.getElementById('input');
|
|
439
|
+
const messages = [];
|
|
440
|
+
|
|
441
|
+
// Auth state listener
|
|
442
|
+
Nxcode.auth.onAuthStateChange((user) => {
|
|
443
|
+
document.getElementById('login').textContent = user ? 'Logout' : 'Login';
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
// Login/Logout
|
|
447
|
+
document.getElementById('login').onclick = async () => {
|
|
448
|
+
if (Nxcode.auth.isLoggedIn()) {
|
|
449
|
+
await Nxcode.auth.logout();
|
|
450
|
+
} else {
|
|
451
|
+
await Nxcode.auth.login('google');
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
// Send message
|
|
456
|
+
document.getElementById('send').onclick = async () => {
|
|
457
|
+
const text = input.value.trim();
|
|
458
|
+
if (!text) return;
|
|
459
|
+
|
|
460
|
+
// Add user message
|
|
461
|
+
messages.push({ role: 'user', content: text });
|
|
462
|
+
chat.innerHTML += `<p><b>You:</b> ${text}</p>`;
|
|
463
|
+
input.value = '';
|
|
464
|
+
|
|
465
|
+
// Stream response
|
|
466
|
+
const responseEl = document.createElement('p');
|
|
467
|
+
responseEl.innerHTML = '<b>AI:</b> ';
|
|
468
|
+
chat.appendChild(responseEl);
|
|
469
|
+
|
|
470
|
+
let fullResponse = '';
|
|
471
|
+
await Nxcode.ai.chatStream({
|
|
472
|
+
messages,
|
|
473
|
+
onChunk: (chunk) => {
|
|
474
|
+
fullResponse += chunk.content;
|
|
475
|
+
responseEl.innerHTML = `<b>AI:</b> ${fullResponse}`;
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
messages.push({ role: 'assistant', content: fullResponse });
|
|
480
|
+
};
|
|
481
|
+
</script>
|
|
482
|
+
</body>
|
|
483
|
+
</html>
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## Available Models
|
|
489
|
+
|
|
490
|
+
| Model | Description |
|
|
491
|
+
|-------|-------------|
|
|
492
|
+
| `fast` | Fast, balanced (default) |
|
|
493
|
+
| `pro` | Most capable |
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## Billing Modes
|
|
498
|
+
|
|
499
|
+
Apps can be configured with different billing modes:
|
|
500
|
+
|
|
501
|
+
- **user_pays**: Users pay from their own balance (requires login)
|
|
502
|
+
- **anonymous_allowed**: Anonymous users can use AI with rate limits (creator pays)
|
|
503
|
+
|
|
504
|
+
Anonymous limits (configurable by app creator):
|
|
505
|
+
- Rate limit: X requests per hour per IP
|
|
506
|
+
- Daily budget: Max C$ per day for all anonymous users
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## API Reference Summary
|
|
511
|
+
|
|
512
|
+
| Method | Description |
|
|
513
|
+
|--------|-------------|
|
|
514
|
+
| `Nxcode.configure(appId, options?)` | Configure SDK |
|
|
515
|
+
| `Nxcode.ready()` | Wait for SDK initialization |
|
|
516
|
+
| `Nxcode.isReady()` | Check if SDK is ready |
|
|
517
|
+
| `Nxcode.getConfig()` | Get current config |
|
|
518
|
+
| **Auth** | |
|
|
519
|
+
| `Nxcode.auth.login(provider)` | OAuth login |
|
|
520
|
+
| `Nxcode.auth.logout()` | Logout |
|
|
521
|
+
| `Nxcode.auth.getUser()` | Get current user |
|
|
522
|
+
| `Nxcode.auth.getToken()` | Get auth token |
|
|
523
|
+
| `Nxcode.auth.isLoggedIn()` | Check login status |
|
|
524
|
+
| `Nxcode.auth.onAuthStateChange(cb)` | Auth state listener |
|
|
525
|
+
| **AI** | |
|
|
526
|
+
| `Nxcode.ai.chat(options)` | Chat (non-streaming) |
|
|
527
|
+
| `Nxcode.ai.chatStream(options)` | Chat (streaming) |
|
|
528
|
+
| `Nxcode.ai.generate(options)` | Generate from prompt |
|
|
529
|
+
| `Nxcode.ai.generateStream(options)` | Generate (streaming) |
|
|
530
|
+
| **Billing** | |
|
|
531
|
+
| `Nxcode.billing.getBalance()` | Get user balance |
|
|
532
|
+
| `Nxcode.billing.topUp()` | Open top-up page |
|
|
533
|
+
| **Payment** | |
|
|
534
|
+
| `Nxcode.payment.charge(options)` | Process payment |
|
|
535
|
+
| `Nxcode.payment.getTransactions()` | Get transaction history |
|