npm package: @margdarsan/sdk
Description: Margdarsan SDK for mobile and web applications with Firebase-like configuration
Author: Margdarsan
Latest version: 1.0.0

# @margdarsan/sdk

Firebase-like SDK for Margdarsan with comprehensive license validation, app registration, and feature management for iOS, Android, and Web applications.

## Features

- 🔐 **License Validation** - Automatic app credential validation with online/offline support
- 📱 **Multi-Platform** - Works on iOS, Android, React Native, and Web
- 🚀 **Auto-Configuration** - Firebase-like config file setup
- 📊 **Telemetry & Analytics** - Built-in event tracking and error reporting
- 🔄 **Offline Mode** - Graceful offline operation with configurable grace periods
- 🛡️ **Security** - SHA fingerprint validation for Android, Bundle ID validation for iOS
- ⚡ **Lightweight** - Minimal dependencies, optimized bundle size

## Installation

```bash
npm install @margdarsan/sdk
# or
yarn add @margdarsan/sdk
```

For React Native, you'll also need:

```bash
npm install @react-native-async-storage/async-storage
```

## Quick Start

### 1. Register Your App

Visit your Margdarsan Super Admin Dashboard and register your app:
1. Go to Tenants → Select Tenant → Apps & Licenses
2. Click "Register New App"
3. Select your platform (iOS/Android/Web)
4. Fill in the required credentials
5. Download the configuration file

### 2. Add Configuration File

#### iOS
1. Download `MargdarsanConfig.plist`
2. Add it to your Xcode project
3. Ensure it's included in the app bundle (Target → Build Phases → Copy Bundle Resources)

#### Android
1. Download `margdarsan-services.json`
2. Place it in `android/app/src/main/assets/`
3. Create the directory if it doesn't exist

#### Web
1. Download `margdarsan-config.js`
2. Include it in your HTML before your app bundle:
```html
<script src="/path/to/margdarsan-config.js"></script>
```

### 3. Initialize SDK

#### Auto-Initialization (Recommended)

```typescript
import { MargdarsanSDK } from '@margdarsan/sdk';

// Auto-initialize from config file
const sdk = await MargdarsanSDK.autoInit();

// Check license status
const isValid = await sdk.isLicenseValid();

if (isValid) {
  // App is licensed, continue normal operation
  console.log('App is licensed!');
} else {
  // Show license error
  console.error('App is not licensed');
}
```

#### Manual Initialization

```typescript
import { MargdarsanSDK } from '@margdarsan/sdk';

const sdk = MargdarsanSDK.init({
  tenantId: 'your-tenant-id',
  appId: 'your-app-id',
  apiBaseUrl: 'https://api.margdarsan.com',
  autoValidate: true,
  enableOfflineMode: true,
  gracePeriodDays: 30,
  enableTelemetry: true,
});
```

## Usage Examples

### React Native Example

```typescript
import React, { useState, useEffect } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { MargdarsanSDK } from '@margdarsan/sdk';

export default function App() {
  const [sdk, setSdk] = useState(null);
  const [isLicensed, setIsLicensed] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function initializeSDK() {
      try {
        const sdkInstance = await MargdarsanSDK.autoInit();
        setSdk(sdkInstance);

        const licenseStatus = await sdkInstance.getCachedLicenseStatus();
        setIsLicensed(licenseStatus?.valid || false);

        // Listen for license changes
        sdkInstance.on('licenseStatusChanged', (status) => {
          setIsLicensed(status.valid);
        });

        setLoading(false);
      } catch (error) {
        console.error('Failed to initialize SDK:', error);
        setLoading(false);
      }
    }

    initializeSDK();
  }, []);

  if (loading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator />
      </View>
    );
  }

  if (!isLicensed) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>App is not licensed. Please contact support.</Text>
      </View>
    );
  }

  return <YourApp sdk={sdk} />;
}
```

### Web Example

```typescript
import { MargdarsanSDK } from '@margdarsan/sdk';

async function initApp() {
  try {
    // Auto-init from margdarsan-config.js
    const sdk = await MargdarsanSDK.autoInit();

    // Validate license
    const result = await sdk.validateLicense();

    if (result.valid) {
      console.log('✓ App is licensed');
      startApp();
    } else {
      console.error('✗ License validation failed:', result.message);
      showLicenseError(result.message);
    }
  } catch (error) {
    console.error('SDK initialization failed:', error);
  }
}

initApp();
```

### Feature Checking

```typescript
// Check if specific features are enabled
const hasOPD = await sdk.hasFeature('opd');
const hasBilling = await sdk.hasFeature('billing');

if (hasOPD) {
  // Enable OPD module
}

if (hasBilling) {
  // Enable billing module
}
```

### Event Tracking

```typescript
// Track custom events
sdk.trackEvent('user_login', {
  userId: 'user123',
  timestamp: new Date().toISOString(),
});

sdk.trackEvent('appointment_created', {
  doctorId: 'doc456',
  patientId: 'pat789',
});
```

### Event Listeners

```typescript
// Listen for license status changes
sdk.on('licenseStatusChanged', (status) => {
  console.log('License status changed:', status);
});

// Listen for validation errors
sdk.on('validationError', (error) => {
  console.error('Validation error:', error);
});

// Listen for initialization
sdk.on('initialized', (data) => {
  console.log('SDK initialized on platform:', data.platform);
});
```

## API Reference

### MargdarsanSDK

#### Static Methods

- `MargdarsanSDK.init(config: SDKConfig): MargdarsanSDK` - Initialize SDK with configuration
- `MargdarsanSDK.autoInit(): Promise<MargdarsanSDK>` - Auto-initialize from config file
- `MargdarsanSDK.getInstance(): MargdarsanSDK` - Get SDK instance

#### Instance Methods

- `validateLicense(): Promise<ValidationResult>` - Validate app license with server
- `getCachedLicenseStatus(): Promise<CachedLicenseStatus | null>` - Get cached license status
- `isLicenseValid(): Promise<boolean>` - Check if license is valid
- `hasFeature(featureCode: string): Promise<boolean>` - Check if feature is enabled
- `trackEvent(eventType: string, eventData: any): void` - Track telemetry event
- `on(eventType: SDKEventType, handler: Function): void` - Register event handler
- `off(eventType: SDKEventType, handler: Function): void` - Unregister event handler
- `getPlatform(): string` - Get current platform
- `getConfig(): SDKConfig` - Get SDK configuration
- `destroy(): void` - Destroy SDK instance

## Configuration Options

```typescript
interface SDKConfig {
  tenantId: string;              // Your tenant ID
  appId: string;                 // Your app ID
  apiBaseUrl: string;            // API base URL
  platform?: Platform;           // Platform (auto-detected if not provided)
  autoValidate?: boolean;        // Auto-validate on init (default: true)
  validationFrequencyHours?: number;  // Validation frequency (default: 24)
  enableOfflineMode?: boolean;   // Enable offline mode (default: true)
  gracePeriodDays?: number;      // Offline grace period (default: 30)
  enableTelemetry?: boolean;     // Enable telemetry (default: true)
  debug?: boolean;               // Enable debug logs (default: false)
  credentials?: AppCredentials;  // Manual credentials (auto-detected if not provided)
}
```

## Platform-Specific Setup

### iOS

#### Find Your Bundle ID

```bash
# In your iOS project
cat YourApp.xcodeproj/project.pbxproj | grep PRODUCT_BUNDLE_IDENTIFIER
```

Or check in Xcode: **Target → General → Bundle Identifier**

### Android

#### Generate SHA Fingerprints

For debug key:
```bash
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
```

For release key:
```bash
keytool -list -v -keystore /path/to/your/keystore.jks -alias your-alias
```

Copy the SHA-1 and SHA-256 fingerprints and add them in the Super Admin portal.

### Web

Configure allowed domains in the Super Admin portal:
- Development: `localhost:3000`, `localhost:8080`
- Production: `yourdomain.com`
- Wildcard subdomains: `*.yourdomain.com`

## Security Best Practices

1. **Never hardcode credentials** - Always use configuration files
2. **Protect config files** - Don't commit them to version control
3. **Use release keys** - Generate separate SHA fingerprints for release builds
4. **Enable enforcement** - Set violation action to "block" in production
5. **Monitor validation logs** - Check the Super Admin dashboard regularly

## Troubleshooting

### "App not registered" Error

- Ensure you've registered your app in the Super Admin dashboard
- Verify Bundle ID / Package Name matches exactly
- Check that the app status is "Active" (not suspended or revoked)

### "SHA fingerprint mismatch" (Android)

- Generate SHA fingerprint for your current keystore
- Add it to your app registration in the Super Admin dashboard
- Ensure you're using the correct keystore (debug vs release)

### "Domain not allowed" (Web)

- Add your domain to the allowed domains list
- Use wildcard domains (`*.yourdomain.com`) for subdomains
- Check CORS settings if applicable

### License expired

- Check the grace period settings
- Validate license manually: `await sdk.validateLicense()`
- Contact your administrator if the issue persists

## Support

- **Documentation**: https://docs.margdarsan.com/sdk
- **Issues**: https://github.com/margdarsan/sdk/issues
- **Email**: support@margdarsan.com

## License

MIT © Margdarsan