# @emblemvault/auth-sdk

Official TypeScript SDK for Emblem Vault authentication.

## Installation

```bash
npm install @emblemvault/auth-sdk
# or
yarn add @emblemvault/auth-sdk
```

## Quick Start

```typescript
import { EmblemAuthSDK } from '@emblemvault/auth-sdk';

// Minimal setup - only appId is required
const auth = new EmblemAuthSDK({
  appId: 'your-app-id',
  onSuccess: (session) => {
    console.log('Authenticated!', session);
  },
  onError: (error) => {
    console.error('Auth failed:', error);
  }
});

// Open authentication modal
auth.openAuthModal();

// Get current session
const session = auth.getSession();

// Use JWT for API calls
fetch('https://api.emblemvault.ai/protected-endpoint', {
  headers: {
    'Authorization': `Bearer ${session.authToken}`
  }
});
```

## Features

- 🔐 **Multiple Auth Methods** - Wallet (EVM, Solana, Hedera) and OAuth (Twitter, Google)
- 🔑 **JWT-based Sessions** - Secure token management with auto-refresh
- 💾 **Session Persistence** - Stay logged in across page reloads (enabled by default)
- 🎨 **Flexible UI** - Iframe or popup modal modes
- 📦 **TypeScript** - Full type definitions included
- 🌐 **Browser & Node** - Works in browsers and Node.js environments
- ⚡ **Lightweight** - < 15KB minified and gzipped

## API Reference

### Constructor

```typescript
new EmblemAuthSDK(config: EmblemAuthConfig)
```

#### Config Options

| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| `appId` | string | ✅ | - | Your application ID |
| `authUrl` | string | ❌ | `https://auth.emblemvault.ai` | Auth service URL for modal, init, bootstrap, refresh |
| `apiUrl` | string | ❌ | `https://api.emblemvault.ai` | Backend API for vault operations and signing only |
| `modalMode` | 'iframe' \| 'popup' \| 'auto' | ❌ | `'auto'` | Modal display mode |
| `persistSession` | boolean | ❌ | `true` | Persist session to localStorage (stay logged in) |
| `onSuccess` | (session) => void | ❌ | - | Success callback |
| `onError` | (error) => void | ❌ | - | Error callback |

**URL Configuration:**
- `authUrl` handles: auth modal (`/connect`), `/api/auth/init`, `/auth/bootstrap`, `/api/auth/refresh`
- `apiUrl` handles: vault info, signing, decryption, and other vault operations

### Methods

#### `openAuthModal(): Promise<void>`
Opens the authentication modal for users to sign in.

#### `getSession(): AuthSession | null`
Returns the current authentication session.

#### `refreshSession(): Promise<AuthSession | null>`
Manually refreshes the authentication token.

#### `authenticateWallet(params): Promise<AuthSession | null>`
Programmatically authenticate with wallet signature.

#### `getVaultInfo(): Promise<VaultInfo>`
Retrieves information about the user's vault. Caches the result for the session duration.

```typescript
const vaultInfo = await auth.getVaultInfo();
console.log(vaultInfo.vaultId);
console.log(vaultInfo.evmAddress);
```

#### `getVaultApiKey(): Promise<string>`
Retrieves or generates the vault API key.

#### `logout(): void`
Clears the current session.

#### `hydrateSession(session: AuthSession): void`
Restores a session from external storage. Useful for Node.js environments where `localStorage` is not available. This activates the auto-refresh timer.

```typescript
// Restore session from file/database
const saved = await loadSessionFromFile();
if (saved) {
  auth.hydrateSession(saved);
}
```

#### `on(event, handler): void`
Subscribe to authentication events.

#### `off(event, handler): void`
Unsubscribe from authentication events.

### Events

- `session` - Fired when session is established or updated
- `sessionExpired` - Session has expired
- `sessionRefreshed` - Session was refreshed
- `sessionWillRefresh` - Session will refresh soon
- `authError` - Authentication error occurred

### Session Persistence

By default, sessions are persisted to `localStorage`, allowing users to stay logged in across page reloads and browser sessions. This follows the industry-standard "stay logged in" behavior.

```typescript
// Default behavior - sessions are persisted
const auth = new EmblemAuthSDK({
  appId: 'your-app-id'
});

// Sessions will automatically restore on page load
const session = auth.getSession(); // Returns persisted session if valid

// To disable persistence (session only lasts until page closes)
const auth = new EmblemAuthSDK({
  appId: 'your-app-id',
  persistSession: false
});
```

**Notes:**
- Sessions are stored with the key `emblem_session_{appId}`
- Expired sessions are automatically cleared on load
- Calling `logout()` clears the persisted session
- Works gracefully in private browsing mode (falls back to memory-only)

### Node.js Usage

In Node.js environments, `localStorage` is not available, so you must implement your own session persistence. The SDK's auto-refresh timer still works—use `hydrateSession()` to restore sessions and subscribe to events to keep your storage in sync.

```typescript
import { EmblemAuthSDK } from '@emblemvault/auth-sdk';
import fs from 'fs/promises';

const SESSION_FILE = './session.json';

const auth = new EmblemAuthSDK({
  appId: 'your-app-id',
  persistSession: false // No effect in Node.js, but explicit
});

// Restore session from file on startup
async function restoreSession() {
  try {
    const data = await fs.readFile(SESSION_FILE, 'utf-8');
    const session = JSON.parse(data);
    auth.hydrateSession(session); // Activates auto-refresh timer
  } catch {
    // No saved session
  }
}

// Keep file in sync with SDK's auto-refresh
auth.on('sessionRefreshed', async (session) => {
  await fs.writeFile(SESSION_FILE, JSON.stringify(session));
});

auth.on('sessionExpired', async () => {
  await fs.unlink(SESSION_FILE).catch(() => {});
});

// Initialize
await restoreSession();
```

**Key points:**
- `hydrateSession()` restores the session and starts the auto-refresh timer
- The SDK will automatically refresh tokens ~60 seconds before expiry
- Subscribe to `sessionRefreshed` to persist the new session after refresh
- Subscribe to `sessionExpired` to clear your storage when refresh fails

### Types

#### `VaultInfo`
```typescript
interface VaultInfo {
  vaultId: string;
  evmAddress?: string;
  solanaAddress?: string;
  hederaAccountId?: string;
  createdAt?: string;
  metadata?: Record<string, any>;
}
```

## CDN Usage

```html
<script src="https://unpkg.com/@emblemvault/auth-sdk@latest/dist/emblem-auth.min.js"></script>
<script>
  // Only appId is required - authUrl and apiUrl have production defaults
  const auth = new EmblemAuth.EmblemAuthSDK({
    appId: 'your-app-id'
  });

  auth.openAuthModal();
</script>
```

Alternative CDNs:
- jsDelivr: `https://cdn.jsdelivr.net/npm/@emblemvault/auth-sdk@latest/dist/emblem-auth.min.js`
- unpkg (specific version): `https://unpkg.com/@emblemvault/auth-sdk@2.0.0/dist/emblem-auth.min.js`

## License

MIT