Fix all shadow deprecation warnings across entire mobile app

- Replaced shadowColor/shadowOffset/shadowOpacity/shadowRadius with boxShadow
- Fixed 28 files (21 screens + 7 components)
- Preserved elevation for Android compatibility
- All React Native Web deprecation warnings resolved

Files fixed:
- All screen components
- All reusable components
- Navigation components
- Modal components
This commit is contained in:
2026-01-14 15:05:10 +03:00
parent 9090e0fc2b
commit 8d30519efc
231 changed files with 30234 additions and 62124 deletions
+18 -38
View File
@@ -1,7 +1,10 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { I18nManager } from 'react-native';
import { saveLanguage, getCurrentLanguage, isRTL, LANGUAGE_KEY, languages } from '../i18n';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { isRTL, languages } from '../i18n';
import i18n from '../i18n';
// Language is set at build time via environment variable
const BUILD_LANGUAGE = process.env.EXPO_PUBLIC_DEFAULT_LANGUAGE || 'en';
interface Language {
code: string;
@@ -12,7 +15,6 @@ interface Language {
interface LanguageContextType {
currentLanguage: string;
changeLanguage: (languageCode: string) => Promise<void>;
isRTL: boolean;
hasSelectedLanguage: boolean;
availableLanguages: Language[];
@@ -21,52 +23,30 @@ interface LanguageContextType {
const LanguageContext = createContext<LanguageContextType | undefined>(undefined);
export const LanguageProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [currentLanguage, setCurrentLanguage] = useState(getCurrentLanguage());
const [hasSelectedLanguage, setHasSelectedLanguage] = useState(false);
const [currentIsRTL, setCurrentIsRTL] = useState(isRTL());
const checkLanguageSelection = React.useCallback(async () => {
try {
const saved = await AsyncStorage.getItem(LANGUAGE_KEY);
setHasSelectedLanguage(!!saved);
} catch (error) {
if (__DEV__) console.error('Failed to check language selection:', error);
}
}, []);
// Language is fixed at build time - no runtime switching
const [currentLanguage] = useState(BUILD_LANGUAGE);
const [currentIsRTL] = useState(isRTL(BUILD_LANGUAGE));
useEffect(() => {
// Check if user has already selected a language
// eslint-disable-next-line react-hooks/set-state-in-effect
checkLanguageSelection();
}, [checkLanguageSelection]);
// Initialize i18n with build-time language
i18n.changeLanguage(BUILD_LANGUAGE);
const changeLanguage = async (languageCode: string) => {
try {
await saveLanguage(languageCode);
setCurrentLanguage(languageCode);
setHasSelectedLanguage(true);
// Set RTL if needed
const isRTLLanguage = ['ar', 'ckb', 'fa'].includes(BUILD_LANGUAGE);
I18nManager.allowRTL(isRTLLanguage);
I18nManager.forceRTL(isRTLLanguage);
const newIsRTL = isRTL(languageCode);
setCurrentIsRTL(newIsRTL);
// Update RTL layout if needed
if (I18nManager.isRTL !== newIsRTL) {
// Note: Changing RTL requires app restart in React Native
I18nManager.forceRTL(newIsRTL);
// You may want to show a message to restart the app
}
} catch (error) {
if (__DEV__) console.error('Failed to change language:', error);
if (__DEV__) {
console.log(`[LanguageContext] Build language: ${BUILD_LANGUAGE}, RTL: ${isRTLLanguage}`);
}
};
}, []);
return (
<LanguageContext.Provider
value={{
currentLanguage,
changeLanguage,
isRTL: currentIsRTL,
hasSelectedLanguage,
hasSelectedLanguage: true, // Always true - language pre-selected at build time
availableLanguages: languages,
}}
>
+449
View File
@@ -0,0 +1,449 @@
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { Keyring } from '@pezkuwi/keyring';
import { KeyringPair } from '@pezkuwi/keyring/types';
import { ApiPromise, WsProvider } from '@pezkuwi/api';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as SecureStore from 'expo-secure-store';
import { cryptoWaitReady, mnemonicGenerate } from '@pezkuwi/util-crypto';
import { ENV } from '../config/environment';
interface Account {
address: string;
name: string;
meta?: {
name?: string;
};
}
export type NetworkType = 'pezkuwi' | 'dicle' | 'zagros' | 'bizinikiwi';
export interface NetworkConfig {
name: string;
displayName: string;
rpcEndpoint: string;
ss58Format: number;
type: 'mainnet' | 'testnet' | 'canary';
}
export const NETWORKS: Record<NetworkType, NetworkConfig> = {
pezkuwi: {
name: 'pezkuwi',
displayName: 'Pezkuwi Mainnet',
rpcEndpoint: 'wss://rpc-mainnet.pezkuwichain.io:9944',
ss58Format: 42,
type: 'mainnet',
},
dicle: {
name: 'dicle',
displayName: 'Dicle Testnet',
rpcEndpoint: 'wss://rpc-dicle.pezkuwichain.io:9944',
ss58Format: 2,
type: 'testnet',
},
zagros: {
name: 'zagros',
displayName: 'Zagros Canary',
rpcEndpoint: 'wss://rpc-zagros.pezkuwichain.io:9944',
ss58Format: 42,
type: 'canary',
},
bizinikiwi: {
name: 'bizinikiwi',
displayName: 'Bizinikiwi Testnet (Beta)',
rpcEndpoint: ENV.wsEndpoint || 'wss://rpc.pezkuwichain.io:9944',
ss58Format: 42,
type: 'testnet',
},
};
interface PezkuwiContextType {
// Chain state
api: ApiPromise | null;
isApiReady: boolean;
// Keyring state
isReady: boolean;
accounts: Account[];
selectedAccount: Account | null;
setSelectedAccount: (account: Account | null) => void;
// Network management
currentNetwork: NetworkType;
switchNetwork: (network: NetworkType) => Promise<void>;
// Wallet operations
connectWallet: () => Promise<void>;
disconnectWallet: () => void;
createWallet: (name: string, mnemonic?: string) => Promise<{ address: string; mnemonic: string }>;
importWallet: (name: string, mnemonic: string) => Promise<{ address: string }>;
getKeyPair: (address: string) => Promise<KeyringPair | null>;
signMessage: (address: string, message: string) => Promise<string | null>;
error: string | null;
}
const PezkuwiContext = createContext<PezkuwiContextType | undefined>(undefined);
const WALLET_STORAGE_KEY = '@pezkuwi_wallets';
const SELECTED_ACCOUNT_KEY = '@pezkuwi_selected_account';
const SELECTED_NETWORK_KEY = '@pezkuwi_selected_network';
interface PezkuwiProviderProps {
children: ReactNode;
}
export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) => {
const [api, setApi] = useState<ApiPromise | null>(null);
const [isApiReady, setIsApiReady] = useState(false);
const [isReady, setIsReady] = useState(false);
const [accounts, setAccounts] = useState<Account[]>([]);
const [selectedAccount, setSelectedAccount] = useState<Account | null>(null);
const [currentNetwork, setCurrentNetwork] = useState<NetworkType>('bizinikiwi');
const [error, setError] = useState<string | null>(null);
const [keyring, setKeyring] = useState<Keyring | null>(null);
// Load saved network on mount
useEffect(() => {
const loadNetwork = async () => {
try {
const savedNetwork = await AsyncStorage.getItem(SELECTED_NETWORK_KEY);
if (savedNetwork && savedNetwork in NETWORKS) {
setCurrentNetwork(savedNetwork as NetworkType);
}
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to load network:', err);
}
};
loadNetwork();
}, []);
// Initialize blockchain connection
useEffect(() => {
let retryTimeout: NodeJS.Timeout;
let isSubscribed = true;
const initApi = async () => {
try {
console.log('🔗 [Pezkuwi] Starting API initialization...');
setIsApiReady(false);
setError(null); // Clear previous errors
const networkConfig = NETWORKS[currentNetwork];
console.log(`🌐 [Pezkuwi] Connecting to ${networkConfig.displayName} at ${networkConfig.rpcEndpoint}`);
const provider = new WsProvider(networkConfig.rpcEndpoint);
console.log('📡 [Pezkuwi] WsProvider created, creating API...');
const newApi = await ApiPromise.create({ provider });
console.log('✅ [Pezkuwi] API created successfully');
if (isSubscribed) {
setApi(newApi);
setIsApiReady(true);
setError(null); // Clear any previous errors
console.log('✅ [Pezkuwi] Connected to', networkConfig.displayName);
}
} catch (err) {
console.error('❌ [Pezkuwi] Failed to connect to blockchain:', err);
console.error('❌ [Pezkuwi] Error details:', JSON.stringify(err, null, 2));
if (isSubscribed) {
setError('Failed to connect to blockchain. Check your internet connection.');
setIsApiReady(false); // ✅ FIX: Don't set ready on error
setApi(null); // ✅ FIX: Clear API on error
// Retry connection after 5 seconds
console.log('🔄 [Pezkuwi] Will retry connection in 5 seconds...');
retryTimeout = setTimeout(() => {
if (isSubscribed) {
console.log('🔄 [Pezkuwi] Retrying blockchain connection...');
initApi();
}
}, 5000);
}
}
};
initApi();
// Cleanup on network change or unmount
return () => {
isSubscribed = false;
if (retryTimeout) {
clearTimeout(retryTimeout);
}
if (api) {
api.disconnect();
}
};
}, [currentNetwork]);
// Initialize crypto and keyring
useEffect(() => {
const initCrypto = async () => {
try {
console.log('🔐 [Pezkuwi] Starting crypto initialization...');
console.log('⏳ [Pezkuwi] Waiting for crypto libraries...');
await cryptoWaitReady();
console.log('✅ [Pezkuwi] Crypto wait ready completed');
const networkConfig = NETWORKS[currentNetwork];
console.log(`🌐 [Pezkuwi] Creating keyring for ${networkConfig.displayName}`);
const kr = new Keyring({ type: 'sr25519', ss58Format: networkConfig.ss58Format });
setKeyring(kr);
setIsReady(true);
console.log('✅ [Pezkuwi] Crypto libraries initialized successfully');
} catch (err) {
console.error('❌ [Pezkuwi] Failed to initialize crypto:', err);
console.error('❌ [Pezkuwi] Error details:', JSON.stringify(err, null, 2));
setError('Failed to initialize crypto libraries');
// Still set ready to allow app to work without crypto
setIsReady(true);
}
};
initCrypto();
}, [currentNetwork]);
// Load stored accounts on mount
useEffect(() => {
const loadAccounts = async () => {
try {
const stored = await AsyncStorage.getItem(WALLET_STORAGE_KEY);
if (stored) {
const wallets = JSON.parse(stored);
setAccounts(wallets);
// Load selected account
const selectedAddr = await AsyncStorage.getItem(SELECTED_ACCOUNT_KEY);
if (selectedAddr) {
const account = wallets.find((w: Account) => w.address === selectedAddr);
if (account) {
setSelectedAccount(account);
}
}
}
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to load accounts:', err);
}
};
loadAccounts();
}, []);
// Create a new wallet
const createWallet = async (
name: string,
mnemonic?: string
): Promise<{ address: string; mnemonic: string }> => {
if (!keyring) {
throw new Error('Keyring not initialized');
}
try {
// Generate or use provided mnemonic
const mnemonicPhrase = mnemonic || mnemonicGenerate(12);
// Create account from mnemonic
const pair = keyring.addFromMnemonic(mnemonicPhrase, { name });
const newAccount: Account = {
address: pair.address,
name,
meta: { name },
};
// Store account (address only, not the seed!)
const updatedAccounts = [...accounts, newAccount];
setAccounts(updatedAccounts);
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
// SECURITY: Store encrypted seed in SecureStore (hardware-backed storage)
const seedKey = `pezkuwi_seed_${pair.address}`;
await SecureStore.setItemAsync(seedKey, mnemonicPhrase);
if (__DEV__) console.log('[Pezkuwi] Wallet created:', pair.address);
return {
address: pair.address,
mnemonic: mnemonicPhrase,
};
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to create wallet:', err);
throw new Error('Failed to create wallet');
}
};
// Import existing wallet from mnemonic
const importWallet = async (
name: string,
mnemonic: string
): Promise<{ address: string }> => {
if (!keyring) {
throw new Error('Keyring not initialized');
}
try {
// Create account from mnemonic
const pair = keyring.addFromMnemonic(mnemonic.trim(), { name });
// Check if account already exists
if (accounts.some(a => a.address === pair.address)) {
throw new Error('Wallet already exists');
}
const newAccount: Account = {
address: pair.address,
name,
meta: { name },
};
// Store account
const updatedAccounts = [...accounts, newAccount];
setAccounts(updatedAccounts);
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
// Store seed securely
const seedKey = `pezkuwi_seed_${pair.address}`;
await SecureStore.setItemAsync(seedKey, mnemonic.trim());
if (__DEV__) console.log('[Pezkuwi] Wallet imported:', pair.address);
return { address: pair.address };
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to import wallet:', err);
throw err;
}
};
// Get keypair for signing transactions
const getKeyPair = async (address: string): Promise<KeyringPair | null> => {
if (!keyring) {
throw new Error('Keyring not initialized');
}
try {
// SECURITY: Load seed from SecureStore (encrypted storage)
const seedKey = `pezkuwi_seed_${address}`;
const mnemonic = await SecureStore.getItemAsync(seedKey);
if (!mnemonic) {
if (__DEV__) console.error('[Pezkuwi] No seed found for address:', address);
return null;
}
// Recreate keypair from mnemonic
const pair = keyring.addFromMnemonic(mnemonic);
return pair;
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to get keypair:', err);
return null;
}
};
// Sign a message with the keypair
const signMessage = async (address: string, message: string): Promise<string | null> => {
try {
const pair = await getKeyPair(address);
if (!pair) {
return null;
}
// Sign the message
const signature = pair.sign(message);
// Convert to hex string
const signatureHex = Buffer.from(signature).toString('hex');
return signatureHex;
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to sign message:', err);
return null;
}
};
// Connect wallet (load existing accounts)
const connectWallet = async () => {
try {
setError(null);
if (accounts.length === 0) {
setError('No wallets found. Please create a wallet first.');
return;
}
// Auto-select first account if none selected
if (!selectedAccount && accounts.length > 0) {
setSelectedAccount(accounts[0]);
await AsyncStorage.setItem(SELECTED_ACCOUNT_KEY, accounts[0].address);
}
if (__DEV__) console.log(`[Pezkuwi] Connected with ${accounts.length} account(s)`);
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Wallet connection failed:', err);
setError('Failed to connect wallet');
}
};
// Disconnect wallet
const disconnectWallet = () => {
setSelectedAccount(null);
AsyncStorage.removeItem(SELECTED_ACCOUNT_KEY);
if (__DEV__) console.log('[Pezkuwi] Wallet disconnected');
};
// Switch network
const switchNetwork = async (network: NetworkType) => {
try {
if (network === currentNetwork) {
return;
}
if (__DEV__) console.log('[Pezkuwi] Switching to network:', NETWORKS[network].displayName);
// Save network preference
await AsyncStorage.setItem(SELECTED_NETWORK_KEY, network);
// Update state (will trigger useEffect to reconnect)
setCurrentNetwork(network);
setIsApiReady(false);
if (__DEV__) console.log('[Pezkuwi] Network switched successfully');
} catch (err) {
if (__DEV__) console.error('[Pezkuwi] Failed to switch network:', err);
setError('Failed to switch network');
}
};
// Update selected account storage when it changes
useEffect(() => {
if (selectedAccount) {
AsyncStorage.setItem(SELECTED_ACCOUNT_KEY, selectedAccount.address);
}
}, [selectedAccount]);
const value: PezkuwiContextType = {
api,
isApiReady,
isReady,
accounts,
selectedAccount,
setSelectedAccount,
currentNetwork,
switchNetwork,
connectWallet,
disconnectWallet,
createWallet,
importWallet,
getKeyPair,
signMessage,
error,
};
return <PezkuwiContext.Provider value={value}>{children}</PezkuwiContext.Provider>;
};
// Hook to use Pezkuwi context
export const usePezkuwi = (): PezkuwiContextType => {
const context = useContext(PezkuwiContext);
if (!context) {
throw new Error('usePezkuwi must be used within PezkuwiProvider');
}
return context;
};
-269
View File
@@ -1,269 +0,0 @@
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { ApiPromise, WsProvider } from '@pezkuwi/api';
import { Keyring } from '@pezkuwi/keyring';
import { KeyringPair } from '@pezkuwi/keyring/types';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as SecureStore from 'expo-secure-store';
import { cryptoWaitReady } from '@pezkuwi/util-crypto';
import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/polkadot';
interface Account {
address: string;
name: string;
meta?: {
name?: string;
};
}
interface PolkadotContextType {
api: ApiPromise | null;
isApiReady: boolean;
isConnected: boolean;
accounts: Account[];
selectedAccount: Account | null;
setSelectedAccount: (account: Account | null) => void;
connectWallet: () => Promise<void>;
disconnectWallet: () => void;
createWallet: (name: string, mnemonic?: string) => Promise<{ address: string; mnemonic: string }>;
getKeyPair: (address: string) => Promise<KeyringPair | null>;
error: string | null;
}
const PolkadotContext = createContext<PolkadotContextType | undefined>(undefined);
const WALLET_STORAGE_KEY = '@pezkuwi_wallets';
const SELECTED_ACCOUNT_KEY = '@pezkuwi_selected_account';
interface PolkadotProviderProps {
children: ReactNode;
endpoint?: string;
}
export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
children,
endpoint = DEFAULT_ENDPOINT, // Beta testnet RPC from shared config
}) => {
const [api, setApi] = useState<ApiPromise | null>(null);
const [isApiReady, setIsApiReady] = useState(false);
const [accounts, setAccounts] = useState<Account[]>([]);
const [selectedAccount, setSelectedAccount] = useState<Account | null>(null);
const [error, setError] = useState<string | null>(null);
const [keyring, setKeyring] = useState<Keyring | null>(null);
// Initialize crypto and keyring
useEffect(() => {
const initCrypto = async () => {
try {
await cryptoWaitReady();
const kr = new Keyring({ type: 'sr25519' });
setKeyring(kr);
if (__DEV__) console.warn('✅ Crypto libraries initialized');
} catch (err) {
if (__DEV__) console.error('❌ Failed to initialize crypto:', err);
setError('Failed to initialize crypto libraries');
}
};
initCrypto();
}, []);
// Initialize Polkadot API
useEffect(() => {
const initApi = async () => {
try {
if (__DEV__) console.warn('🔗 Connecting to Pezkuwi node:', endpoint);
const provider = new WsProvider(endpoint);
const apiInstance = await ApiPromise.create({ provider });
await apiInstance.isReady;
setApi(apiInstance);
setIsApiReady(true);
setError(null);
if (__DEV__) console.warn('✅ Connected to Pezkuwi node');
// Get chain info
const [chain, nodeName, nodeVersion] = await Promise.all([
apiInstance.rpc.system.chain(),
apiInstance.rpc.system.name(),
apiInstance.rpc.system.version(),
]);
if (__DEV__) {
console.warn(`📡 Chain: ${chain}`);
console.warn(`🖥️ Node: ${nodeName} v${nodeVersion}`);
}
} catch (err) {
if (__DEV__) console.error('❌ Failed to connect to node:', err);
setError(`Failed to connect to node: ${endpoint}`);
setIsApiReady(false);
}
};
initApi();
return () => {
if (api) {
api.disconnect();
}
};
}, [endpoint, api]);
// Load stored accounts on mount
useEffect(() => {
const loadAccounts = async () => {
try {
const stored = await AsyncStorage.getItem(WALLET_STORAGE_KEY);
if (stored) {
const wallets = JSON.parse(stored);
setAccounts(wallets);
// Load selected account
const selectedAddr = await AsyncStorage.getItem(SELECTED_ACCOUNT_KEY);
if (selectedAddr) {
const account = wallets.find((w: Account) => w.address === selectedAddr);
if (account) {
setSelectedAccount(account);
}
}
}
} catch (err) {
if (__DEV__) console.error('Failed to load accounts:', err);
}
};
loadAccounts();
}, []);
// Create a new wallet
const createWallet = async (
name: string,
mnemonic?: string
): Promise<{ address: string; mnemonic: string }> => {
if (!keyring) {
throw new Error('Keyring not initialized');
}
try {
// Generate or use provided mnemonic
const mnemonicPhrase = mnemonic || Keyring.prototype.generateMnemonic();
// Create account from mnemonic
const pair = keyring.addFromMnemonic(mnemonicPhrase, { name });
const newAccount: Account = {
address: pair.address,
name,
meta: { name },
};
// Store account (address only, not the seed!)
const updatedAccounts = [...accounts, newAccount];
setAccounts(updatedAccounts);
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
// SECURITY: Store encrypted seed in SecureStore (encrypted hardware-backed storage)
const seedKey = `pezkuwi_seed_${pair.address}`;
await SecureStore.setItemAsync(seedKey, mnemonicPhrase);
if (__DEV__) console.warn('✅ Wallet created:', pair.address);
return {
address: pair.address,
mnemonic: mnemonicPhrase,
};
} catch (err) {
if (__DEV__) console.error('❌ Failed to create wallet:', err);
throw new Error('Failed to create wallet');
}
};
// Get keypair for signing transactions
const getKeyPair = async (address: string): Promise<KeyringPair | null> => {
if (!keyring) {
throw new Error('Keyring not initialized');
}
try {
// SECURITY: Load seed from SecureStore (encrypted storage)
const seedKey = `pezkuwi_seed_${address}`;
const mnemonic = await SecureStore.getItemAsync(seedKey);
if (!mnemonic) {
if (__DEV__) console.error('No seed found for address:', address);
return null;
}
// Recreate keypair from mnemonic
const pair = keyring.addFromMnemonic(mnemonic);
return pair;
} catch (err) {
if (__DEV__) console.error('Failed to get keypair:', err);
return null;
}
};
// Connect wallet (load existing accounts)
const connectWallet = async () => {
try {
setError(null);
if (accounts.length === 0) {
setError('No wallets found. Please create a wallet first.');
return;
}
// Auto-select first account if none selected
if (!selectedAccount && accounts.length > 0) {
setSelectedAccount(accounts[0]);
await AsyncStorage.setItem(SELECTED_ACCOUNT_KEY, accounts[0].address);
}
if (__DEV__) console.warn(`✅ Connected with ${accounts.length} account(s)`);
} catch (err) {
if (__DEV__) console.error('❌ Wallet connection failed:', err);
setError('Failed to connect wallet');
}
};
// Disconnect wallet
const disconnectWallet = () => {
setSelectedAccount(null);
AsyncStorage.removeItem(SELECTED_ACCOUNT_KEY);
if (__DEV__) console.warn('🔌 Wallet disconnected');
};
// Update selected account storage when it changes
useEffect(() => {
if (selectedAccount) {
AsyncStorage.setItem(SELECTED_ACCOUNT_KEY, selectedAccount.address);
}
}, [selectedAccount]);
const value: PolkadotContextType = {
api,
isApiReady,
isConnected: isApiReady,
accounts,
selectedAccount,
setSelectedAccount,
connectWallet,
disconnectWallet,
createWallet,
getKeyPair,
error,
};
return <PolkadotContext.Provider value={value}>{children}</PolkadotContext.Provider>;
};
// Hook to use Polkadot context
export const usePolkadot = (): PolkadotContextType => {
const context = useContext(PolkadotContext);
if (!context) {
throw new Error('usePolkadot must be used within PolkadotProvider');
}
return context;
};
@@ -1,20 +1,20 @@
import React from 'react';
import { renderHook, act, waitFor } from '@testing-library/react-native';
import { PolkadotProvider, usePolkadot } from '../PolkadotContext';
import { PezkuwiProvider, usePezkuwi } from './PezkuwiContext';
import { ApiPromise } from '@pezkuwi/api';
// Wrapper for provider
const wrapper = ({ children }: { children: React.ReactNode }) => (
<PolkadotProvider>{children}</PolkadotProvider>
<PezkuwiProvider>{children}</PezkuwiProvider>
);
describe('PolkadotContext', () => {
describe('PezkuwiContext', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should provide polkadot context', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
it('should provide pezkuwi context', () => {
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(result.current).toBeDefined();
expect(result.current.api).toBeNull();
@@ -23,7 +23,7 @@ describe('PolkadotContext', () => {
});
it('should initialize API connection', async () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
await waitFor(() => {
expect(result.current.isApiReady).toBe(false); // Mock doesn't complete
@@ -31,14 +31,14 @@ describe('PolkadotContext', () => {
});
it('should provide connectWallet function', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(result.current.connectWallet).toBeDefined();
expect(typeof result.current.connectWallet).toBe('function');
});
it('should handle disconnectWallet', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
act(() => {
result.current.disconnectWallet();
@@ -48,14 +48,14 @@ describe('PolkadotContext', () => {
});
it('should provide setSelectedAccount function', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(result.current.setSelectedAccount).toBeDefined();
expect(typeof result.current.setSelectedAccount).toBe('function');
});
it('should set selected account', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
const testAccount = { address: '5test', name: 'Test Account' };
@@ -67,31 +67,31 @@ describe('PolkadotContext', () => {
});
it('should provide getKeyPair function', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(result.current.getKeyPair).toBeDefined();
expect(typeof result.current.getKeyPair).toBe('function');
});
it('should throw error when usePolkadot is used outside provider', () => {
it('should throw error when usePezkuwi is used outside provider', () => {
// Suppress console error for this test
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
expect(() => {
renderHook(() => usePolkadot());
}).toThrow('usePolkadot must be used within PolkadotProvider');
renderHook(() => usePezkuwi());
}).toThrow('usePezkuwi must be used within PezkuwiProvider');
spy.mockRestore();
});
it('should handle accounts array', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(Array.isArray(result.current.accounts)).toBe(true);
});
it('should handle error state', () => {
const { result } = renderHook(() => usePolkadot(), { wrapper });
const { result } = renderHook(() => usePezkuwi(), { wrapper });
expect(result.current.error).toBeDefined();
});