hp-app-bundle-sdk
v1.0.6
Published
A comprehensive SDK for building mini-applications.
Maintainers
Readme
MiniApp SDK
A comprehensive TypeScript SDK for building native mobile mini-applications with modular architecture, native bridge communication, and extensive platform integration capabilities.
Introduction
The MiniApp SDK provides a unified interface for developing mini-applications that run within native mobile apps. It offers a modular architecture with dedicated managers for authentication, payments, UI components, storage, caching, and utility functions. The SDK handles native bridge communication, event management, and provides both modern module-based APIs and legacy compatibility.
Installation
# Using npm
npm install hp-app-bundle-sdk
# Using yarn
yarn add hp-app-bundle-sdkProject Structure
The SDK follows a modular architecture with clear separation of concerns:
src/
├── core/ # Core SDK functionality
│ ├── MiniApp.ts # Main SDK class
│ ├── ConfigManager.ts # Configuration management
│ ├── EventManager.ts # Event system
│ ├── NativeBridge.ts # Native communication
│ └── types.ts # Core type definitions
├── modules/ # Feature modules
│ ├── auth/ # Authentication module
│ ├── biometrics/ # Biometric authentication
│ ├── cache/ # Caching system
│ ├── contacts/ # Device contacts
│ ├── payment/ # Payment processing
│ ├── storage/ # Data storage
│ ├── ui/ # UI components
│ └── utility/ # Utility functions
└── index.ts # Main exportsCore Components
- MiniApp: Main SDK class that orchestrates all modules and provides legacy compatibility
- ConfigManager: Handles SDK configuration with deep merging and validation
- EventManager: Type-safe event system for inter-module communication
- NativeBridge: Manages communication between JavaScript and native platforms
Module Managers
- AuthManager: Handles Firebase, Google, and Facebook authentication
- BiometricsManager: Manages biometric authentication (TouchID, FaceID, fingerprint)
- CacheManager: Provides in-memory and persistent caching with TTL and LRU eviction
- ContactManager: Device contacts access with permission management
- PaymentManager: Payment processing, verification, and history
- StorageManager: Secure and standard storage with encryption support
- UIManager: Native UI components (toasts, alerts, loading indicators)
- UtilityManager: Utility functions (QR codes, file downloads, sharing, calling)
Complete Method Reference
AuthManager
Handles user authentication with multiple providers including Firebase, Google, and Facebook.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| login(provider?) | provider?: 'google' \| 'facebook' \| 'firebase' | Promise<UserProfile> | Authenticate user with specified provider (default: firebase) |
| logout() | None | Promise<void> | Log out current user and clear tokens |
| getAccessToken() | None | Promise<string> | Get current access token |
| isAuthenticated() | None | Promise<boolean> | Check if user is authenticated |
| getUserProfile() | None | Promise<UserProfile> | Get current user profile |
| firebaseSignOut() | None | Promise<void> | Sign out from Firebase |
| initializeFirebase(config) | config: FirebaseAuthConfig | void | Initialize Firebase with config |
UIManager
Provides native UI components and interactions with web fallbacks.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| showToast(message, options?) | message: string, options?: ToastOptions | Promise<void> | Show toast notification |
| showAlert(message, options?) | message: string, options?: AlertOptions | Promise<void> | Show alert dialog |
| showConfirm(message, options?) | message: string, options?: ConfirmOptions | Promise<boolean> | Show confirmation dialog |
| showActionSheet(options) | options: ActionSheetOptions | Promise<string \| null> | Show action sheet with options |
| showLoading(options?) | options?: LoadingOptions | Promise<void> | Show loading indicator |
| hideLoading() | None | Promise<void> | Hide loading indicator |
| setTitle(title) | title: string | Promise<void> | Set navigation bar title |
| setNavigationBarColor(color, textColor?) | color: string, textColor?: 'light' \| 'dark' | Promise<void> | Set navigation bar color |
PaymentManager
Handles payment processing, verification, and history with auto-verification support.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| makePayment(request) | request: PaymentRequest | Promise<PaymentResult> | Process payment with auto-verification |
| verifyPayment(referenceId) | referenceId: string | Promise<PaymentResult> | Verify payment by reference ID |
| getPaymentHistory(options?) | options?: { limit?: number, offset?: number } | Promise<PaymentResult[]> | Get payment history with pagination |
ContactManager
Manages device contacts with comprehensive permission handling.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| checkPermission() | None | Promise<ContactsPermissionResult> | Check current permission status |
| requestPermission() | None | Promise<ContactsPermissionResult> | Request contacts permission |
| getContacts(options?) | options?: { limit?: number, offset?: number } | Promise<Contact[]> | Get device contacts with pagination |
| searchContacts(query, options?) | query: string, options?: { limit?: number } | Promise<Contact[]> | Search contacts by query |
| getContact(contactId) | contactId: string | Promise<Contact \| null> | Get specific contact by ID |
BiometricsManager
Handles biometric authentication (TouchID, FaceID, Fingerprint).
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| isAvailable() | None | Promise<boolean> | Check if biometrics are available |
| getBiometryType() | None | Promise<'TouchID' \| 'FaceID' \| 'Fingerprint' \| 'None'> | Get available biometry type |
| authenticate(reason?) | reason?: string | Promise<BiometricResult> | Authenticate with biometrics |
StorageManager
Provides secure and standard storage with encryption support.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| setItem(key, value) | key: string, value: any | Promise<void> | Store data with optional encryption |
| getItem<T>(key) | key: string | Promise<T \| null> | Retrieve and decrypt data |
| removeItem(key) | key: string | Promise<void> | Remove stored item |
| clear() | None | Promise<void> | Clear all stored data |
| getAllKeys() | None | Promise<string[]> | Get all storage keys |
CacheManager
Intelligent caching with TTL, LRU eviction, and size management.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| set<T>(key, value, ttl?) | key: string, value: T, ttl?: number | Promise<void> | Cache data with optional TTL |
| get<T>(key) | key: string | Promise<T \| undefined> | Retrieve cached data |
| delete(key) | key: string | Promise<boolean> | Remove cached item |
| clear() | None | Promise<void> | Clear all cached data |
| has(key) | key: string | Promise<boolean> | Check if key exists in cache |
| getStats() | None | { hits: number, misses: number, totalSize: number } | Get cache statistics |
| cleanup() | None | Promise<void> | Remove expired items |
UtilityManager
Utility functions for QR codes, downloads, sharing, and calling with timeout support.
| Method | Parameters | Return Value | Description |
|--------|------------|--------------|-------------|
| showQR(qrData, productType) | qrData: string, productType: string | Promise<any> | Display QR code with timeout |
| downloadFile(url, fileType, productType) | url: string, fileType: string, productType: string | Promise<any> | Download file with timeout |
| share(content, imageUrl?) | content: string, imageUrl?: string | Promise<any> | Share content with timeout |
| call(payload, productType, credentials, meetingId) | payload: string, productType: string, credentials: string, meetingId: string | Promise<any> | Make call with timeout |
Usage Guide
Basic Setup
import { MiniApp } from 'hp-app-bundle-sdk';
// Initialize with optional configuration
const miniapp = new MiniApp({
core: {
logLevel: 'info',
enableAnalytics: true,
autoInitialize: false
}
});
// Initialize with client ID
await miniapp.init('your-client-id');Using Multiple Modules Simultaneously
Example 1: Secure Payment Flow with Biometric Authentication
const miniapp = new MiniApp();
await miniapp.init('your-client-id');
// Initialize modules
const auth = miniapp.useAuth({ autoRefresh: true });
const biometrics = miniapp.useBiometrics({ allowDeviceCredentials: true });
const payment = miniapp.usePayment({ autoVerify: true });
const ui = miniapp.useUI();
const storage = miniapp.useStorage({ defaultStorage: 'secure', encrypt: true });
async function processSecurePayment(amount: number, description: string) {
try {
// 1. Check if user is authenticated
const isAuth = await auth.isAuthenticated();
if (!isAuth) {
await ui.showAlert('Please login first');
const user = await auth.login('firebase');
await ui.showToast(`Welcome, ${user.name}!`);
}
// 2. Verify biometric authentication for high-value transactions
if (amount > 1000) {
const biometricAvailable = await biometrics.isAvailable();
if (biometricAvailable) {
const biometricResult = await biometrics.authenticate(
`Authenticate payment of $${amount}`
);
if (!biometricResult.success) {
await ui.showAlert('Biometric authentication required for this transaction');
return;
}
}
}
// 3. Show loading and process payment
await ui.showLoading({ text: 'Processing payment...', cancelable: false });
const paymentResult = await payment.makePayment({
amount: amount * 100, // Convert to cents
currency: 'USD',
description,
referenceId: `txn_${Date.now()}`
});
await ui.hideLoading();
// 4. Handle payment result
if (paymentResult.success) {
// Store transaction for offline access
await storage.setItem(`transaction_${paymentResult.transactionId}`, {
...paymentResult,
timestamp: new Date().toISOString()
});
await ui.showToast('Payment successful!');
return paymentResult;
} else {
await ui.showAlert('Payment failed. Please try again.');
}
} catch (error) {
await ui.hideLoading();
await ui.showAlert(`Error: ${error.message}`);
}
}
// Usage
await processSecurePayment(1500, 'Premium subscription');Example 2: Contact Sharing with Caching and UI Feedback
const miniapp = new MiniApp();
await miniapp.init('your-client-id');
// Initialize modules
const contacts = miniapp.useContacts();
const cache = miniapp.useCache({ maxSize: 5 * 1024 * 1024, defaultTTL: 3600000 });
const ui = miniapp.useUI();
const utility = miniapp.useUtility({ timeout: 30000 });
async function shareContactList() {
try {
// 1. Check cache first
let contactList = await cache.get('device_contacts');
if (!contactList) {
// 2. Request permission with user feedback
await ui.showLoading({ text: 'Requesting contacts permission...' });
const permission = await contacts.requestPermission();
await ui.hideLoading();
if (!permission.granted) {
const retry = await ui.showConfirm(
'Contacts permission is required to share your contact list. Would you like to try again?'
);
if (retry && permission.canAskAgain) {
return await shareContactList(); // Retry
} else {
await ui.showAlert('Cannot share contacts without permission');
return;
}
}
// 3. Fetch contacts with progress feedback
await ui.showLoading({ text: 'Loading contacts...' });
contactList = await contacts.getContacts({ limit: 500 });
await ui.hideLoading();
// 4. Cache the results
await cache.set('device_contacts', contactList);
await ui.showToast(`Loaded ${contactList.length} contacts`);
} else {
await ui.showToast(`Using cached contacts (${contactList.length} items)`);
}
// 5. Let user select sharing method
const shareMethod = await ui.showActionSheet({
title: 'How would you like to share?',
options: ['Share as Text', 'Generate QR Code', 'Send via Email'],
cancelText: 'Cancel'
});
if (!shareMethod || shareMethod === 'Cancel') return;
// 6. Process based on selection
const contactText = contactList.map(c => `${c.name}: ${c.phoneNumbers?.[0]}`).join('\n');
switch (shareMethod) {
case 'Share as Text':
await utility.share(contactText);
break;
case 'Generate QR Code':
await utility.showQR(JSON.stringify(contactList), 'contacts');
break;
case 'Send via Email':
await utility.share(
`My Contacts:\n\n${contactText}`,
undefined // No image
);
break;
}
await ui.showToast('Contacts shared successfully!');
} catch (error) {
await ui.hideLoading();
await ui.showAlert(`Failed to share contacts: ${error.message}`);
}
}
// Usage
await shareContactList();Example 3: Multi-Module Data Sync with Event Handling
const miniapp = new MiniApp();
await miniapp.init('your-client-id');
// Initialize all modules
const auth = miniapp.useAuth({ autoRefresh: true });
const storage = miniapp.useStorage({ defaultStorage: 'secure', encrypt: true });
const cache = miniapp.useCache({ storageType: 'localStorage', defaultTTL: 1800000 });
const ui = miniapp.useUI();
const payment = miniapp.usePayment();
// Set up event listeners for cross-module communication
miniapp.events.on('auth:login:success', async (event) => {
const user = event.data;
// Cache user profile
await cache.set('current_user', user, 3600000); // 1 hour
// Load user preferences from storage
const preferences = await storage.getItem('user_preferences');
if (preferences) {
await ui.showToast(`Welcome back, ${user.name}!`);
} else {
await ui.showToast(`Welcome, ${user.name}! Setting up your profile...`);
// Set default preferences
await storage.setItem('user_preferences', {
theme: 'light',
notifications: true,
autoSync: true
});
}
});
miniapp.events.on('payment:completed', async (event) => {
const paymentResult = event.data;
if (paymentResult.success) {
// Update user's payment history in cache
const existingHistory = await cache.get('payment_history') || [];
existingHistory.unshift(paymentResult);
await cache.set('payment_history', existingHistory.slice(0, 10)); // Keep last 10
// Store in secure storage for persistence
await storage.setItem(`payment_${paymentResult.transactionId}`, paymentResult);
await ui.showToast('Payment recorded successfully!');
}
});
miniapp.events.on('storage:error', async (event) => {
console.error('Storage error:', event.error);
await ui.showAlert('Data sync failed. Please try again.');
});
// Main application flow
async function initializeApp() {
try {
await ui.showLoading({ text: 'Initializing app...' });
// Check for cached user session
const cachedUser = await cache.get('current_user');
if (cachedUser && await auth.isAuthenticated()) {
await ui.showToast(`Welcome back, ${cachedUser.name}!`);
} else {
// Prompt for login
const shouldLogin = await ui.showConfirm('Would you like to sign in?');
if (shouldLogin) {
await auth.login('firebase');
}
}
// Load cached payment history
const paymentHistory = await cache.get('payment_history');
if (paymentHistory?.length > 0) {
console.log(`Loaded ${paymentHistory.length} recent payments`);
}
await ui.hideLoading();
await ui.showToast('App ready!');
} catch (error) {
await ui.hideLoading();
await ui.showAlert(`Initialization failed: ${error.message}`);
}
}
// Start the app
await initializeApp();Example 4: Offline-First Architecture with Multiple Modules
const miniapp = new MiniApp();
await miniapp.init('your-client-id');
// Initialize modules for offline-first approach
const storage = miniapp.useStorage({ defaultStorage: 'localStorage', encrypt: false });
const cache = miniapp.useCache({ storageType: 'localStorage', maxSize: 10 * 1024 * 1024 });
const ui = miniapp.useUI();
const auth = miniapp.useAuth({ tokenStorage: 'localStorage' });
class OfflineDataManager {
constructor(private miniapp: MiniApp) {}
async syncData() {
const ui = this.miniapp.useUI();
const storage = this.miniapp.useStorage({ defaultStorage: 'localStorage' });
const cache = this.miniapp.useCache({ storageType: 'localStorage' });
try {
await ui.showLoading({ text: 'Syncing data...' });
// Get pending offline actions
const pendingActions = await storage.getItem('pending_actions') || [];
if (pendingActions.length > 0) {
for (const action of pendingActions) {
try {
await this.processAction(action);
// Remove successful action
const updatedActions = pendingActions.filter(a => a.id !== action.id);
await storage.setItem('pending_actions', updatedActions);
} catch (error) {
console.error(`Failed to sync action ${action.id}:`, error);
}
}
}
// Update cache with fresh data
await this.refreshCache();
await ui.hideLoading();
await ui.showToast('Data synced successfully!');
} catch (error) {
await ui.hideLoading();
await ui.showAlert(`Sync failed: ${error.message}`);
}
}
async addOfflineAction(action: any) {
const storage = this.miniapp.useStorage({ defaultStorage: 'localStorage' });
const pendingActions = await storage.getItem('pending_actions') || [];
pendingActions.push({
...action,
id: `action_${Date.now()}`,
timestamp: new Date().toISOString()
});
await storage.setItem('pending_actions', pendingActions);
}
private async processAction(action: any) {
// Process different types of offline actions
switch (action.type) {
case 'payment':
const payment = this.miniapp.usePayment();
return await payment.makePayment(action.data);
case 'contact_update':
const contacts = this.miniapp.useContacts();
return await contacts.getContacts(); // Refresh contacts
default:
throw new Error(`Unknown action type: ${action.type}`);
}
}
private async refreshCache() {
const cache = this.miniapp.useCache({ storageType: 'localStorage' });
// Clear expired items
await cache.cleanup();
// Refresh critical data
const auth = this.miniapp.useAuth();
if (await auth.isAuthenticated()) {
const userProfile = await auth.getUserProfile();
await cache.set('user_profile', userProfile, 3600000); // 1 hour
}
}
}
// Usage
const dataManager = new OfflineDataManager(miniapp);
// Sync data when app starts
await dataManager.syncData();
// Add offline actions when network is unavailable
await dataManager.addOfflineAction({
type: 'payment',
data: { amount: 5000, currency: 'USD', description: 'Offline payment' }
});Event-Driven Architecture
// Set up comprehensive event handling across all modules
const miniapp = new MiniApp();
await miniapp.init('your-client-id');
// Global error handler
miniapp.events.on('*:error', async (event) => {
console.error('Module error:', event);
const ui = miniapp.useUI();
await ui.showToast('An error occurred. Please try again.');
});
// Authentication events
miniapp.events.on('auth:login:success', (event) => {
console.log('User logged in:', event.data.email);
});
miniapp.events.on('auth:logout:success', () => {
console.log('User logged out');
// Clear sensitive data
const cache = miniapp.useCache({ storageType: 'memory' });
cache.clear();
});
// Payment events
miniapp.events.on('payment:completed', (event) => {
if (event.data.success) {
console.log('Payment successful:', event.data.transactionId);
}
});
// UI events
miniapp.events.on('ui:showToast:success', (event) => {
console.log('Toast shown:', event.data);
});
// Storage events
miniapp.events.on('storage:set', (event) => {
console.log('Data stored:', event.data.key);
});
// Utility events
miniapp.events.on('utility:share:success', () => {
console.log('Content shared successfully');
});Module Configuration Examples
// Configure modules with specific settings
const miniapp = new MiniApp({
core: {
logLevel: 'debug',
enableAnalytics: true
}
});
// Auth with multiple providers
const auth = miniapp.useAuth({
autoRefresh: true,
refreshInterval: 300000, // 5 minutes
tokenStorage: 'localStorage',
providers: {
firebase: {
apiKey: 'your-api-key',
authDomain: 'your-domain.firebaseapp.com'
},
google: {
clientId: 'your-google-client-id'
}
}
});
// UI with custom settings
const ui = miniapp.useUI({
toastDuration: 5000,
alertTitle: 'MyApp',
confirmTitle: 'Confirm Action',
loadingText: 'Please wait...'
});
// Payment with auto-verification
const payment = miniapp.usePayment({
defaultCurrency: 'USD',
autoVerify: true
});
// Storage with encryption
const storage = miniapp.useStorage({
defaultStorage: 'secure',
encrypt: true,
keyPrefix: 'myapp_'
});
// Cache with size limits
const cache = miniapp.useCache({
maxSize: 50 * 1024 * 1024, // 50MB
defaultTTL: 1800000, // 30 minutes
storageType: 'localStorage'
});
// Biometrics with fallback
const biometrics = miniapp.useBiometrics({
allowDeviceCredentials: true,
promptMessage: 'Authenticate to continue',
cancelButtonText: 'Cancel',
fallbackButtonText: 'Use Password'
});
// Contacts with auto-permission
const contacts = miniapp.useContacts({
requestPermissionOnInit: true
});
// Utility with custom timeout
const utility = miniapp.useUtility({
timeout: 45000 // 45 seconds
});