npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blockfact/react-native-facti-pro

v2.5.1

Published

Complete SDK for BlockFact - Content registration with wallet management

Readme

@blockfact/react-native-facti-pro

Complete SDK for BlockFact - Content registration with Starknet wallet management.

🎉 100% Free & Open Source - No API keys, no usage limits, no fees

⚠️ Camera Devices Only - This SDK only accepts images captured directly from camera with EXIF data. This prevents misuse by image editing software and ensures authenticity at source.

Features

  • Camera-Only Registration - Only accepts images from camera devices (prevents misuse)
  • Starknet Wallet Management - Generate and securely store wallets
  • Content Registration - Upload, watermark, and register on blockchain
  • Device Attestation - iOS DeviceCheck / Android Play Integrity validation
  • EXIF Validation - Requires fresh camera EXIF data
  • Automatic ZKP Generation - Zero-knowledge proofs for privacy
  • IPFS Storage - Permanent .facti file storage
  • Blockchain Verification - Verify content authenticity
  • Secure Key Storage - iOS Keychain / Android Keystore
  • Completely Free - No API keys, no limits, no charges

Installation

npm install @blockfact/react-native-facti-pro
npm install react-native-get-random-values
# or
yarn add @blockfact/react-native-facti-pro react-native-get-random-values

Required Setup

1. Add crypto polyfill to index.js:

import 'react-native-get-random-values';
// ... rest of your index.js

2. Update metro.config.js:

const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

const config = {
  resolver: {
    unstable_enablePackageExports: false,
  },
};

module.exports = mergeConfig(defaultConfig, config);

iOS Setup

cd ios && pod install

Android Setup

Add Play Integrity API to android/app/build.gradle:

dependencies {
    implementation 'com.google.android.play:integrity:1.3.0'
}

Then create native module - see detailed setup instructions at the end of this README.

Usage

1. Wrap Your App

import { BlockFactProvider } from '@blockfact/react-native-facti-pro';

function App() {
  return (
    <BlockFactProvider>
      <YourApp />
    </BlockFactProvider>
  );
}

2. Create Wallet

import { useBlockFact } from '@blockfact/react-native-facti-pro';

function WalletScreen() {
  const { wallet, createWallet, hasWallet, loading } = useBlockFact();

  const handleCreateWallet = async () => {
    try {
      const newWallet = await createWallet();
      console.log('Wallet created:', newWallet.address);
    } catch (error) {
      console.error('Failed to create wallet:', error);
    }
  };

  if (loading) return <Text>Loading...</Text>;

  if (!hasWallet) {
    return (
      <Button title="Create Wallet" onPress={handleCreateWallet} />
    );
  }

  return (
    <View>
      <Text>Wallet Address:</Text>
      <Text>{wallet.address}</Text>
    </View>
  );
}

3. Register Content

import { useBlockFact } from '@blockfact/react-native-facti-pro';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';

function CameraScreen() {
  const { registerContent, loading } = useBlockFact();

  const handleTakePhoto = async () => {
    // Take photo
    const result = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 1,
    });

    if (result.canceled) return;

    // Get location
    const location = await Location.getCurrentPositionAsync({});

    // Register on blockchain
    try {
      const registration = await registerContent({
        imageUri: result.assets[0].uri,
        latitude: location.coords.latitude,
        longitude: location.coords.longitude,
        metadata: {
          description: 'My photo',
          tags: ['nature', 'landscape']
        }
      });

      console.log('Registered!');
      console.log('Transaction:', registration.txHash);
      console.log('.facti URL:', registration.factiUrl);
      
      // Share or save registration.factiUrl
    } catch (error) {
      console.error('Registration failed:', error);
    }
  };

  return (
    <Button 
      title={loading ? "Processing..." : "Take Photo"} 
      onPress={handleTakePhoto}
      disabled={loading}
    />
  );
}

4. Verify Content

import { verifyContent } from '@blockfact/react-native-facti-pro';

async function verifyFactiFile(factiUrl) {
  try {
    const result = await verifyContent(factiUrl);
    
    if (result.valid) {
      console.log('✅ Content verified!');
      console.log('Block:', result.blockNumber);
      console.log('Timestamp:', result.timestamp);
      console.log('Metadata:', result.metadata);
    } else {
      console.log('❌ Verification failed');
    }
  } catch (error) {
    console.error('Verification error:', error);
  }
}

API Reference

BlockFactProvider

Wrap your app with this provider.

Props:

  • children (ReactNode) - Your app components

No API key required!

useBlockFact()

Hook to access BlockFact functionality.

Returns:

{
  wallet: Wallet | null,           // Current wallet
  loading: boolean,                // Loading state
  error: string | null,            // Error message
  hasWallet: boolean,              // Whether wallet exists
  createWallet: () => Promise<Wallet>,
  registerContent: (params) => Promise<RegistrationResult>,
  deleteWallet: () => Promise<void>
}

createWallet()

Generate a new Starknet wallet. Stored securely in device keychain.

Returns:

{
  address: string,      // Starknet address (0x...)
  publicKey: string     // Public key
}

registerContent(params)

Register content on blockchain.

Parameters:

{
  imageUri: string,              // Local image URI
  latitude: number,              // GPS latitude
  longitude: number,             // GPS longitude
  metadata?: object              // Optional custom metadata
}

Returns:

{
  factiUrl: string,     // IPFS URL to .facti file
  factiCid: string,     // IPFS CID
  txHash: string,       // Blockchain transaction hash
  sessionId: string     // Session identifier
}

verifyContent(factiUrl)

Verify a .facti file on blockchain.

Parameters:

  • factiUrl (string) - URL to .facti file

Returns:

{
  valid: boolean,       // Whether content is valid
  metadata: object,     // Content metadata
  blockNumber: number,  // Block number
  timestamp: string     // Registration timestamp
}

deleteWallet()

Delete wallet from device. Cannot be recovered!

Why Free?

BlockFact is building the trust layer for digital media. Our goal is to make .facti the standard file format for verified content.

Free SDK = Maximum adoption = Industry standard

We don't charge developers. Our revenue comes from:

  • Camera manufacturer licensing
  • Platform partnerships (iOS/Android)
  • Enterprise verification services

Help us make .facti the standard - use it in your app!

Complete Example

import React, { useState } from 'react';
import { View, Button, Text, Image } from 'react-native';
import { BlockFactProvider, useBlockFact } from '@blockfact/react-native-facti-pro';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';

function ContentRegistration() {
  const { wallet, createWallet, registerContent, hasWallet, loading } = useBlockFact();
  const [result, setResult] = useState(null);

  const handleRegister = async () => {
    // Create wallet if needed
    if (!hasWallet) {
      await createWallet();
    }

    // Pick image
    const image = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 1,
    });

    if (image.canceled) return;

    // Get location
    const location = await Location.getCurrentPositionAsync({});

    // Register
    const registration = await registerContent({
      imageUri: image.assets[0].uri,
      latitude: location.coords.latitude,
      longitude: location.coords.longitude
    });

    setResult(registration);
  };

  return (
    <View style={{ padding: 20 }}>
      {wallet && (
        <Text>Wallet: {wallet.address.slice(0, 10)}...</Text>
      )}
      
      <Button 
        title={loading ? "Processing..." : "Register Content"}
        onPress={handleRegister}
        disabled={loading}
      />

      {result && (
        <View style={{ marginTop: 20 }}>
          <Text>✅ Registered!</Text>
          <Text>TX: {result.txHash.slice(0, 20)}...</Text>
          <Text>IPFS: {result.factiCid}</Text>
        </View>
      )}
    </View>
  );
}

export default function App() {
  return (
    <BlockFactProvider>
      <ContentRegistration />
    </BlockFactProvider>
  );
}

Security

  • Private keys stored in iOS Keychain / Android Keystore
  • Keys never leave the device
  • All requests over HTTPS
  • Open source - audit the code

Contributing

We welcome contributions! This is an open source project.

License

Proprietary - See LICENSE file

Free to use, not free to copy.

This SDK is free to use for any purpose, but you may not redistribute, reverse engineer, or create derivative works. For commercial licensing or manufacturer integration, contact [email protected]

Support

  • Email: [email protected]
  • Docs: https://docs.blockfact.io
  • Discord: https://discord.gg/blockfact
  • GitHub: https://github.com/blockfact/react-native-facti-pro

Links


Built with ❤️ by BlockFact - Making digital media trustworthy

Features

  • Starknet Wallet Management - Generate and securely store wallets
  • Content Registration - Upload, watermark, and register on blockchain
  • Automatic ZKP Generation - Zero-knowledge proofs for privacy
  • IPFS Storage - Permanent .facti file storage
  • Blockchain Verification - Verify content authenticity
  • Secure Key Storage - iOS Keychain / Android Keystore

Installation

npm install @blockfact/react-native-facti-pro
# or
yarn add @blockfact/react-native-facti-pro

iOS Setup

cd ios && pod install

Android Setup

No additional setup required.

Usage

1. Wrap Your App

import { BlockFactProvider } from '@blockfact/react-native-facti-pro';

function App() {
  return (
    <BlockFactProvider apiKey="YOUR_API_KEY">
      <YourApp />
    </BlockFactProvider>
  );
}

2. Create Wallet

import { useBlockFact } from '@blockfact/react-native-facti-pro';

function WalletScreen() {
  const { wallet, createWallet, hasWallet, loading } = useBlockFact();

  const handleCreateWallet = async () => {
    try {
      const newWallet = await createWallet();
      console.log('Wallet created:', newWallet.address);
    } catch (error) {
      console.error('Failed to create wallet:', error);
    }
  };

  if (loading) return <Text>Loading...</Text>;

  if (!hasWallet) {
    return (
      <Button title="Create Wallet" onPress={handleCreateWallet} />
    );
  }

  return (
    <View>
      <Text>Wallet Address:</Text>
      <Text>{wallet.address}</Text>
    </View>
  );
}

3. Register Content

import { useBlockFact } from '@blockfact/react-native-facti-pro';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';

function CameraScreen() {
  const { registerContent, loading } = useBlockFact();

  const handleTakePhoto = async () => {
    // Take photo
    const result = await ImagePicker.launchCameraAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 1,
    });

    if (result.canceled) return;

    // Get location
    const location = await Location.getCurrentPositionAsync({});

    // Register on blockchain
    try {
      const registration = await registerContent({
        imageUri: result.assets[0].uri,
        latitude: location.coords.latitude,
        longitude: location.coords.longitude,
        metadata: {
          description: 'My photo',
          tags: ['nature', 'landscape']
        }
      });

      console.log('Registered!');
      console.log('Transaction:', registration.txHash);
      console.log('.facti URL:', registration.factiUrl);
      
      // Share or save registration.factiUrl
    } catch (error) {
      console.error('Registration failed:', error);
    }
  };

  return (
    <Button 
      title={loading ? "Processing..." : "Take Photo"} 
      onPress={handleTakePhoto}
      disabled={loading}
    />
  );
}

4. Verify Content

import { verifyContent } from '@blockfact/react-native-facti-pro';

async function verifyFactiFile(factiUrl) {
  try {
    const result = await verifyContent(factiUrl);
    
    if (result.valid) {
      console.log('✅ Content verified!');
      console.log('Block:', result.blockNumber);
      console.log('Timestamp:', result.timestamp);
      console.log('Metadata:', result.metadata);
    } else {
      console.log('❌ Verification failed');
    }
  } catch (error) {
    console.error('Verification error:', error);
  }
}

API Reference

BlockFactProvider

Wrap your app with this provider.

Props:

  • apiKey (string, required) - Your BlockFact Pro API key
  • children (ReactNode) - Your app components

useBlockFact()

Hook to access BlockFact functionality.

Returns:

{
  wallet: Wallet | null,           // Current wallet
  loading: boolean,                // Loading state
  error: string | null,            // Error message
  hasWallet: boolean,              // Whether wallet exists
  createWallet: () => Promise<Wallet>,
  registerContent: (params) => Promise<RegistrationResult>,
  deleteWallet: () => Promise<void>
}

createWallet()

Generate a new Starknet wallet. Stored securely in device keychain.

Returns:

{
  address: string,      // Starknet address (0x...)
  publicKey: string     // Public key
}

registerContent(params)

Register content on blockchain.

Parameters:

{
  imageUri: string,              // Local image URI
  latitude: number,              // GPS latitude
  longitude: number,             // GPS longitude
  metadata?: object              // Optional custom metadata
}

Returns:

{
  factiUrl: string,     // IPFS URL to .facti file
  factiCid: string,     // IPFS CID
  txHash: string,       // Blockchain transaction hash
  sessionId: string     // Session identifier
}

verifyContent(factiUrl)

Verify a .facti file on blockchain.

Parameters:

  • factiUrl (string) - URL to .facti file

Returns:

{
  valid: boolean,       // Whether content is valid
  metadata: object,     // Content metadata
  blockNumber: number,  // Block number
  timestamp: string     // Registration timestamp
}

deleteWallet()

Delete wallet from device. Cannot be recovered!

Complete Example

import React, { useState } from 'react';
import { View, Button, Text, Image } from 'react-native';
import { BlockFactProvider, useBlockFact } from '@blockfact/react-native-facti-pro';
import * as ImagePicker from 'expo-image-picker';
import * as Location from 'expo-location';

function ContentRegistration() {
  const { wallet, createWallet, registerContent, hasWallet, loading } = useBlockFact();
  const [result, setResult] = useState(null);

  const handleRegister = async () => {
    // Create wallet if needed
    if (!hasWallet) {
      await createWallet();
    }

    // Pick image
    const image = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 1,
    });

    if (image.canceled) return;

    // Get location
    const location = await Location.getCurrentPositionAsync({});

    // Register
    const registration = await registerContent({
      imageUri: image.assets[0].uri,
      latitude: location.coords.latitude,
      longitude: location.coords.longitude
    });

    setResult(registration);
  };

  return (
    <View style={{ padding: 20 }}>
      {wallet && (
        <Text>Wallet: {wallet.address.slice(0, 10)}...</Text>
      )}
      
      <Button 
        title={loading ? "Processing..." : "Register Content"}
        onPress={handleRegister}
        disabled={loading}
      />

      {result && (
        <View style={{ marginTop: 20 }}>
          <Text>✅ Registered!</Text>
          <Text>TX: {result.txHash.slice(0, 20)}...</Text>
          <Text>IPFS: {result.factiCid}</Text>
        </View>
      )}
    </View>
  );
}

export default function App() {
  return (
    <BlockFactProvider apiKey="YOUR_API_KEY">
      <ContentRegistration />
    </BlockFactProvider>
  );
}

Security

  • Private keys stored in iOS Keychain / Android Keystore
  • Keys never leave the device
  • API key validated server-side
  • All requests over HTTPS

License

Commercial license required. Contact [email protected]

Support

  • Email: [email protected]
  • Docs: https://docs.blockfact.io
  • GitHub: https://github.com/blockfact/react-native-facti-pro

Links