Files
pwap/mobile/src/screens/SwapScreen.tsx.bak
T
pezkuwichain 4a3694c831 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
2026-01-14 15:05:10 +03:00

871 lines
25 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect, useMemo } from 'react';
import {
View,
Text,
StyleSheet,
SafeAreaView,
ScrollView,
TouchableOpacity,
TextInput,
Modal,
ActivityIndicator,
Alert,
Platform,
Image,
} from 'react-native';
import { KurdistanColors } from '../theme/colors';
import { usePezkuwi } from '../contexts/PezkuwiContext';
// Token Images
const hezLogo = require('../../../shared/images/hez_logo.png');
const pezLogo = require('../../../shared/images/pez_logo.jpg');
const usdtLogo = require('../../../shared/images/USDT(hez)logo.png');
interface TokenInfo {
symbol: string;
name: string;
assetId: number;
decimals: number;
logo: any;
}
const TOKENS: TokenInfo[] = [
{ symbol: 'HEZ', name: 'Hemuwelet', assetId: 0, decimals: 12, logo: hezLogo },
{ symbol: 'PEZ', name: 'Pezkunel', assetId: 1, decimals: 12, logo: pezLogo },
{ symbol: 'USDT', name: 'Tether USD', assetId: 1000, decimals: 6, logo: usdtLogo },
];
type TransactionStatus = 'idle' | 'signing' | 'submitting' | 'success' | 'error';
const SwapScreen: React.FC = () => {
const { api, isApiReady, selectedAccount, getKeyPair } = usePezkuwi();
const [fromToken, setFromToken] = useState<TokenInfo>(TOKENS[0]);
const [toToken, setToToken] = useState<TokenInfo>(TOKENS[1]);
const [fromAmount, setFromAmount] = useState('');
const [toAmount, setToAmount] = useState('');
const [slippage, setSlippage] = useState(0.5); // 0.5% default
const [fromBalance, setFromBalance] = useState('0');
const [toBalance, setToBalance] = useState('0');
const [txStatus, setTxStatus] = useState<TransactionStatus>('idle');
const [errorMessage, setErrorMessage] = useState('');
const [showTokenSelector, setShowTokenSelector] = useState<'from' | 'to' | null>(null);
const [showSettings, setShowSettings] = useState(false);
const [showConfirm, setShowConfirm] = useState(false);
// Fetch balances
useEffect(() => {
const fetchBalances = async () => {
if (!api || !isApiReady || !selectedAccount) return;
// Fetch From Token Balance
try {
if (fromToken.symbol === 'HEZ') {
const accountInfo = await api.query.system.account(selectedAccount.address);
setFromBalance(accountInfo.data.free.toString());
} else {
const balanceData = await api.query.assets.account(fromToken.assetId, selectedAccount.address);
setFromBalance(balanceData.isSome ? balanceData.unwrap().balance.toString() : '0');
}
} catch (error) {
console.error('Failed to fetch from balance:', error);
setFromBalance('0');
}
// Fetch To Token Balance
try {
if (toToken.symbol === 'HEZ') {
const accountInfo = await api.query.system.account(selectedAccount.address);
setToBalance(accountInfo.data.free.toString());
} else {
const balanceData = await api.query.assets.account(toToken.assetId, selectedAccount.address);
setToBalance(balanceData.isSome ? balanceData.unwrap().balance.toString() : '0');
}
} catch (error) {
console.error('Failed to fetch to balance:', error);
setToBalance('0');
}
};
fetchBalances();
}, [api, isApiReady, selectedAccount, fromToken, toToken]);
// Calculate output amount (simple 1:1 for now - should use pool reserves)
useEffect(() => {
if (!fromAmount || parseFloat(fromAmount) <= 0) {
setToAmount('');
return;
}
// TODO: Implement proper AMM calculation using pool reserves
// For now, simple 1:1 conversion (placeholder)
const calculatedAmount = (parseFloat(fromAmount) * 0.97).toFixed(6); // 3% fee simulation
setToAmount(calculatedAmount);
}, [fromAmount, fromToken, toToken]);
// Calculate formatted balances
const fromBalanceFormatted = useMemo(() => {
return (Number(fromBalance) / Math.pow(10, fromToken.decimals)).toFixed(4);
}, [fromBalance, fromToken]);
const toBalanceFormatted = useMemo(() => {
return (Number(toBalance) / Math.pow(10, toToken.decimals)).toFixed(4);
}, [toBalance, toToken]);
const hasInsufficientBalance = useMemo(() => {
const amountNum = parseFloat(fromAmount || '0');
const balanceNum = parseFloat(fromBalanceFormatted);
return amountNum > 0 && amountNum > balanceNum;
}, [fromAmount, fromBalanceFormatted]);
const handleSwapDirection = () => {
const tempToken = fromToken;
const tempBalance = fromBalance;
const tempAmount = fromAmount;
setFromToken(toToken);
setToToken(tempToken);
setFromBalance(toBalance);
setToBalance(tempBalance);
setFromAmount(toAmount);
setToAmount(tempAmount);
};
const handleMaxClick = () => {
setFromAmount(fromBalanceFormatted);
};
const handleTokenSelect = (token: TokenInfo) => {
if (showTokenSelector === 'from') {
if (token.symbol === toToken.symbol) {
Alert.alert('Error', 'Cannot select the same token for both sides');
return;
}
setFromToken(token);
} else if (showTokenSelector === 'to') {
if (token.symbol === fromToken.symbol) {
Alert.alert('Error', 'Cannot select the same token for both sides');
return;
}
setToToken(token);
}
setShowTokenSelector(null);
};
const handleConfirmSwap = async () => {
if (!api || !selectedAccount) {
Alert.alert('Error', 'Please connect your wallet');
return;
}
setTxStatus('signing');
setShowConfirm(false);
setErrorMessage('');
try {
const keypair = await getKeyPair(selectedAccount.address);
if (!keypair) throw new Error('Failed to load keypair');
const amountIn = BigInt(Math.floor(parseFloat(fromAmount) * Math.pow(10, fromToken.decimals)));
const minAmountOut = BigInt(
Math.floor(parseFloat(toAmount) * (1 - slippage / 100) * Math.pow(10, toToken.decimals))
);
let tx;
if (fromToken.symbol === 'HEZ' && toToken.symbol === 'PEZ') {
// HEZ → PEZ: wrap(HEZ→wHEZ) then swap(wHEZ→PEZ)
const wrapTx = api.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
[0, 1], // wHEZ → PEZ
amountIn.toString(),
minAmountOut.toString(),
selectedAccount.address,
true
);
tx = api.tx.utility.batchAll([wrapTx, swapTx]);
} else if (fromToken.symbol === 'PEZ' && toToken.symbol === 'HEZ') {
// PEZ → HEZ: swap(PEZ→wHEZ) then unwrap(wHEZ→HEZ)
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
[1, 0], // PEZ → wHEZ
amountIn.toString(),
minAmountOut.toString(),
selectedAccount.address,
true
);
const unwrapTx = api.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = api.tx.utility.batchAll([swapTx, unwrapTx]);
} else if (fromToken.symbol === 'HEZ') {
// HEZ → Any Asset: wrap(HEZ→wHEZ) then swap(wHEZ→Asset)
const wrapTx = api.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
[0, toToken.assetId],
amountIn.toString(),
minAmountOut.toString(),
selectedAccount.address,
true
);
tx = api.tx.utility.batchAll([wrapTx, swapTx]);
} else if (toToken.symbol === 'HEZ') {
// Any Asset → HEZ: swap(Asset→wHEZ) then unwrap(wHEZ→HEZ)
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
[fromToken.assetId, 0],
amountIn.toString(),
minAmountOut.toString(),
selectedAccount.address,
true
);
const unwrapTx = api.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = api.tx.utility.batchAll([swapTx, unwrapTx]);
} else {
// Direct swap between assets (PEZ ↔ USDT, etc.)
tx = api.tx.assetConversion.swapExactTokensForTokens(
[fromToken.assetId, toToken.assetId],
amountIn.toString(),
minAmountOut.toString(),
selectedAccount.address,
true
);
}
setTxStatus('submitting');
await tx.signAndSend(keypair, ({ status, dispatchError }) => {
if (status.isInBlock) {
if (dispatchError) {
const errorMsg = dispatchError.toString();
setErrorMessage(errorMsg);
setTxStatus('error');
Alert.alert('Transaction Failed', errorMsg);
} else {
setTxStatus('success');
Alert.alert('Success!', `Swapped ${fromAmount} ${fromToken.symbol} for ~${toAmount} ${toToken.symbol}`);
setTimeout(() => {
setFromAmount('');
setToAmount('');
setTxStatus('idle');
}, 2000);
}
}
});
} catch (error: any) {
console.error('Swap failed:', error);
setErrorMessage(error.message || 'Transaction failed');
setTxStatus('error');
Alert.alert('Error', error.message || 'Swap transaction failed');
}
};
if (!selectedAccount) {
return (
<SafeAreaView style={styles.container}>
<View style={styles.centerContent}>
<Text style={styles.emptyIcon}>💱</Text>
<Text style={styles.emptyText}>Connect your wallet to swap tokens</Text>
</View>
</SafeAreaView>
);
}
return (
<SafeAreaView style={styles.container}>
{/* Transaction Loading Overlay */}
{(txStatus === 'signing' || txStatus === 'submitting') && (
<View style={styles.loadingOverlay}>
<View style={styles.loadingCard}>
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
<Text style={styles.loadingText}>
{txStatus === 'signing' ? 'Waiting for signature...' : 'Processing swap...'}
</Text>
</View>
</View>
)}
<ScrollView style={styles.scrollContent} contentContainerStyle={styles.scrollContentContainer}>
{/* Header */}
<View style={styles.header}>
<Text style={styles.headerTitle}>Swap Tokens</Text>
<TouchableOpacity onPress={() => setShowSettings(true)} style={styles.settingsButton}>
<Text style={styles.settingsIcon}>⚙️</Text>
</TouchableOpacity>
</View>
{/* From Token Card */}
<View style={styles.tokenCard}>
<View style={styles.tokenCardHeader}>
<Text style={styles.tokenCardLabel}>From</Text>
<Text style={styles.tokenCardBalance}>
Balance: {fromBalanceFormatted} {fromToken.symbol}
</Text>
</View>
<View style={styles.tokenInputRow}>
<TextInput
style={styles.amountInput}
placeholder="0.0"
placeholderTextColor="#999"
keyboardType="decimal-pad"
value={fromAmount}
onChangeText={setFromAmount}
/>
<TouchableOpacity
style={styles.tokenSelector}
onPress={() => setShowTokenSelector('from')}
>
<Image source={fromToken.logo} style={styles.tokenLogo} resizeMode="contain" />
<Text style={styles.tokenSymbol}>{fromToken.symbol}</Text>
<Text style={styles.tokenSelectorArrow}>▼</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.maxButton} onPress={handleMaxClick}>
<Text style={styles.maxButtonText}>MAX</Text>
</TouchableOpacity>
</View>
{/* Swap Direction Button */}
<View style={styles.swapDirectionContainer}>
<TouchableOpacity style={styles.swapDirectionButton} onPress={handleSwapDirection}>
<Text style={styles.swapDirectionIcon}>⇅</Text>
</TouchableOpacity>
</View>
{/* To Token Card */}
<View style={styles.tokenCard}>
<View style={styles.tokenCardHeader}>
<Text style={styles.tokenCardLabel}>To</Text>
<Text style={styles.tokenCardBalance}>
Balance: {toBalanceFormatted} {toToken.symbol}
</Text>
</View>
<View style={styles.tokenInputRow}>
<TextInput
style={styles.amountInput}
placeholder="0.0"
placeholderTextColor="#999"
value={toAmount}
editable={false}
/>
<TouchableOpacity
style={styles.tokenSelector}
onPress={() => setShowTokenSelector('to')}
>
<Image source={toToken.logo} style={styles.tokenLogo} resizeMode="contain" />
<Text style={styles.tokenSymbol}>{toToken.symbol}</Text>
<Text style={styles.tokenSelectorArrow}>▼</Text>
</TouchableOpacity>
</View>
</View>
{/* Swap Details */}
<View style={styles.detailsCard}>
<View style={styles.detailRow}>
<Text style={styles.detailLabel}>️ Exchange Rate</Text>
<Text style={styles.detailValue}>1 {fromToken.symbol} ≈ 1 {toToken.symbol}</Text>
</View>
<View style={styles.detailRow}>
<Text style={styles.detailLabel}>Slippage Tolerance</Text>
<Text style={styles.detailValueHighlight}>{slippage}%</Text>
</View>
</View>
{/* Warnings */}
{hasInsufficientBalance && (
<View style={[styles.warningCard, styles.errorCard]}>
<Text style={styles.warningIcon}>⚠️</Text>
<Text style={styles.warningText}>Insufficient {fromToken.symbol} balance</Text>
</View>
)}
{/* Swap Button */}
<TouchableOpacity
style={[
styles.swapButton,
(!fromAmount || hasInsufficientBalance || txStatus !== 'idle') && styles.swapButtonDisabled
]}
onPress={() => setShowConfirm(true)}
disabled={!fromAmount || hasInsufficientBalance || txStatus !== 'idle'}
>
<Text style={styles.swapButtonText}>
{hasInsufficientBalance
? `Insufficient ${fromToken.symbol} Balance`
: 'Swap Tokens'}
</Text>
</TouchableOpacity>
</ScrollView>
{/* Token Selector Modal */}
<Modal visible={showTokenSelector !== null} transparent animationType="slide" onRequestClose={() => setShowTokenSelector(null)}>
<View style={styles.modalOverlay}>
<View style={styles.modalCard}>
<Text style={styles.modalHeader}>Select Token</Text>
{TOKENS.map((token) => (
<TouchableOpacity
key={token.symbol}
style={styles.tokenOption}
onPress={() => handleTokenSelect(token)}
>
<Image source={token.logo} style={styles.tokenOptionLogo} resizeMode="contain" />
<View style={styles.tokenOptionInfo}>
<Text style={styles.tokenOptionSymbol}>{token.symbol}</Text>
<Text style={styles.tokenOptionName}>{token.name}</Text>
</View>
</TouchableOpacity>
))}
<TouchableOpacity style={styles.modalCloseButton} onPress={() => setShowTokenSelector(null)}>
<Text style={styles.modalCloseButtonText}>Cancel</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
{/* Settings Modal */}
<Modal visible={showSettings} transparent animationType="slide" onRequestClose={() => setShowSettings(false)}>
<View style={styles.modalOverlay}>
<View style={styles.modalCard}>
<Text style={styles.modalHeader}>Swap Settings</Text>
<Text style={styles.settingsLabel}>Slippage Tolerance</Text>
<View style={styles.slippageButtons}>
{[0.1, 0.5, 1.0, 2.0].map((val) => (
<TouchableOpacity
key={val}
style={[styles.slippageButton, slippage === val && styles.slippageButtonActive]}
onPress={() => setSlippage(val)}
>
<Text style={[styles.slippageButtonText, slippage === val && styles.slippageButtonTextActive]}>
{val}%
</Text>
</TouchableOpacity>
))}
</View>
<TouchableOpacity style={styles.modalCloseButton} onPress={() => setShowSettings(false)}>
<Text style={styles.modalCloseButtonText}>Close</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
{/* Confirm Modal */}
<Modal visible={showConfirm} transparent animationType="slide" onRequestClose={() => setShowConfirm(false)}>
<View style={styles.modalOverlay}>
<View style={styles.modalCard}>
<Text style={styles.modalHeader}>Confirm Swap</Text>
<View style={styles.confirmDetails}>
<View style={styles.confirmRow}>
<Text style={styles.confirmLabel}>You Pay</Text>
<Text style={styles.confirmValue}>{fromAmount} {fromToken.symbol}</Text>
</View>
<View style={styles.confirmRow}>
<Text style={styles.confirmLabel}>You Receive</Text>
<Text style={styles.confirmValue}>{toAmount} {toToken.symbol}</Text>
</View>
<View style={[styles.confirmRow, styles.confirmRowBorder]}>
<Text style={styles.confirmLabelSmall}>Slippage</Text>
<Text style={styles.confirmValueSmall}>{slippage}%</Text>
</View>
</View>
<View style={styles.confirmButtons}>
<TouchableOpacity style={styles.confirmCancelButton} onPress={() => setShowConfirm(false)}>
<Text style={styles.confirmCancelButtonText}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.confirmSwapButton} onPress={handleConfirmSwap}>
<Text style={styles.confirmSwapButtonText}>Confirm Swap</Text>
</TouchableOpacity>
</View>
</View>
</View>
</Modal>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F8F9FA',
},
centerContent: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 40,
},
emptyIcon: {
fontSize: 64,
marginBottom: 16,
},
emptyText: {
fontSize: 16,
color: '#666',
textAlign: 'center',
},
scrollContent: {
flex: 1,
},
scrollContentContainer: {
padding: 16,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 20,
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
},
settingsButton: {
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#F5F5F5',
justifyContent: 'center',
alignItems: 'center',
},
settingsIcon: {
fontSize: 20,
},
tokenCard: {
backgroundColor: '#FFFFFF',
borderRadius: 16,
padding: 16,
marginBottom: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.05,
shadowRadius: 4,
elevation: 2,
},
tokenCardHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 12,
},
tokenCardLabel: {
fontSize: 14,
color: '#666',
},
tokenCardBalance: {
fontSize: 12,
color: '#999',
},
tokenInputRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
amountInput: {
flex: 1,
fontSize: 28,
fontWeight: 'bold',
color: '#333',
padding: 0,
},
tokenSelector: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#F5F5F5',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 12,
gap: 8,
},
tokenLogo: {
width: 24,
height: 24,
},
tokenSymbol: {
fontSize: 16,
fontWeight: '600',
color: '#333',
},
tokenSelectorArrow: {
fontSize: 10,
color: '#666',
},
maxButton: {
alignSelf: 'flex-start',
marginTop: 8,
paddingHorizontal: 12,
paddingVertical: 6,
backgroundColor: 'rgba(0, 143, 67, 0.1)',
borderRadius: 8,
borderWidth: 1,
borderColor: 'rgba(0, 143, 67, 0.3)',
},
maxButtonText: {
fontSize: 12,
fontWeight: '600',
color: KurdistanColors.kesk,
},
swapDirectionContainer: {
alignItems: 'center',
marginVertical: -12,
zIndex: 10,
},
swapDirectionButton: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#FFFFFF',
borderWidth: 2,
borderColor: '#E5E5E5',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
swapDirectionIcon: {
fontSize: 24,
color: '#333',
},
detailsCard: {
backgroundColor: '#FFFFFF',
borderRadius: 16,
padding: 16,
marginTop: 16,
marginBottom: 16,
},
detailRow: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
},
detailLabel: {
fontSize: 14,
color: '#666',
},
detailValue: {
fontSize: 14,
color: '#333',
fontWeight: '500',
},
detailValueHighlight: {
fontSize: 14,
color: '#3B82F6',
fontWeight: '600',
},
warningCard: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#FEF3C7',
borderRadius: 12,
padding: 12,
marginBottom: 16,
gap: 8,
},
errorCard: {
backgroundColor: '#FEE2E2',
},
warningIcon: {
fontSize: 20,
},
warningText: {
flex: 1,
fontSize: 14,
color: '#991B1B',
},
swapButton: {
backgroundColor: KurdistanColors.kesk,
borderRadius: 16,
padding: 18,
alignItems: 'center',
marginBottom: 20,
},
swapButtonDisabled: {
backgroundColor: '#CCC',
},
swapButtonText: {
fontSize: 18,
fontWeight: 'bold',
color: '#FFFFFF',
},
loadingOverlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0,0,0,0.7)',
justifyContent: 'center',
alignItems: 'center',
zIndex: 1000,
},
loadingCard: {
backgroundColor: '#FFFFFF',
borderRadius: 20,
padding: 32,
alignItems: 'center',
gap: 16,
},
loadingText: {
fontSize: 16,
fontWeight: '600',
color: '#333',
},
modalOverlay: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
modalCard: {
backgroundColor: '#FFFFFF',
borderRadius: 20,
padding: 24,
width: '100%',
maxWidth: 400,
},
modalHeader: {
fontSize: 22,
fontWeight: 'bold',
color: '#333',
marginBottom: 20,
textAlign: 'center',
},
tokenOption: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
borderRadius: 12,
backgroundColor: '#F8F9FA',
marginBottom: 8,
gap: 12,
},
tokenOptionLogo: {
width: 40,
height: 40,
},
tokenOptionInfo: {
flex: 1,
},
tokenOptionSymbol: {
fontSize: 16,
fontWeight: 'bold',
color: '#333',
},
tokenOptionName: {
fontSize: 12,
color: '#666',
},
modalCloseButton: {
backgroundColor: '#EEE',
borderRadius: 12,
padding: 16,
alignItems: 'center',
marginTop: 12,
},
modalCloseButtonText: {
fontSize: 16,
fontWeight: '600',
color: '#333',
},
settingsLabel: {
fontSize: 14,
fontWeight: '500',
color: '#666',
marginBottom: 12,
},
slippageButtons: {
flexDirection: 'row',
gap: 8,
marginBottom: 20,
},
slippageButton: {
flex: 1,
padding: 12,
borderRadius: 12,
backgroundColor: '#F5F5F5',
alignItems: 'center',
},
slippageButtonActive: {
backgroundColor: KurdistanColors.kesk,
},
slippageButtonText: {
fontSize: 14,
fontWeight: '600',
color: '#666',
},
slippageButtonTextActive: {
color: '#FFFFFF',
},
confirmDetails: {
backgroundColor: '#F8F9FA',
borderRadius: 12,
padding: 16,
marginBottom: 20,
},
confirmRow: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 8,
},
confirmRowBorder: {
borderTopWidth: 1,
borderTopColor: '#E5E5E5',
marginTop: 8,
paddingTop: 16,
},
confirmLabel: {
fontSize: 14,
color: '#666',
},
confirmValue: {
fontSize: 16,
fontWeight: 'bold',
color: '#333',
},
confirmLabelSmall: {
fontSize: 12,
color: '#999',
},
confirmValueSmall: {
fontSize: 12,
color: '#666',
},
confirmButtons: {
flexDirection: 'row',
gap: 12,
},
confirmCancelButton: {
flex: 1,
padding: 16,
borderRadius: 12,
backgroundColor: '#EEE',
alignItems: 'center',
},
confirmCancelButtonText: {
fontSize: 16,
fontWeight: '600',
color: '#333',
},
confirmSwapButton: {
flex: 1,
padding: 16,
borderRadius: 12,
backgroundColor: KurdistanColors.kesk,
alignItems: 'center',
},
confirmSwapButtonText: {
fontSize: 16,
fontWeight: '600',
color: '#FFFFFF',
},
});
export default SwapScreen;