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

v1.0.5

Published

React Native component for displaying and verifying .facti files

Downloads

610

Readme

@blockfact/react-native-facti

React Native component for displaying and verifying .facti files.

Installation

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

Usage

Basic Display

import FactiImage from '@blockfact/react-native-facti';

function Gallery() {
  return (
    <FactiImage 
      factiUrl="https://gateway.pinata.cloud/ipfs/QmXXX"
      style={{ marginVertical: 20 }}
    />
  );
}

With Metadata Overlay

<FactiImage 
  factiUrl="https://gateway.pinata.cloud/ipfs/QmXXX"
  showMetadata={true}
  onMetadataLoad={(metadata) => {
    console.log('Loaded:', metadata.tx_hash);
  }}
/>

Parse .facti File Manually

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

async function loadFacti() {
  const { imageUri, metadata } = await parseFacTi(
    'https://gateway.pinata.cloud/ipfs/QmXXX'
  );
  
  console.log('Transaction:', metadata.tx_hash);
  console.log('Owner:', metadata.wallet);
  console.log('GPS:', metadata.latitude, metadata.longitude);
  
  // Use imageUri in Image component
  <Image source={{ uri: imageUri }} />
}

Custom Metadata Display

import { parseFacTi } from '@blockfact/react-native-facti';
import { View, Image, Text } from 'react-native';

function CustomFactiView({ factiUrl }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    parseFacTi(factiUrl).then(setData);
  }, [factiUrl]);

  if (!data) return <Text>Loading...</Text>;

  return (
    <View>
      <Image source={{ uri: data.imageUri }} style={{ width: 300, height: 300 }} />
      <Text>Owner: {data.metadata.wallet}</Text>
      <Text>Location: {data.metadata.latitude}, {data.metadata.longitude}</Text>
    </View>
  );
}

Component Props

FactiImage

| Prop | Type | Default | Description | |------|------|---------|-------------| | factiUrl | string | required | URL to .facti file (IPFS, HTTP, etc.) | | style | object | {} | Style for container View | | showMetadata | boolean | false | Show verification badge overlay | | onMetadataLoad | function | null | Callback when metadata is loaded |

API

parseFacTi(factiUrl)

Parses a .facti file and returns image + metadata.

Parameters:

  • factiUrl (string) - URL to .facti file

Returns:

{
  imageUri: "data:image/png;base64,...",  // Base64 data URI
  metadata: {
    tx_hash: "0x...",
    wallet: "0x...",
    timestamp: "2026-02-26T13:20:00Z",
    latitude: 40.7128,
    longitude: -74.0060,
    session_id: "preprocess-...",
    // ... other fields
  }
}

Features

  • ✅ Parse .facti files from any URL
  • ✅ Display watermarked image
  • ✅ Show metadata (transaction, owner, GPS, timestamp)
  • ✅ Clickable blockchain verification link
  • ✅ Clickable GPS coordinates (opens Google Maps)
  • ✅ Verification badge overlay
  • ✅ Error handling
  • ✅ Loading states

File Format Support

Supports .facti v1.0+ with structure:

  • Magic number (4 bytes): 0xFA 0x49 0x01 0x00
  • Metadata hash (32 bytes)
  • Metadata length (4 bytes, big-endian)
  • Metadata JSON (N bytes)
  • Image data (M bytes)

Examples

Gallery View

import { FlatList } from 'react-native';
import FactiImage from './FactiImage';

const factiFiles = [
  'https://gateway.pinata.cloud/ipfs/QmAAA',
  'https://gateway.pinata.cloud/ipfs/QmBBB',
  'https://gateway.pinata.cloud/ipfs/QmCCC',
];

function FactiGallery() {
  return (
    <FlatList
      data={factiFiles}
      renderItem={({ item }) => (
        <FactiImage 
          factiUrl={item}
          showMetadata={true}
          style={{ marginBottom: 20 }}
        />
      )}
      keyExtractor={(item) => item}
    />
  );
}

Upload from Device

import * as DocumentPicker from 'expo-document-picker';
import { parseFacTi } from './FactiImage';

async function pickFactiFile() {
  const result = await DocumentPicker.getDocumentAsync({
    type: '*/*',
  });
  
  if (result.type === 'success') {
    // Read file as base64
    const base64 = await FileSystem.readAsStringAsync(result.uri, {
      encoding: FileSystem.EncodingType.Base64,
    });
    
    // Convert to data URL
    const dataUrl = `data:application/octet-stream;base64,${base64}`;
    
    // Parse
    const { imageUri, metadata } = await parseFacTi(dataUrl);
    console.log('Loaded local .facti file:', metadata);
  }
}

Verification Screen

function VerificationScreen({ factiUrl }) {
  const [metadata, setMetadata] = useState(null);

  return (
    <ScrollView>
      <FactiImage 
        factiUrl={factiUrl}
        onMetadataLoad={setMetadata}
      />
      
      {metadata && (
        <View style={{ padding: 20 }}>
          <Text style={{ fontSize: 18, fontWeight: 'bold' }}>
            ✅ Blockchain Verified
          </Text>
          <Text>Transaction: {metadata.tx_hash}</Text>
          <Text>Timestamp: {new Date(metadata.timestamp).toLocaleString()}</Text>
        </View>
      )}
    </ScrollView>
  );
}

Notes

  • Works with Expo and bare React Native
  • No native modules required
  • Uses standard Web APIs (fetch, TextDecoder, Uint8Array)
  • Images converted to base64 data URIs for React Native compatibility
  • Supports both PNG and JPEG images

Troubleshooting

"Invalid .facti file format"

  • File doesn't start with magic number 0xFA 0x49 0x01 0x00
  • Verify URL is correct and file is accessible

Image not displaying

  • Check that image data is valid PNG/JPEG
  • Verify base64 conversion is working
  • Try logging imageUri to debug

Metadata parsing error

  • JSON in .facti file may be corrupted
  • Check metadata length field is correct