@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 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 |