Skip to content

Getting Started

The Alphyn React Native SDK provides device attestation, security scanning, threat detection, scan history, and action verification for iOS and Android. This page is a complete, end-to-end integration: follow it top to bottom and your app is protected. Nothing here sends you to another page for a required step; the links are only for edge cases (Expo, Objective-C, ProGuard).

A React Native project is two apps on the portal, one for Android and one for iOS, each with its own API key. You will use both.

  1. Register both apps. On portal.byterialab.com, Apps → Register App: once with your Android applicationId (Platform: Android), once with your iOS bundle identifier (Platform: iOS). Generate an API key for each. Full walkthrough: How to Register Your App.
  2. Export your registry key. Every install and build path resolves the native binaries from the Alphyn package registry with your app API key. Set it wherever your build runs (shell profile, an untracked env file, or a CI secret), and never commit it:
Terminal window
export ALPHYN_REGISTRY_KEY=<YOUR_APP_API_KEY>
Section titled “Option A: Integrate with the Alphyn CLI (recommended)”

One command does everything on this page: it adds the SDK, wires both native layers, adds the JavaScript initialization, and installs the build-registration hooks.

Terminal window
alphyn-cli integrate --android-api-key <ANDROID_APP_KEY> --ios-api-key <IOS_APP_KEY>
npm install # or: yarn / pnpm, your project's package manager
cd ios && pod install
alphyn-cli doctor

For the development loop, pin your iOS debug hash (an iOS app’s hash changes on every build and only archives register, so debug and simulator builds cannot initialize the SDK without it; the hash is in the dashboard under App Details):

Terminal window
alphyn-cli integrate --android-api-key <ANDROID_APP_KEY> --ios-api-key <IOS_APP_KEY> --ios-debug-hash <64-HEX>

doctor reports every piece of the integration and names anything missing. If you use the CLI, you are done. The rest of this page is the same integration by hand.

Option B: Integrate from the registry, by hand (no CLI)

Section titled “Option B: Integrate from the registry, by hand (no CLI)”

Five steps. Do them in order; at the end your app resolves the SDK from the registry, initializes, and registers its builds, with the same protection the CLI sets up. (The CLI additionally installs a launch-time iOS initializer in the AppDelegate; the hand steps below start the SDK from JavaScript instead, which is the same single, gated init.)

Step 1: Install the JavaScript package from the registry

Section titled “Step 1: Install the JavaScript package from the registry”

Point the @alphyn scope at the registry in a project-root .npmrc (this affects the @alphyn scope only; your other dependencies keep their own registry). The auth token reads your key from the environment, so no secret is committed:

# .npmrc (project root)
@alphyn:registry=https://packages.byterialab.com/npm/
//packages.byterialab.com/npm/:_authToken=${ALPHYN_REGISTRY_KEY}

Then install the package (find the latest <version> from GET https://packages.byterialab.com/npm/@alphyn%2Freact-native-sdk, field dist-tags.latest):

Terminal window
export ALPHYN_REGISTRY_KEY=<YOUR_APP_API_KEY>
npm install @alphyn/react-native-sdk@<version>

The npm package carries only the JavaScript and the native bridge. The iOS framework and the Android AAR still resolve from the registry, wired in the next two steps.

React Native resolves dependencies from project-level repositories, so :app cannot see the SDK module’s own repository. Add the authenticated Alphyn registry Maven to your Android root build script, android/build.gradle:

allprojects {
repositories {
maven {
url System.getenv('ALPHYN_REGISTRY_URL') ?: 'https://packages.byterialab.com/maven'
credentials {
username = 'x'
password = System.getenv('ALPHYN_REGISTRY_KEY') ?: ''
}
}
}
}

Requirements: minSdkVersion 26 or higher. You add no permissions and no ProGuard rules: the AAR declares its own permissions (Android merges them) and ships its own consumer R8 rules. Do not add QUERY_ALL_PACKAGES; Google Play rejects it for this use case and the SDK does not need it.

Set the iOS deployment target in ios/Podfile, then fetch the framework (it comes from the registry, using the key you exported):

# ios/Podfile
platform :ios, '15.0'
Terminal window
cd ios && pod install

Add these keys to ios/<YourApp>/Info.plist. All are required: without the App Transport Security exception the SDK cannot reach its backend (the attestation host uses a private CA the system does not trust, so the connection is refused before the SDK’s own pinning runs), and a shortened LSApplicationQueriesSchemes list silently narrows jailbreak detection:

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.byterialab.backgroundcheck</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>cydia</string>
<string>sileo</string>
<string>zbra</string>
<string>filza</string>
<string>undecimus</string>
<string>installer</string>
<string>taig</string>
<string>dopamine</string>
<string>trollstore</string>
<string>trollstorehelper</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>alphyn-attestation-api.byterialab.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>

AlphynSDK.register() claims the background task identifiers and must run at launch, before React Native starts; it cannot be deferred to JavaScript. Add it to your Swift ios/<YourApp>/AppDelegate.swift:

import Alphyn
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
do {
try AlphynSDK.register()
} catch {
print("AlphynSDK register failed: \(error)")
}
// ... your existing React Native setup ...
return true
}
}

If your app still uses an Objective-C AppDelegate, expose register() through a small Swift shim: see Platform Setup.

Call initialize() as early as possible in your JS entry point (index.js), before rendering:

import { AlphynSDK } from '@alphyn/react-native-sdk';
await AlphynSDK.initialize({
scanInterval: 45, // SECONDS, must be greater than 8
androidDebugHash: __DEV__ ? 'YOUR_ANDROID_DEBUG_HASH' : undefined,
iosDebugHash: __DEV__ ? 'YOUR_IOS_DEBUG_HASH' : undefined,
});

initialize() is idempotent, and the debug hashes (from the dashboard under App Details, one per platform) are only needed in development; keep them behind __DEV__ so a release bundle never carries them. Never ship a debug hash.

Alphyn is fail-closed: a build whose hash was never registered terminates at launch, with no build-time error.

  • Android. The app hash is the SHA-256 of your signing certificate, so it is stable across builds and you register it once per signing key. Run the SDK-provided post-action-android.sh <apk-path> <YOUR_ANDROID_API_KEY> after each signed build (or, if you use the CLI, its Gradle hook does this automatically). For Play App Signing, also enroll Google’s re-signing certificate once; see Play App Signing.
  • iOS. A build registers at archive time through an Xcode archive post-action. Set it up once: Register via Xcode post-action. Debug and simulator builds never register, which is why development needs the pinned iosDebugHash from Step 4.

That is the whole integration. Verify a debug run initializes without errors, then archive and confirm the build appears in the dashboard.

  • Expo: managed Expo projects.
  • Platform Setup: the exhaustive reference, including the Objective-C AppDelegate shim, the merged permission set, and what to do if your build pipeline strips consumer R8 rules.
  • Installation: installing from a downloaded tarball when your machine cannot reach the registry for the JS package.
  • CLI: React Native: exactly what alphyn-cli integrate writes into your project.