PERS SDK / [Exports](/sdk-reference/modules)

# PERS SDK Introduction

The PERS SDK is a platform-agnostic TypeScript library that provides a clean, modern interface for integrating with the PERS (Phygital Experience Rewards System) platform. Built with a Manager-Service architecture, it offers consistent APIs for tourism loyalty applications across web, mobile, and server environments.

## What is PERS?

PERS is a comprehensive tourism loyalty platform that bridges physical and digital experiences through:

- **Loyalty Programs** - Token-based reward systems
- **Campaign Management** - Marketing campaigns and challenges
- **Business Operations** - Merchant and venue management
- **Payment Processing** - Integrated payment solutions
- **Blockchain Integration** - Web3 and digital token support
- **Analytics** - Comprehensive reporting and insights


## Installation

```bash
# Core SDK + required peer dependencies
npm install @explorins/pers-sdk @explorins/pers-shared ethers@^6.15.0
```

## Quick Start

### Basic Setup

```typescript
import { PersSDK } from "@explorins/pers-sdk";
import { BrowserFetchClientAdapter } from "@explorins/pers-sdk/platform-adapters";

const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
  environment: "production",
  // API Project Key is used to identify the Tenant Context.
  // It does NOT authenticate the user or admin.
  apiProjectKey: "your-project-key"
});
```

### Authentication Flow

```typescript
// Login with external JWT (Firebase, Auth0, etc.)
// This wraps the /auth/token endpoint using SessionAuthRequestDTO
await sdk.auth.loginWithToken(firebaseJWT, "user");

// Alternative: Login with raw user data (guest/anonymous users)
await sdk.auth.loginWithRawData({
  externalId: "guest-123",
  email: "guest@example.com",
  firstName: "Guest"
});

// Check authentication status
if (await sdk.auth.isAuthenticated()) {
  const user = await sdk.auth.getCurrentUser();
  console.log("Welcome,", user.name);
}
```

### Core Operations

```typescript
// Business operations
const businesses = await sdk.businesses.getActiveBusinesses();
const business = await sdk.businesses.getBusinessById("business-123");

// Campaign management
const campaigns = await sdk.campaigns.getActiveCampaigns();
const claim = await sdk.campaigns.claimCampaign({
  campaignId: "campaign-123",
  businessId: "business-456"  // Optional business context
});

// Token operations - get available tokens
const tokens = await sdk.tokens.getTokens();
const creditToken = await sdk.tokens.getActiveCreditToken();

// Transaction history
const transactions = await sdk.transactions.getUserTransactionHistory('ALL');

// File operations
const uploadUrl = await sdk.files.getSignedPutUrl("entity-123", "profile-image", "jpg");
const downloadUrl = await sdk.files.getSignedGetUrl("entity-123", "profile-image");
```

## Platform Integration

### Angular

```typescript
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { PersSDK } from "@explorins/pers-sdk";
import { AngularHttpClientAdapter } from "@explorins/pers-sdk/platform-adapters";

@Injectable({ providedIn: "root" })
export class PersSDKService {
  private sdk: PersSDK;

  constructor(httpClient: HttpClient) {
    this.sdk = new PersSDK(new AngularHttpClientAdapter(httpClient), {
      environment: "production",
      apiProjectKey: "your-project-key" // Tenant Context ID
    });
  }

  getSDK(): PersSDK {
    return this.sdk;
  }
}
```

### React/Browser

```typescript
import { PersSDK } from "@explorins/pers-sdk";
import { BrowserFetchClientAdapter } from "@explorins/pers-sdk/platform-adapters";

const sdk = new PersSDK(new BrowserFetchClientAdapter(), {
  environment: "production",
  apiProjectKey: "your-project-key"
});

// React Hook example
export function usePersSDK() {
  return sdk;
}
```

### Node.js

```typescript
import { PersSDK } from "@explorins/pers-sdk";
import { NodeHttpClientAdapter } from "@explorins/pers-sdk/platform-adapters";

const sdk = new PersSDK(new NodeHttpClientAdapter(), {
  environment: "production",
  apiProjectKey: "your-project-key"
});
```

## Architecture Overview

The SDK follows a clean Manager-Service pattern:

### Manager Layer (Primary Interface)

- **sdk.auth** - Authentication and user sessions
- **sdk.users** - User profile management
- **sdk.userStatus** - User status/tier management
- **sdk.tokens** - Token operations and balances
- **sdk.businesses** - Business operations
- **sdk.campaigns** - Marketing campaigns
- **sdk.redemptions** - Reward redemptions
- **sdk.transactions** - Transaction history
- **sdk.purchases** - Purchase and payment processing
- **sdk.files** - File upload and management
- **sdk.analytics** - Reporting and insights
- **sdk.tenants** - Multi-tenant configuration
- **sdk.apiKeys** - API key management (admin)
- **sdk.donations** - Charitable giving and donations
- **sdk.web3** - Blockchain operations and token balances


### Service Layer (Advanced Access)

For advanced operations, you can access services directly:

```typescript
const userService = sdk.users.getUserService();
const campaignService = sdk.campaigns.getCampaignService();
const fileService = sdk.files.getFileService();
```

## Core Features

### Authentication System

- External JWT integration (Firebase, Auth0, custom providers)
- Native token validation and refresh
- Support for both user and admin authentication flows
- Automatic token management and renewal


### Business Management

- Business registration and profile management
- Business type categorization
- Public business discovery
- Admin tools for business operations


### Campaign System

- Create and manage marketing campaigns
- User participation and claim tracking
- Advanced campaign triggers and automation
- Analytics and performance metrics


### Token Economy

- Multi-token support (credit, reward, utility tokens)
- Balance management and transfers
- Transaction history and analytics
- Integration with external payment systems


### User Token Balances (On-Chain)

> **Important**: User token balances are queried directly from the blockchain via `sdk.web3.*` methods, not stored in the PERS backend. See the npm package README for detailed examples.


### File Management

- Secure file upload and download
- Signed URL generation for direct browser access
- Media optimization and processing
- Cloud storage integration


### Reward Redemptions

- Flexible redemption offer system
- User redemption tracking
- Multiple redemption types (discounts, products, experiences)
- Inventory management


## Configuration

```typescript
interface PersConfig {
  environment?: "staging" | "production"; // Default: 'production'
  apiProjectKey: string; // Tenant Context Identifier (NOT for Auth)
  authStorage?: TokenStorage;  // Default: LocalStorage, recommend IndexedDB
  dpop?: { enabled?: boolean }; // Default: true (security feature)
  timeout?: number;
  retries?: number;
}
```

### Environment Configuration

- **development** - Local development and testing
- **staging** - Pre-production testing
- **production** - Live environment


### Authentication Options

You can provide a custom authentication provider or let the SDK create one automatically:

```typescript
// Auto-created provider (recommended)
const sdk = new PersSDK(httpClient, {
  environment: "production",
  apiProjectKey: "your-key"
});

// Custom provider
const sdk = new PersSDK(httpClient, {
  environment: "production",
  apiProjectKey: "your-key",
  authProvider: customAuthProvider
});
```

## Error Handling

```typescript
import { PersApiError, AuthenticationError } from "@explorins/pers-sdk/core";

try {
  const user = await sdk.auth.getCurrentUser();
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Handle 401 - redirect to login
  } else if (error instanceof PersApiError) {
    console.error("API Error:", error.message, error.status);
  }
}
```

## Performance Features

- **Bundle Size**: ~85 KB minified
- **Tree-shaking**: Import only what you need
- **Zero External Auth Dependencies**: Native browser APIs
- **Intelligent Token Refresh**: Background refresh with race condition protection
- **Request Optimization**: Automatic retry and timeout handling


## TypeScript Support

The SDK provides full TypeScript support with type inference. All domain types are exported from `@explorins/pers-shared`:

```typescript
import type { CampaignDTO, BusinessDTO, TokenDTO } from '@explorins/pers-shared';

const campaigns = await sdk.campaigns.getActiveCampaigns(); // CampaignDTO[]
```

## Advanced Usage

### Direct API Access

For operations not covered by managers:

```typescript
const apiClient = sdk.api();
const customData = await apiClient.get("/custom-endpoint");
await apiClient.post("/custom-endpoint", data);
```

### Custom HTTP Client

Implement your own HTTP client for specific requirements:

```typescript
import { HttpClient, RequestOptions } from "@explorins/pers-sdk/core";

class CustomHttpClient implements HttpClient {
  async get<T>(url: string, options?: RequestOptions): Promise<T> {
    // Your implementation
  }
  // ... other methods
}

const sdk = new PersSDK(new CustomHttpClient(), config);
```

### Web3 / Blockchain Operations

Query token balances and owned NFTs directly from the blockchain:

```typescript
// Get reward tokens configuration
const rewardTokens = await sdk.tokens.getRewardTokens();

// Query owned tokens for any wallet address
const result = await sdk.web3.getAccountOwnedTokensFromContract(
  walletAddress,
  rewardTokens[0]
);

console.log(`Wallet owns ${result.totalOwned} tokens`);
result.ownedTokens.forEach(token => {
  console.log(`- ${token.metadata?.name}: ${token.balance}`);
});

// Get blockchain explorer URL
const explorerUrl = await sdk.web3.getExplorerUrl(
  chainId,
  transactionHash,
  'tx'
);
```

## Related Packages

- **[@explorins/pers-sdk-react-native](https://www.npmjs.com/package/@explorins/pers-sdk-react-native)** - React Native integration with passkey support, secure storage, and DPoP. **Use this for React Native apps** instead of the core SDK.
- **[@explorins/pers-shared](https://www.npmjs.com/package/@explorins/pers-shared)** - Shared types, interfaces, and DTOs used across PERS ecosystem (required peer dependency)


## Support and Resources

- **Package**: [npm package](https://www.npmjs.com/package/@explorins/pers-sdk)
- **Platform Documentation**: [PERS Platform Docs](https://docs.pers.ninja/1.intro)
- **Support**: Contact support@explorins.com for issues and feature requests


## License

MIT License - See package for full license details.