npm package: @nxcode/sdk
Description: Nxcode SDK for web applications
Author: Nxcode
Latest version: 1.0.14

# Nxcode SDK

A lightweight JavaScript SDK for integrating Nxcode authentication, billing, payments, and AI capabilities into web applications.

## Installation

```html
<!-- CDN -->
<script src="https://sdk.nxcode.io/v1/nxcode.min.js"></script>
```

```bash
# npm
npm install @nxcode/sdk
```

## Quick Start

```javascript
// SDK auto-initializes based on your domain
// For manual configuration:
Nxcode.configure('your-app-id');

// Login
const user = await Nxcode.auth.login('google');
console.log(user.email, user.balance);

// AI chat
const response = await Nxcode.ai.chat({
  messages: [{ role: 'user', content: 'Hello!' }]
});
console.log(response.content);
```

---

## Authentication

### Login

```javascript
// OAuth login (opens popup)
const user = await Nxcode.auth.login('google');  // or 'github'

// Returns:
// {
//   id: string,
//   email: string,
//   name: string,
//   image: string,
//   balance: number
// }
```

### Logout

```javascript
await Nxcode.auth.logout();
```

### Get Current User

```javascript
const user = Nxcode.auth.getUser();  // null if not logged in
```

### Check Login Status

```javascript
if (Nxcode.auth.isLoggedIn()) {
  // user is authenticated
}
```

### Auth State Change Listener

```javascript
const unsubscribe = Nxcode.auth.onAuthStateChange((user) => {
  if (user) {
    console.log('Logged in:', user.email);
  } else {
    console.log('Logged out');
  }
});

// Later: unsubscribe();
```

### Get Auth Token

```javascript
const token = Nxcode.auth.getToken();  // For custom API calls
```

---

## AI

All AI methods support both authenticated users and anonymous users (if app allows).

### Chat (Non-streaming)

```javascript
const response = await Nxcode.ai.chat({
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'What is 2+2?' }
  ],
  model: 'fast'  // optional, default: 'fast'. Options: 'fast', 'pro'
});

// Returns:
// {
//   content: string,
//   usage: { inputTokens: number, outputTokens: number }
// }
```

### Chat (Streaming)

```javascript
await Nxcode.ai.chatStream({
  messages: [{ role: 'user', content: 'Tell me a story' }],
  onChunk: (chunk) => {
    process.stdout.write(chunk.content);  // or append to DOM
    if (chunk.done) {
      console.log('Completed!');
      console.log('Tokens:', chunk.usage);
    }
  }
});

// chunk: { content: string, done: boolean, usage?: { inputTokens, outputTokens } }
```

### Generate (Simple prompt)

```javascript
// Non-streaming
const response = await Nxcode.ai.generate({
  prompt: 'Write a haiku about coding'
});
console.log(response.text);

// Streaming
await Nxcode.ai.generateStream({
  prompt: 'Write a poem',
  onChunk: (chunk) => console.log(chunk.content)
});
```

### Multimodal (Images)

```javascript
// Image from base64
const response = await Nxcode.ai.chat({
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'What is in this image?' },
      { type: 'image', data: 'base64-encoded-image...', mimeType: 'image/jpeg' }
    ]
  }]
});

// Image from URL
const response = await Nxcode.ai.chat({
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'Describe this image' },
      { type: 'image_url', url: 'https://example.com/image.jpg' }
    ]
  }]
});

// Multiple images
const response = await Nxcode.ai.chat({
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'Compare these two images' },
      { type: 'image', data: image1Base64, mimeType: 'image/png' },
      { type: 'image', data: image2Base64, mimeType: 'image/png' }
    ]
  }]
});
```

### Multi-turn Conversation

```javascript
const messages = [];

// First turn
messages.push({ role: 'user', content: 'My name is Alice' });
const r1 = await Nxcode.ai.chat({ messages });
messages.push({ role: 'assistant', content: r1.content });

// Second turn
messages.push({ role: 'user', content: 'What is my name?' });
const r2 = await Nxcode.ai.chat({ messages });
console.log(r2.content);  // "Your name is Alice"
```

---

## Billing

### Get Balance

```javascript
const balance = await Nxcode.billing.getBalance();
console.log(`Balance: ${balance} C$`);
```

### Top Up

```javascript
Nxcode.billing.topUp();  // Opens top-up page in new tab
```

---

## Payments (In-App Purchases)

### Charge User

```javascript
const result = await Nxcode.payment.charge({
  amount: 1.99,
  description: 'Premium feature unlock',
  metadata: { featureId: 'premium-v2' }  // optional
});

// Returns:
// {
//   success: boolean,
//   transactionId?: string,
//   newBalance?: number,
//   error?: string
// }
```

### Get Transactions

```javascript
const transactions = await Nxcode.payment.getTransactions(50, 0);

// Returns:
// [{
//   id: string,
//   amount: number,
//   description: string,
//   createdAt: string,
//   metadata?: object
// }]
```

---

## Configuration

### Manual Configuration

```javascript
// Configure with app ID
Nxcode.configure('your-app-id');

// With custom endpoint (for development)
Nxcode.configure('your-app-id', {
  apiEndpoint: 'http://localhost:8001'
});
```

### Wait for SDK Ready

```javascript
await Nxcode.ready();
// SDK is now initialized
```

### Check SDK Status

```javascript
if (Nxcode.isReady()) {
  // SDK is configured and ready
}

const config = Nxcode.getConfig();
// { appId, name, billingMode, apiEndpoint }
```

---

## TypeScript Types

```typescript
import type {
  NxcodeUser,
  NxcodeConfig,
  ChatOptions,
  ChatResponse,
  ChatMessage,
  ContentPart,
  TextPart,
  ImagePart,
  ImageUrlPart,
  GenerateOptions,
  GenerateResponse,
  StreamChunk,
  StreamCallback,
  ChargeOptions,
  ChargeResult,
  Transaction,
  AuthStateCallback,
} from '@nxcode/sdk';

// ChatMessage
interface ChatMessage {
  role: 'user' | 'assistant' | 'system';
  content: string | ContentPart[];
}

// ContentPart (for multimodal)
type ContentPart = TextPart | ImagePart | ImageUrlPart;

interface TextPart {
  type: 'text';
  text: string;
}

interface ImagePart {
  type: 'image';
  data: string;      // base64
  mimeType: string;  // 'image/jpeg', 'image/png', etc.
}

interface ImageUrlPart {
  type: 'image_url';
  url: string;
}

// ChatOptions
interface ChatOptions {
  messages: ChatMessage[];
  model?: string;  // default: 'fast'. Options: 'fast', 'pro'
}

// ChatResponse
interface ChatResponse {
  content: string;
  usage?: {
    inputTokens: number;
    outputTokens: number;
  };
}

// StreamChunk
interface StreamChunk {
  content: string;
  done: boolean;
  usage?: {
    inputTokens: number;
    outputTokens: number;
  };
}

// NxcodeUser
interface NxcodeUser {
  id: string;
  email: string;
  name: string;
  image: string;
  balance: number;
}

// ChargeOptions
interface ChargeOptions {
  amount: number;
  description: string;
  metadata?: Record<string, unknown>;
}

// ChargeResult
interface ChargeResult {
  success: boolean;
  transactionId?: string;
  newBalance?: number;
  error?: string;
}
```

---

## Error Handling

```javascript
try {
  const response = await Nxcode.ai.chat({
    messages: [{ role: 'user', content: 'Hello' }]
  });
} catch (error) {
  if (error.message.includes('401') || error.message.includes('Session expired')) {
    // Re-authenticate
    await Nxcode.auth.login('google');
  } else if (error.message.includes('402') || error.message.includes('Insufficient balance')) {
    // Prompt user to top up
    Nxcode.billing.topUp();
  } else if (error.message.includes('429')) {
    // Rate limited (anonymous users)
    console.log('Please sign in for unlimited access');
  } else {
    console.error('AI error:', error.message);
  }
}
```

---

## Complete Example

```html
<!DOCTYPE html>
<html>
<head>
  <title>AI Chat App</title>
  <script src="https://sdk.nxcode.io/v1/nxcode.min.js"></script>
</head>
<body>
  <div id="chat"></div>
  <input id="input" type="text" placeholder="Type a message...">
  <button id="send">Send</button>
  <button id="login">Login</button>

  <script>
    const chat = document.getElementById('chat');
    const input = document.getElementById('input');
    const messages = [];

    // Auth state listener
    Nxcode.auth.onAuthStateChange((user) => {
      document.getElementById('login').textContent = user ? 'Logout' : 'Login';
    });

    // Login/Logout
    document.getElementById('login').onclick = async () => {
      if (Nxcode.auth.isLoggedIn()) {
        await Nxcode.auth.logout();
      } else {
        await Nxcode.auth.login('google');
      }
    };

    // Send message
    document.getElementById('send').onclick = async () => {
      const text = input.value.trim();
      if (!text) return;

      // Add user message
      messages.push({ role: 'user', content: text });
      chat.innerHTML += `<p><b>You:</b> ${text}</p>`;
      input.value = '';

      // Stream response
      const responseEl = document.createElement('p');
      responseEl.innerHTML = '<b>AI:</b> ';
      chat.appendChild(responseEl);

      let fullResponse = '';
      await Nxcode.ai.chatStream({
        messages,
        onChunk: (chunk) => {
          fullResponse += chunk.content;
          responseEl.innerHTML = `<b>AI:</b> ${fullResponse}`;
        }
      });

      messages.push({ role: 'assistant', content: fullResponse });
    };
  </script>
</body>
</html>
```

---

## Available Models

| Model | Description |
|-------|-------------|
| `fast` | Fast, balanced (default) |
| `pro` | Most capable |

---

## Billing Modes

Apps can be configured with different billing modes:

- **user_pays**: Users pay from their own balance (requires login)
- **anonymous_allowed**: Anonymous users can use AI with rate limits (creator pays)

Anonymous limits (configurable by app creator):
- Rate limit: X requests per hour per IP
- Daily budget: Max C$ per day for all anonymous users

---

## API Reference Summary

| Method | Description |
|--------|-------------|
| `Nxcode.configure(appId, options?)` | Configure SDK |
| `Nxcode.ready()` | Wait for SDK initialization |
| `Nxcode.isReady()` | Check if SDK is ready |
| `Nxcode.getConfig()` | Get current config |
| **Auth** | |
| `Nxcode.auth.login(provider)` | OAuth login |
| `Nxcode.auth.logout()` | Logout |
| `Nxcode.auth.getUser()` | Get current user |
| `Nxcode.auth.getToken()` | Get auth token |
| `Nxcode.auth.isLoggedIn()` | Check login status |
| `Nxcode.auth.onAuthStateChange(cb)` | Auth state listener |
| **AI** | |
| `Nxcode.ai.chat(options)` | Chat (non-streaming) |
| `Nxcode.ai.chatStream(options)` | Chat (streaming) |
| `Nxcode.ai.generate(options)` | Generate from prompt |
| `Nxcode.ai.generateStream(options)` | Generate (streaming) |
| **Billing** | |
| `Nxcode.billing.getBalance()` | Get user balance |
| `Nxcode.billing.topUp()` | Open top-up page |
| **Payment** | |
| `Nxcode.payment.charge(options)` | Process payment |
| `Nxcode.payment.getTransactions()` | Get transaction history |