Skip to main content
ParityEdge
React Native & Expo
Mobile Applications

React Native & Expo Mobile Integration

Localize in-app subscription pricing, paywalls, and coin packs across iOS and Android with automatic country detection and offline caching.

Custom useParity Hook with AsyncStorage Caching

Create a lightweight hook with AsyncStorage persistence to query the ParityEdge Anycast Edge API once per app session:

// hooks/useParity.ts
import { useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';

export interface ParityData {
  eligible: boolean;
  discountPercentage: number;
  countryName: string;
  countryCode: string;
  currency: string;
  couponCode: string;
  tier: number;
}

const CACHE_KEY = '@parityedge_cache_v1';
const EDGE_URL = 'https://api.parityedge.app/v1/lookup?pid=prj_live_YOUR_KEY';

export function useParity() {
  const [parity, setParity] = useState<ParityData | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function loadParity() {
      try {
        const cached = await AsyncStorage.getItem(CACHE_KEY);
        if (cached) {
          setParity(JSON.parse(cached));
          setLoading(false);
          return;
        }

        const res = await fetch(EDGE_URL, {
          headers: { Accept: 'application/json' },
        });

        if (res.ok) {
          const data = await res.json();
          setParity(data);
          await AsyncStorage.setItem(CACHE_KEY, JSON.stringify(data));
        }
      } catch (err) {
        console.warn('[ParityEdge] Mobile resolution error:', err);
      } finally {
        setLoading(false);
      }
    }

    loadParity();
  }, []);

  const getDiscountedPrice = (basePrice: number) => {
    if (parity?.eligible && parity.discountPercentage > 0) {
      const multiplier = (100 - parity.discountPercentage) / 100;
      return Number((basePrice * multiplier).toFixed(2));
    }
    return basePrice;
  };

  return { parity, loading, getDiscountedPrice };
}

Mobile Paywall & In-App Purchase UI

// screens/PaywallScreen.tsx
import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity, Linking } from 'react-native';
import { useParity } from '../hooks/useParity';

export function PaywallScreen() {
  const { parity, loading, getDiscountedPrice } = useParity();
  const basePrice = 49.00;
  const finalPrice = getDiscountedPrice(basePrice);

  const handleCheckout = () => {
    const coupon = parity?.couponCode;
    const url = coupon
      ? `https://buy.stripe.com/sample_pro?prefilled_promo_code=${coupon}`
      : 'https://buy.stripe.com/sample_pro';
    Linking.openURL(url);
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Unlock Premium Access</Text>
      
      {parity?.eligible && parity.discountPercentage > 0 && (
        <View style={styles.banner}>
          <Text style={styles.bannerText}>
            🎉 Special {parity.discountPercentage}% purchasing power discount for {parity.countryName}!
          </Text>
        </View>
      )}

      <Text style={styles.price}>${finalPrice.toFixed(2)} / year</Text>
      <TouchableOpacity style={styles.button} onPress={handleCheckout}>
        <Text style={styles.buttonText}>Subscribe Now</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 24, justifyContent: 'center', backgroundColor: '#0B0F19' },
  title: { fontSize: 24, fontWeight: 'bold', color: '#FFFFFF', textAlign: 'center' },
  banner: { backgroundColor: '#064E3B', padding: 12, borderRadius: 12, marginVertical: 16 },
  bannerText: { color: '#34D399', fontSize: 13, textAlign: 'center', fontWeight: '600' },
  price: { fontSize: 32, fontWeight: '800', color: '#FFFFFF', textAlign: 'center', marginVertical: 12 },
  button: { backgroundColor: '#00C57A', padding: 16, borderRadius: 12, alignItems: 'center' },
  buttonText: { color: '#000000', fontWeight: 'bold', fontSize: 16 },
});

Mobile Best Practices

AsyncStorage Session Cache

Cache the response in AsyncStorage or MMKV to ensure instant paywall rendering with zero network latency on subsequent app launches.

Anti-VPN Security Shield

The ParityEdge edge engine detects and filters datacenter proxies in sub-10ms, preventing proxy abuse on mobile checkout sessions.