npm package: @qt-test/apex-sdk
Description: JavaScript SDK for APEX mini-app platform
Author: Interswitch
Latest version: 0.1.0

# @anthropic/apex-sdk

> JavaScript SDK for APEX mini-app platform

The official SDK for building mini-apps on the APEX super app platform. Provides type-safe APIs for device features, storage, networking, UI, payments, and more.

## Installation

```bash
npm install @anthropic/apex-sdk
# or
yarn add @anthropic/apex-sdk
```

## Quick Start

```typescript
import apex from '@anthropic/apex-sdk';

// Device info
const info = await apex.device.getInfo();
console.log(`Running on ${info.platform} ${info.osVersion}`);

// Storage
await apex.storage.set({ key: 'user', value: { name: 'John' } });
const { value } = await apex.storage.get({ key: 'user' });

// Network
const users = await apex.network.get('https://api.example.com/users');

// UI
await apex.ui.showToast({ title: 'Hello!', icon: 'success' });
const { confirm } = await apex.ui.showModal({
  title: 'Confirm',
  content: 'Are you sure?'
});

// Navigation
apex.navigateTo({ url: '/pages/detail/detail?id=123' });
```

## API Reference

### Device

```typescript
// Get device info
const info = await apex.device.getInfo();

// Haptic feedback
await apex.device.vibrate({ pattern: 'success' });

// Network status
const network = await apex.device.getNetworkType();
apex.device.onNetworkChange((info) => console.log(info));

// Screen
await apex.device.setScreenBrightness({ brightness: 0.8 });
await apex.device.keepScreenOn({ enabled: true });
```

### Storage

```typescript
// Basic operations
await apex.storage.set({ key: 'token', value: 'abc123' });
const { value } = await apex.storage.get({ key: 'token' });
await apex.storage.remove({ key: 'token' });
await apex.storage.clear();

// Convenience methods
const theme = await apex.storage.getOrDefault('theme', 'light');
const exists = await apex.storage.has('user');
await apex.storage.setMany({ a: 1, b: 2, c: 3 });
const values = await apex.storage.getMany(['a', 'b', 'c']);
```

### Network

```typescript
// Full request
const res = await apex.network.request({
  url: 'https://api.example.com/users',
  method: 'POST',
  headers: { 'Authorization': 'Bearer token' },
  data: { name: 'John' }
});

// Shorthand methods
const users = await apex.network.get('/users');
const user = await apex.network.post('/users', { name: 'John' });
await apex.network.put('/users/123', { name: 'Jane' });
await apex.network.delete('/users/123');

// File operations
const { tempFilePath } = await apex.network.downloadFile({ url: '...' });
await apex.network.uploadFile({
  url: 'https://api.example.com/upload',
  filePath: tempFilePath,
  name: 'file'
});
```

### UI

```typescript
// Toast
apex.ui.showToast({ title: 'Saved!', icon: 'success' });
apex.ui.success('Done!');
apex.ui.error('Failed!');

// Loading
apex.ui.showLoading({ title: 'Processing...' });
apex.ui.hideLoading();

// Or use withLoading helper
const result = await apex.ui.withLoading(async () => {
  return await fetchData();
}, 'Loading...');

// Modal
const { confirm } = await apex.ui.showModal({
  title: 'Delete',
  content: 'Are you sure?'
});

// Convenience
await apex.ui.alert('Error', 'Something went wrong');
const confirmed = await apex.ui.confirm('Delete', 'Are you sure?');

// Action sheet
const { index } = await apex.ui.showActionSheet({
  items: ['Edit', 'Share', 'Delete']
});

// Navigation bar
apex.ui.setNavigationBarTitle({ title: 'Details' });
apex.ui.setNavigationBarColor({
  backgroundColor: '#1890ff',
  frontColor: '#ffffff'
});
```

### Location

```typescript
// Get current location
const loc = await apex.location.get({ highAccuracy: true });
console.log(loc.latitude, loc.longitude);

// Watch location
const { watchId } = await apex.location.startWatch({ interval: 3000 });
apex.location.onPositionChange((loc) => updateMap(loc));
await apex.location.stopWatch({ watchId });

// Open in maps app
await apex.location.openLocation({
  latitude: 6.4541,
  longitude: 3.3947,
  name: 'Lagos Office'
});

// Pick a location
const selected = await apex.location.chooseLocation();

// Calculate distance
const meters = apex.location.getDistance(lat1, lng1, lat2, lng2);
```

### Media

```typescript
// Choose images
const { tempFiles } = await apex.media.chooseImage({ count: 3 });

// Convenience methods
const photo = await apex.media.takePhoto();
const image = await apex.media.pickImage();

// Video
const video = await apex.media.chooseVideo({ maxDuration: 30 });

// Preview
await apex.media.previewImage({ urls: ['...', '...'] });

// Save to album
await apex.media.saveImageToPhotosAlbum({ filePath: '...' });

// Scan codes
const { result } = await apex.media.scanCode();
const qr = await apex.media.scanQRCode();
const barcode = await apex.media.scanBarcode();
```

### Auth

```typescript
// Biometric authentication
const { success, authType } = await apex.auth.getBiometric({
  reason: 'Authenticate to continue'
});

// Require biometric (throws if fails)
await apex.auth.requireBiometric('Confirm payment');

// User info
const user = await apex.auth.getUserInfo();
console.log(user.nickname, user.phone); // phone is masked

// Get full phone (requires consent)
const { phoneNumber } = await apex.auth.getPhoneNumber();

// Check status
const available = await apex.auth.isBiometricAvailable();
const loggedIn = await apex.auth.isLoggedIn();
```

### Payment

```typescript
// Request payment
const result = await apex.payment.request({
  amount: 500000,      // ₦5,000.00 in kobo
  currency: 'NGN',
  description: 'Order #123'
});

if (result.success) {
  console.log('Paid! Ref:', result.transactionRef);
}

// Quick pay (amount in major units)
await apex.payment.pay(5000, 'Coffee');

// Wallet balance
const { balance, currency } = await apex.payment.getWalletBalance();

// Helpers
apex.payment.formatAmount(500000, 'NGN'); // '₦5,000.00'
apex.payment.parseAmount('5000.00');       // 500000
apex.payment.isValidAmount(500000, 'NGN'); // true
```

### Clipboard

```typescript
// Copy/paste
await apex.clipboard.set({ data: 'Hello' });
const { data } = await apex.clipboard.get();

// Convenience
await apex.clipboard.copy('ABC123');         // Shows 'Copied!' toast
await apex.clipboard.copy(code, 'Code copied!');
const text = await apex.clipboard.read();
const hasContent = await apex.clipboard.hasContent();
```

### Navigation

```typescript
// Navigate to page
apex.navigateTo({ url: '/pages/detail/detail?id=123' });

// Redirect (replace)
apex.redirectTo({ url: '/pages/login/login' });

// Go back
apex.navigateBack();
apex.navigateBack({ delta: 2 });

// Switch tab
apex.switchTab({ url: '/pages/home/home' });

// Relaunch (clear stack)
apex.reLaunch({ url: '/pages/index/index' });
```

### Events

```typescript
// Subscribe
apex.on('location', 'positionChanged', (loc) => {
  console.log(loc);
});

// Unsubscribe
apex.off('location', 'positionChanged', handler);

// Once
apex.once('device', 'networkChange', (info) => {
  console.log('Network changed:', info);
});

// Wait for event (Promise)
const loc = await waitFor('location', 'positionChanged', 5000);
```

## Error Handling

```typescript
import { BridgeError, isErrorCode } from '@anthropic/apex-sdk';

try {
  await apex.payment.request({ ... });
} catch (error) {
  if (error instanceof BridgeError) {
    switch (error.code) {
      case 'PAYMENT_CANCELLED':
        // User cancelled
        break;
      case 'PAYMENT_FAILED':
        apex.ui.error('Payment failed');
        break;
      case 'PERMISSION_DENIED':
        apex.ui.alert('Error', 'Payment permission required');
        break;
    }
  }
}

// Or use helper
if (isErrorCode(error, 'PAYMENT_CANCELLED')) {
  // Handle cancellation
}
```

## TypeScript

Full TypeScript support with all types exported:

```typescript
import type {
  Device,
  Storage,
  Network,
  UI,
  Location,
  Media,
  Auth,
  Payment,
  BridgeErrorCode,
} from '@anthropic/apex-sdk';

const info: Device.GetInfoResponse = await apex.device.getInfo();
const params: Payment.RequestParams = { amount: 5000, ... };
```

## License

MIT