React Native SDK
Complete SDK for content registration with Starknet wallet management
Installation
npm install @blockfact/react-native-facti-proiOS Setup
cd ios && pod installAndroid Setup
Add Play Integrity API to android/app/build.gradle:
dependencies {
implementation 'com.google.android.play:integrity:1.3.0'
}Then create the Play Integrity native module. See the full Android setup guide.
API Reference
BlockFactProvider
Wrap your app with this provider:
import { BlockFactProvider } from '@blockfact/react-native-facti-pro';
<BlockFactProvider>
<App />
</BlockFactProvider>useBlockFact()
Hook to access BlockFact functionality:
const {
wallet, // Current wallet object
loading, // Loading state
error, // Error message
createWallet, // Function to create wallet
registerContent, // Function to register content
deleteWallet, // Function to delete wallet
hasWallet // Boolean: wallet exists
} = useBlockFact();createWallet()
Creates a new Starknet wallet with biometric protection:
const wallet = await createWallet();
// Returns: { address, publicKey, privateKey }🔐 Security
Private keys are stored in iOS Keychain / Android Keystore with biometric authentication required.
registerContent()
Registers content on blockchain:
const result = await registerContent({
imageUri: string, // Required: Image URI
latitude: number, // Required: GPS latitude
longitude: number, // Required: GPS longitude
exifData: object, // Required: Camera EXIF data
captureTimestamp: string, // Required: ISO timestamp
metadata: object // Optional: Additional metadata
});
// Returns:
{
factiUrl: string, // IPFS URL to .facti file
factiCid: string, // IPFS CID
txHash: string, // Blockchain transaction hash
sessionId: string // Session ID for tracking
}⚠️ Camera-Only
Images must be captured within 30 seconds and include valid EXIF data. Screenshots and edited images will be rejected.
Complete Example
import React from 'react';
import { View, Button, Text } from 'react-native';
import { useBlockFact } from '@blockfact/react-native-facti-pro';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';
function CameraScreen() {
const { wallet, createWallet, registerContent, hasWallet } = useBlockFact();
// 1. Create wallet if needed
if (!hasWallet) {
return <Button title="Create Wallet" onPress={createWallet} />;
}
// 2. Capture and register
const handleCapture = async () => {
// Get location
const location = await Location.getCurrentPositionAsync();
// Take photo
const photo = await ImagePicker.launchCameraAsync({
exif: true,
quality: 1
});
// Register on blockchain
const result = await registerContent({
imageUri: photo.uri,
latitude: location.coords.latitude,
longitude: location.coords.longitude,
exifData: photo.exif,
captureTimestamp: new Date().toISOString()
});
console.log('Registered:', result.factiUrl);
};
return (
<View>
<Text>Wallet: {wallet.address}</Text>
<Button title="Take Photo" onPress={handleCapture} />
</View>
);
}Security Features
- ✅ Proper Starknet key generation using starknet.js
- ✅ Biometric authentication (Face ID, Touch ID, Fingerprint)
- ✅ 30-second image freshness window
- ✅ Device attestation (iOS DeviceCheck, Android Play Integrity)
- ✅ EXIF validation required
- ✅ No insecure fallbacks
Troubleshooting
Error: DeviceCheck not available
You need to implement the iOS DeviceCheck native module. See the iOS setup guide.
Error: Image too old
Images must be registered within 30 seconds of capture. Call registerContent() immediately after taking the photo.
Error: EXIF data required
Make sure to enable EXIF data when capturing: { exif: true }