Official React Native SDK for Bota wearable devices.
npm install @bota-dev/react-native-sdk react-native-ble-plx
# or
yarn add @bota-dev/react-native-sdk react-native-ble-plx- Add Bluetooth permissions to
ios/YourApp/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to connect to Bota recording devices</string>
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
</array>- Install pods:
cd ios && pod install- Add permissions to
android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />import { BotaClient } from '@bota-dev/react-native-sdk';
// Initialize SDK
await BotaClient.configure({
environment: 'production',
logLevel: 'info',
});
// Wait for Bluetooth
await BotaClient.waitForBluetooth();
// Scan for devices
BotaClient.devices.on('deviceDiscovered', (device) => {
console.log('Found device:', device.name);
});
BotaClient.devices.startScan();
// Connect to a device
const connectedDevice = await BotaClient.devices.connect(discoveredDevice);
// Provision with token from your backend
await BotaClient.devices.provision(connectedDevice, deviceToken, 'production');
// List recordings
const recordings = await BotaClient.recordings.listRecordings(connectedDevice);
// Sync a recording
for await (const progress of BotaClient.recordings.syncRecording(
connectedDevice,
recording,
uploadInfo // from your backend
)) {
console.log(`${progress.stage}: ${progress.progress * 100}%`);
}Main entry point for the SDK.
// Configure SDK
await BotaClient.configure({
environment: 'production' | 'sandbox',
backgroundSyncEnabled: boolean,
wifiOnlyUpload: boolean,
logLevel: 'debug' | 'info' | 'warn' | 'error' | 'none',
});
// Access managers
BotaClient.devices // DeviceManager
BotaClient.recordings // RecordingManager
BotaClient.ota // OTAManager
// State
BotaClient.state // 'uninitialized' | 'initializing' | 'ready' | 'error'
BotaClient.bluetoothState // 'unknown' | 'poweredOn' | 'poweredOff' | ...
BotaClient.isBluetoothReadyHandles device discovery, connection, and provisioning.
// Scanning
BotaClient.devices.startScan({ timeout: 30000, deviceTypes: ['bota_pin'] });
BotaClient.devices.stopScan();
BotaClient.devices.getDiscoveredDevices();
// Connection
const device = await BotaClient.devices.connect(discoveredDevice);
await BotaClient.devices.disconnect(device);
BotaClient.devices.isConnected(deviceId);
// Provisioning
await BotaClient.devices.provision(device, token, 'production');
await BotaClient.devices.isProvisioned(device);
// Status
const status = await BotaClient.devices.getStatus(device);
const unsubscribe = BotaClient.devices.subscribeToStatus(device, (status) => {});
// Events
BotaClient.devices.on('deviceDiscovered', (device) => {});
BotaClient.devices.on('deviceConnected', (device) => {});
BotaClient.devices.on('deviceDisconnected', (deviceId, error) => {});
BotaClient.devices.on('deviceStatusUpdated', (deviceId, status) => {});Handles recording transfer and upload.
// List recordings on device
const recordings = await BotaClient.recordings.listRecordings(device);
// Sync a recording (transfer + upload)
for await (const progress of BotaClient.recordings.syncRecording(
device,
recording,
uploadInfo
)) {
// progress.stage: 'preparing' | 'transferring' | 'uploading' | 'completing' | 'completed' | 'failed'
// progress.progress: 0.0 - 1.0
}
// Sync all recordings
for await (const progress of BotaClient.recordings.syncAllRecordings(
device,
async (recording) => {
// Get upload info from your backend
return await yourBackend.getUploadInfo(device.serialNumber, recording);
}
)) {
console.log(`Recording ${progress.recordingIndex}/${progress.totalRecordings}`);
}
// Upload queue management
BotaClient.recordings.getPendingUploads();
BotaClient.recordings.cancelUpload(taskId);
BotaClient.recordings.retryFailedUploads();
BotaClient.recordings.pauseUploads();
BotaClient.recordings.resumeUploads();
// Events
BotaClient.recordings.on('syncStarted', (uuid) => {});
BotaClient.recordings.on('syncCompleted', (uuid, recordingId) => {});
BotaClient.recordings.on('syncFailed', (uuid, error) => {});
BotaClient.recordings.on('uploadProgress', (taskId, progress) => {});interface DiscoveredDevice {
id: string;
name: string;
deviceType: 'bota_pin' | 'bota_pin_4g' | 'bota_note';
firmwareVersion: string;
pairingState: 'unpaired' | 'pairing' | 'paired' | 'error';
rssi: number;
}
interface ConnectedDevice {
id: string;
serialNumber: string;
deviceType: DeviceType;
firmwareVersion: string;
isProvisioned: boolean;
connectionState: ConnectionState;
mtu: number;
}
interface DeviceStatus {
batteryLevel: number;
storageUsedPercent: number;
state: DeviceState;
pendingRecordings: number;
lastSyncAt: Date | null;
flags: DeviceFlags;
}
interface DeviceRecording {
uuid: string;
startedAt: Date;
durationMs: number;
fileSizeBytes: number;
codec: AudioCodec;
}
interface UploadInfo {
uploadUrl: string; // Pre-signed S3 URL
uploadToken: string; // Upload token (up_*)
recordingId: string; // Recording ID (rec_*)
completeUrl: string; // URL to call when complete
expiresAt: Date;
}
interface SyncProgress {
stage: SyncStage;
progress: number;
bytesTransferred?: number;
bytesUploaded?: number;
totalBytes?: number;
recordingId?: string;
error?: string;
}import {
BotaError,
BluetoothError,
DeviceError,
ProvisioningError,
TransferError,
UploadError,
} from '@bota/react-native-sdk';
try {
await BotaClient.devices.connect(device);
} catch (error) {
if (error instanceof BluetoothError) {
// Handle Bluetooth errors
} else if (error instanceof DeviceError) {
// Handle device errors (connection, not found, etc.)
} else if (error instanceof ProvisioningError) {
// Handle provisioning errors
}
}The SDK does not communicate directly with the Bota API. Your mobile app should:
- Authenticate users through your own backend
- Call your backend to register devices and get device tokens
- Call your backend to create recordings and get upload URLs
- The SDK uploads directly to S3 using the pre-signed URLs
See the Bota API documentation for backend integration details.
MIT