npm package: @producthacker/sdk
Description: HiveForge SDK for hosted deployments - AI proxy, billing proxy, and entitlement management
Author: HiveForge
Latest version: 0.1.0

# @producthacker/sdk

Official SDK for HiveForge hosted deployments. Provides:

- **Entitlement Management** - Feature gating and subscription status
- **AI Proxy** - Proxied OpenAI requests with quota management
- **Billing Proxy** - Proxied Stripe operations
- **React Integration** - Hooks and components for React apps

## Installation

```bash
npm install @producthacker/sdk
# or
yarn add @producthacker/sdk
# or
pnpm add @producthacker/sdk
```

## Quick Start

```typescript
import { HiveForgeClient } from '@producthacker/sdk';

// Create client with environment variables
const hiveforge = new HiveForgeClient({
  deploymentId: process.env.HIVEFORGE_DEPLOYMENT_ID!,
  deploymentSecret: process.env.HIVEFORGE_DEPLOYMENT_SECRET!,
});

// Initialize (fetches entitlements)
await hiveforge.initialize();

// Check subscription status
console.log(hiveforge.getStatus()); // 'active', 'trialing', etc.
console.log(hiveforge.getTier()); // 'sandbox', 'launch', 'growth', etc.

// Check if features are enabled
if (hiveforge.isEnabled('ai_enabled')) {
  // Use AI features
}
```

## Environment Variables

```env
HIVEFORGE_DEPLOYMENT_ID=your_deployment_id
HIVEFORGE_DEPLOYMENT_SECRET=your_deployment_secret
HIVEFORGE_API_URL=https://api.hiveforge.dev/api/v1  # Optional
```

## AI Proxy

Make OpenAI requests through HiveForge (no API keys in your app):

```typescript
// Chat completion
const response = await hiveforge.ai.complete({
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Hello!' },
  ],
  model: 'gpt-4o-mini', // Optional, defaults to gpt-4o-mini
  temperature: 0.7,
});

console.log(response.content);
console.log(response.tokens_used);

// Embeddings
const embeddings = await hiveforge.ai.embed({
  text: 'Hello world',
  model: 'text-embedding-3-small',
});

console.log(embeddings.embeddings[0].length); // dimensions

// Check quota
const quota = await hiveforge.ai.getQuota();
console.log(quota.remaining); // tokens remaining

// Streaming completion (async generator)
for await (const chunk of hiveforge.ai.stream({
  messages: [{ role: 'user', content: 'Tell me a story' }],
})) {
  process.stdout.write(chunk.content);
  if (chunk.done) break;
}

// Streaming with callbacks
await hiveforge.ai.streamToString({
  messages: [{ role: 'user', content: 'Hello!' }],
  onChunk: (chunk) => process.stdout.write(chunk.content),
  onComplete: (full) => console.log('\nDone:', full.length, 'chars'),
});
```

## Billing Proxy

Handle Stripe operations without exposing API keys:

```typescript
// Create checkout session
const checkout = await hiveforge.billing.createCheckout({
  priceId: 'price_xxx',
  customerEmail: 'customer@example.com',
  successUrl: 'https://yourapp.com/success',
  cancelUrl: 'https://yourapp.com/cancel',
});

// Redirect to checkout
window.location.href = checkout.url;

// Or use the helper
await hiveforge.billing.redirectToCheckout({
  priceId: 'price_xxx',
  customerEmail: 'customer@example.com',
  successUrl: '/success',
  cancelUrl: '/cancel',
});

// Customer portal
const portal = await hiveforge.billing.createPortal({
  customerId: 'cus_xxx',
  returnUrl: 'https://yourapp.com/account',
});

window.location.href = portal.url;
```

## React Integration

### Provider Setup

```tsx
import { HiveForgeClient, EntitlementWrapper } from '@producthacker/sdk';

const hiveforge = new HiveForgeClient({
  deploymentId: process.env.NEXT_PUBLIC_HIVEFORGE_DEPLOYMENT_ID!,
  deploymentSecret: process.env.HIVEFORGE_DEPLOYMENT_SECRET!,
});

function App() {
  return (
    <EntitlementWrapper client={hiveforge} upgradeUrl="/pricing">
      <YourApp />
    </EntitlementWrapper>
  );
}
```

### Hooks

```tsx
import {
  useHiveForge,
  useFeature,
  useSubscriptionStatus,
  useTier,
  useMessage,
} from '@producthacker/sdk';

function MyComponent() {
  // Full access to client and state
  const { client, entitlements, isLoading, error, refresh } = useHiveForge();

  // Check feature flags
  const aiEnabled = useFeature('ai_enabled');
  const billingEnabled = useFeature('billing_enabled');

  // Get status
  const status = useSubscriptionStatus(); // 'active', 'trialing', etc.
  const tier = useTier(); // 'sandbox', 'launch', etc.
  const message = useMessage(); // "Trial expires in 3 days"

  if (isLoading) return <div>Loading...</div>;

  return (
    <div>
      <p>Status: {status}</p>
      <p>Tier: {tier}</p>
      {message && <p>{message}</p>}
      {aiEnabled && <AIFeatures />}
    </div>
  );
}
```

### Feature Gating

```tsx
import { EntitlementGate } from '@producthacker/sdk';

function MyComponent() {
  return (
    <div>
      <EntitlementGate feature="ai_enabled" fallback={<UpgradePrompt />}>
        <AIAssistant />
      </EntitlementGate>
    </div>
  );
}
```

## Event Handling

```typescript
// Subscribe to events
const unsubscribe = hiveforge.on('entitlements:updated', (entitlements) => {
  console.log('Entitlements updated:', entitlements.tier);
});

hiveforge.on('quota:warning', ({ resource, used, limit }) => {
  console.warn(`${resource} quota at ${Math.round((used / limit) * 100)}%`);
});

hiveforge.on('quota:exceeded', ({ resource }) => {
  alert(`${resource} quota exceeded. Please upgrade.`);
});

hiveforge.on('status:changed', ({ previous, current }) => {
  console.log(`Status changed from ${previous} to ${current}`);
});

// Unsubscribe
unsubscribe();
```

## Error Handling

```typescript
import { AIProxyException, BillingProxyException, HiveForgeError } from '@producthacker/sdk';

try {
  const response = await hiveforge.ai.complete({
    messages: [{ role: 'user', content: 'Hello!' }],
  });
} catch (error) {
  if (error instanceof AIProxyException) {
    if (error.isQuotaExceeded) {
      // Show upgrade prompt
      window.location.href = error.upgradeUrl!;
    } else {
      console.error('AI error:', error.code, error.message);
    }
  } else if (error instanceof BillingProxyException) {
    console.error('Billing error:', error.code, error.message);
  } else if (error instanceof HiveForgeError) {
    console.error('HiveForge error:', error.message);
  }
}
```

## Feature Flags Reference

| Feature            | Type           | Description                       |
| ------------------ | -------------- | --------------------------------- |
| `ai_enabled`       | boolean        | AI proxy available                |
| `ai_monthly_limit` | number \| null | Token limit (null = unlimited)    |
| `billing_enabled`  | boolean        | Billing proxy available           |
| `custom_domain`    | boolean        | Custom domain support             |
| `white_label`      | boolean        | White labeling enabled            |
| `api_rate_limit`   | number \| null | API rate limit (null = unlimited) |
| `support_level`    | string         | Support tier                      |

## Subscription Statuses

| Status         | Description                           |
| -------------- | ------------------------------------- |
| `active`       | Subscription is active                |
| `trialing`     | In trial period                       |
| `past_due`     | Payment failed, retrying              |
| `grace_period` | Subscription lapsed, features limited |
| `suspended`    | Account suspended                     |
| `canceled`     | Subscription canceled                 |

## Server-Side Usage (Next.js)

```typescript
// lib/hiveforge.ts
import { HiveForgeClient } from '@producthacker/sdk';

export const hiveforge = new HiveForgeClient({
  deploymentId: process.env.HIVEFORGE_DEPLOYMENT_ID!,
  deploymentSecret: process.env.HIVEFORGE_DEPLOYMENT_SECRET!,
});

// Initialize once on server start
if (typeof window === 'undefined') {
  hiveforge.initialize().catch(console.error);
}

// pages/api/ai.ts
import { hiveforge } from '@/lib/hiveforge';

export default async function handler(req, res) {
  const { message } = req.body;

  const response = await hiveforge.ai.complete({
    messages: [{ role: 'user', content: message }],
  });

  res.json({ content: response.content });
}
```

## Enterprise Self-Hosted Mode

For self-hosted enterprise deployments, use a JWT license key instead of deployment credentials:

```typescript
import { createEnterpriseLicenseManagerFromEnv } from '@producthacker/sdk';

// Create license manager from HIVEFORGE_LICENSE_KEY env var
const license = createEnterpriseLicenseManagerFromEnv();

// Initialize (validates license, decrypts API keys)
await license.initialize();

// Get decrypted API keys for direct API calls
const openaiKey = license.getApiKey('openai');
const stripeKey = license.getApiKey('stripe');

// Check features
if (license.isEnabled('ai_enabled')) {
  // Use OpenAI SDK directly with openaiKey
  const openai = new OpenAI({ apiKey: openaiKey });
  const response = await openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello!' }],
  });
}

// Get company info from license
console.log(license.getCompanyName()); // "Acme Corp"
console.log(license.getExpirationDate()); // Date object

// Check license validity
if (!license.isValid()) {
  console.error('License expired or invalid');
}

// Shutdown when done
license.shutdown();
```

### Enterprise Environment Variables

```env
HIVEFORGE_LICENSE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
HIVEFORGE_LICENSE_SIGNING_KEY=your-signing-key  # Must match server's signing key
```

### Enterprise Features

- **Offline Operation**: Works without internet for up to 30 days (configurable grace period)
- **Embedded API Keys**: OpenAI and Stripe keys encrypted in the license
- **Phone Home**: Optional periodic license validation
- **Direct API Access**: No proxy - call APIs directly with decrypted keys

## License

MIT