diff --git a/android/.gitignore b/android/.gitignore index d914c32..d731bb6 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -38,4 +38,15 @@ yarn-error.* # generated native folders /ios -/android +# Ignore most of android except app icons and manifest +/android/* +!/android/app/ +/android/app/* +!/android/app/src/ +/android/app/src/* +!/android/app/src/main/ +/android/app/src/main/* +!/android/app/src/main/AndroidManifest.xml +!/android/app/src/main/res/ +/android/app/src/main/res/* +!/android/app/src/main/res/mipmap-*/ diff --git a/android/App.js b/android/App.js index 698f945..f202339 100644 --- a/android/App.js +++ b/android/App.js @@ -37,6 +37,7 @@ import { Vibration, Animated, } from "react-native"; +import Toast from "react-native-toast-message"; import NetInfo from "@react-native-community/netinfo"; import { Keypair, @@ -54,7 +55,10 @@ import slip10 from "micro-key-producer/slip10.js"; import { randomBytes, secretbox } from "tweetnacl"; import bs58 from "bs58"; import { GestureHandlerRootView } from "react-native-gesture-handler"; -import { SafeAreaProvider } from "react-native-safe-area-context"; +import { + SafeAreaProvider, + useSafeAreaInsets, +} from "react-native-safe-area-context"; // Replaced @gorhom/bottom-sheet with simple Modal-based implementation import BottomSheet, { SimpleBottomSheetView as BottomSheetView, @@ -301,6 +305,9 @@ const NETWORKS = [ const apolloClient = createApolloClient("backpack-android", "1.0.0"); function AppContent() { + // Get safe area insets + const insets = useSafeAreaInsets(); + // Authentication states const [authState, setAuthState] = useState("loading"); // 'loading', 'setup', 'locked', 'unlocked' const [password, setPassword] = useState(null); @@ -330,6 +337,9 @@ function AppContent() { const [showBluetoothDrawer, setShowBluetoothDrawer] = useState(false); const [pairedDevices, setPairedDevices] = useState([]); + // State for address selector -> send screen communication + const [selectedAddressForSend, setSelectedAddressForSend] = useState(""); + // Wallet management states const [showAddWalletModal, setShowAddWalletModal] = useState(false); const [showCreateWalletModal, setShowCreateWalletModal] = useState(false); @@ -481,16 +491,10 @@ function AppContent() { }, []); // Debug logging function - only logs when debug drawer is active - const addDebugLog = useCallback( - (message) => { - if (!showDebugDrawer) return; // Only log when debug drawer is open - const timestamp = new Date().toLocaleTimeString(); - setDebugLogs((prev) => - [...prev, `[${timestamp}] ${message}`].slice(-100) - ); // Keep last 100 logs - }, - [showDebugDrawer] - ); + const addDebugLog = useCallback((message) => { + const timestamp = new Date().toLocaleTimeString(); + setDebugLogs((prev) => [...prev, `[${timestamp}] ${message}`].slice(-100)); // Keep last 100 logs + }, []); // Wallet storage functions const saveWalletsToStorage = async (walletsToSave) => { @@ -510,11 +514,17 @@ function AppContent() { }; const loadWalletsFromStorage = async () => { + console.log("🔵 loadWalletsFromStorage called"); try { const storedWallets = await AsyncStorage.getItem("@wallets"); + console.log("📦 Raw stored wallets:", storedWallets ? "exists" : "null"); if (storedWallets) { const parsed = JSON.parse(storedWallets); - console.log("Loaded wallets from storage:", parsed.length); + console.log("✅ Loaded wallets from storage:", parsed.length); + console.log( + "📝 Wallet addresses:", + parsed.map((w) => w.publicKey).join(", ") + ); // Reconstruct keypairs from stored secret keys const walletsWithKeypairs = parsed.map((wallet) => { @@ -547,15 +557,30 @@ function AppContent() { (w) => String(w.id) === storedSelectedWalletId ); if (selectedWalletFromStorage) { + console.log( + "🟢 Setting selected wallet from storage:", + selectedWalletFromStorage.name, + selectedWalletFromStorage.publicKey + ); setSelectedWallet(selectedWalletFromStorage); console.log( "Restored selected wallet:", selectedWalletFromStorage.name ); } else if (walletsWithKeypairs.length > 0) { + console.log( + "🟡 No saved selection, using first wallet:", + walletsWithKeypairs[0].name, + walletsWithKeypairs[0].publicKey + ); setSelectedWallet(walletsWithKeypairs[0]); } } else if (walletsWithKeypairs.length > 0) { + console.log( + "🟠 No wallet ID stored, using first wallet:", + walletsWithKeypairs[0].name, + walletsWithKeypairs[0].publicKey + ); setSelectedWallet(walletsWithKeypairs[0]); } } catch (err) { @@ -641,7 +666,9 @@ function AppContent() { // Load wallets and master seed phrase on mount useEffect(() => { + console.log("🔐 Auth state changed to:", authState); if (authState === "unlocked") { + console.log("🔓 App unlocked, loading wallets..."); loadWalletsFromStorage(); loadMasterSeedPhrase(); loadDerivationIndex(); @@ -786,7 +813,13 @@ function AppContent() { ); const data = await response.json(); + console.log("API Response Data:", JSON.stringify(data, null, 2)); + if (data.balance !== undefined) { + console.log( + `✅ Balance API returned: balance=${data.balance}, tokens count=${data.tokens?.length}` + ); + // Format balance with up to 6 decimals for display const balanceStr = data.balance.toLocaleString("en-US", { minimumFractionDigits: 2, @@ -817,11 +850,19 @@ function AppContent() { token.symbol === "XNT" ? "💎" : token.symbol === "SOL" ? "◎" : "🪙", })); + console.log(`📊 Updating state with: + - balance: ${balanceStr} + - balanceUSD: ${usdStr} + - tokenPrice: ${price} + - tokens count: ${formattedTokens.length}`); + setBalance(balanceStr); setBalanceUSD(usdStr); setTokenPrice(price); setTokens(formattedTokens); + console.log("✅ State updated successfully"); + // Save to cache setBalanceCache((prev) => ({ ...prev, @@ -954,7 +995,18 @@ function AppContent() { // Load initial balance useEffect(() => { - if (!selectedWallet) return; + console.log("🔄 useEffect triggered for balance/transactions"); + console.log("selectedWallet:", selectedWallet); + console.log("currentNetwork:", currentNetwork); + + if (!selectedWallet) { + console.log("⚠️ No selected wallet, skipping balance/transaction check"); + return; + } + + console.log( + `✅ Calling checkBalance and checkTransactions for wallet: ${selectedWallet.publicKey}` + ); checkBalance(); checkTransactions(); }, [selectedWallet?.publicKey, currentNetwork]); @@ -1088,7 +1140,12 @@ function AppContent() { }); } - Alert.alert("Success", "Wallet deleted successfully"); + Toast.show({ + type: "success", + text1: "Success", + text2: "Wallet deleted successfully", + position: "bottom", + }); }, }, ] @@ -1183,6 +1240,8 @@ function AppContent() { }; const handleSend = async () => { + // Clear any previously selected address + setSelectedAddressForSend(""); await sendSheetRef.current?.present(); }; @@ -1192,37 +1251,67 @@ function AppContent() { console.log("📋 selectedWallet.address:", selectedWallet?.address); console.log("📋 selectedWallet.publicKey:", selectedWallet?.publicKey); Clipboard.setString(text); - Alert.alert("Copied", "Address copied to clipboard"); + Toast.show({ + type: "success", + text1: "Copied", + text2: "Address copied to clipboard", + position: "bottom", + visibilityTime: 2000, + }); }; - const handleSendSubmit = async () => { + const handleSendSubmit = async (amount, address) => { // Dismiss keyboard when Send button is pressed Keyboard.dismiss(); if (!selectedWallet) { - Alert.alert("Error", "No wallet selected"); + Toast.show({ + type: "error", + text1: "Error", + text2: "No wallet selected", + position: "bottom", + }); return; } - if (!sendAddress || !sendAmount) { - Alert.alert("Error", "Please enter both address and amount"); + if (!address || !amount) { + Toast.show({ + type: "error", + text1: "Error", + text2: "Please enter both address and amount", + position: "bottom", + }); return; } + // Store values in state for confirmation screen + setSendAmount(amount); + setSendAddress(address); + // Trim the address to remove any whitespace - const trimmedAddress = sendAddress.trim(); + const trimmedAddress = address.trim(); // Validate address format try { new PublicKey(trimmedAddress); } catch (e) { - Alert.alert("Error", "Invalid recipient address"); + Toast.show({ + type: "error", + text1: "Error", + text2: "Invalid recipient address", + position: "bottom", + }); return; } // Validate amount - const amountNum = parseFloat(sendAmount); + const amountNum = parseFloat(amount); if (isNaN(amountNum) || amountNum <= 0) { - Alert.alert("Error", "Invalid amount"); + Toast.show({ + type: "error", + text1: "Error", + text2: "Invalid amount", + position: "bottom", + }); return; } @@ -1405,15 +1494,30 @@ function AppContent() { }; const handleSwap = () => { - Alert.alert("Swap", "Swap functionality would open here"); + Toast.show({ + type: "info", + text1: "Swap", + text2: "Swap functionality would open here", + position: "bottom", + }); }; const handleStake = () => { - Alert.alert("Stake", "Stake functionality would open here"); + Toast.show({ + type: "info", + text1: "Stake", + text2: "Stake functionality would open here", + position: "bottom", + }); }; const handleBridge = () => { - Alert.alert("Bridge", "Bridge functionality would open here"); + Toast.show({ + type: "info", + text1: "Bridge", + text2: "Bridge functionality would open here", + position: "bottom", + }); }; const copyAddress = () => { @@ -2097,9 +2201,17 @@ function AppContent() { const updatedWallets = wallets .map((w) => ({ ...w, selected: false })) .concat(newWallet); + + console.log( + "💾 Saving new wallet to storage:", + newWallet.name, + newWallet.publicKey + ); setWallets(updatedWallets); setSelectedWallet(newWallet); + console.log("✅ Set new wallet as selectedWallet"); await saveWalletsToStorage(updatedWallets); + console.log("💾 Wallets saved to storage"); // Increment and save derivation index for next wallet const nextIndex = walletDerivationIndex + 1; @@ -3575,7 +3687,7 @@ function AppContent() { {/* Bottom Tab Bar */} - + { @@ -5339,6 +5451,7 @@ function AppContent() { handleSendSubmit={handleSendSubmit} wallets={wallets} addressSelectorSheetRef={addressSelectorSheetRef} + selectedAddressFromSelector={selectedAddressForSend} onDismiss={() => sendSheetRef.current?.dismiss()} /> @@ -5464,6 +5577,11 @@ function AppContent() { backgroundColor="#000000" > { + setSelectedAddressForSend(address); + addressSelectorSheetRef.current?.dismiss(); + }} onDismiss={() => addressSelectorSheetRef.current?.dismiss()} /> @@ -5485,6 +5603,112 @@ function AppContent() { onDismiss={() => ledgerSheetRef.current?.dismiss()} /> + + {/* Toast notifications */} + ( + + + {props.text1} + + + {props.text2} + + + ), + error: (props) => ( + + + {props.text1} + + + {props.text2} + + + ), + info: (props) => ( + + + {props.text1} + + + {props.text2} + + + ), + }} + /> ); } @@ -6954,12 +7178,10 @@ const styles = StyleSheet.create({ flexDirection: "row", backgroundColor: "transparent", borderTopWidth: 0, - paddingBottom: 35, paddingTop: 0, paddingHorizontal: 20, justifyContent: "space-around", alignItems: "flex-start", - height: 86, }, bottomTabItem: { flex: 1, diff --git a/android/android/app/src/main/AndroidManifest.xml b/android/android/app/src/main/AndroidManifest.xml index 8c091d8..c5ab1bd 100644 --- a/android/android/app/src/main/AndroidManifest.xml +++ b/android/android/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ - + diff --git a/android/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..3aa0dff Binary files /dev/null and b/android/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..3aa0dff Binary files /dev/null and b/android/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..33f5776 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..33f5776 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..096827f Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..096827f Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..19f7d81 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..19f7d81 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..e5492d0 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e5492d0 Binary files /dev/null and b/android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/package-lock.json b/android/package-lock.json index 798f706..efff9b6 100644 --- a/android/package-lock.json +++ b/android/package-lock.json @@ -40,9 +40,10 @@ "react-native-qrcode-svg": "^6.3.20", "react-native-quick-crypto": "^0.7.17", "react-native-reanimated": "~4.1.1", - "react-native-safe-area-context": "^5.6.2", + "react-native-safe-area-context": "github:AppAndFlow/react-native-safe-area-context", "react-native-screens": "^4.18.0", "react-native-svg": "15.12.1", + "react-native-toast-message": "^2.3.3", "react-native-webview": "^13.16.0", "react-native-worklets": "^0.6.1", "stream-browserify": "^3.0.0", @@ -9986,8 +9987,7 @@ }, "node_modules/react-native-safe-area-context": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", - "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", + "resolved": "git+ssh://git@github.com/AppAndFlow/react-native-safe-area-context.git#8b2267a4726b7520e82d35f26d23bacce9ec44c9", "license": "MIT", "peerDependencies": { "react": "*", @@ -10023,6 +10023,16 @@ "react-native": "*" } }, + "node_modules/react-native-toast-message": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.3.3.tgz", + "integrity": "sha512-4IIUHwUPvKHu4gjD0Vj2aGQzqPATiblL1ey8tOqsxOWRPGGu52iIbL8M/mCz4uyqecvPdIcMY38AfwRuUADfQQ==", + "license": "MIT", + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-webview": { "version": "13.16.0", "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz", diff --git a/android/package.json b/android/package.json index c12fd2f..d07451e 100644 --- a/android/package.json +++ b/android/package.json @@ -41,9 +41,10 @@ "react-native-qrcode-svg": "^6.3.20", "react-native-quick-crypto": "^0.7.17", "react-native-reanimated": "~4.1.1", - "react-native-safe-area-context": "^5.6.2", + "react-native-safe-area-context": "github:AppAndFlow/react-native-safe-area-context", "react-native-screens": "^4.18.0", "react-native-svg": "15.12.1", + "react-native-toast-message": "^2.3.3", "react-native-webview": "^13.16.0", "react-native-worklets": "^0.6.1", "stream-browserify": "^3.0.0", diff --git a/android/screens/AddressSelectorScreen.js b/android/screens/AddressSelectorScreen.js index 4d91c44..1b01251 100644 --- a/android/screens/AddressSelectorScreen.js +++ b/android/screens/AddressSelectorScreen.js @@ -1,16 +1,16 @@ -import React from 'react'; +import React from "react"; import { View, Text, TouchableOpacity, StyleSheet, ScrollView, -} from 'react-native'; +} from "react-native"; export default function AddressSelectorScreen({ wallets = [], onSelect = () => {}, - onDismiss + onDismiss, }) { return ( @@ -34,7 +34,7 @@ export default function AddressSelectorScreen({ {wallet.name} - {wallet.address} + {wallet.publicKey} @@ -47,26 +47,26 @@ export default function AddressSelectorScreen({ const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#000000', + backgroundColor: "#000000", }, header: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", paddingHorizontal: 16, paddingVertical: 16, borderBottomWidth: 1, - borderBottomColor: '#1a1a1a', + borderBottomColor: "#1a1a1a", }, headerTitle: { fontSize: 18, - fontWeight: '600', - color: '#FFFFFF', + fontWeight: "600", + color: "#FFFFFF", }, headerClose: { fontSize: 24, - color: '#4A90E2', - fontWeight: '600', + color: "#4A90E2", + fontWeight: "600", }, content: { flex: 1, @@ -75,7 +75,7 @@ const styles = StyleSheet.create({ addressItem: { paddingVertical: 16, paddingHorizontal: 16, - backgroundColor: '#0a0a0a', + backgroundColor: "#0a0a0a", borderRadius: 12, marginBottom: 8, }, @@ -84,13 +84,13 @@ const styles = StyleSheet.create({ }, addressName: { fontSize: 16, - fontWeight: '600', - color: '#FFFFFF', + fontWeight: "600", + color: "#FFFFFF", marginBottom: 6, }, addressText: { fontSize: 12, - color: '#888888', - fontFamily: 'monospace', + color: "#888888", + fontFamily: "monospace", }, }); diff --git a/android/screens/SendScreen.js b/android/screens/SendScreen.js index 6bc00fc..e9c9488 100644 --- a/android/screens/SendScreen.js +++ b/android/screens/SendScreen.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from "react"; import { View, Text, @@ -6,7 +6,7 @@ import { TouchableOpacity, StyleSheet, ScrollView, -} from 'react-native'; +} from "react-native"; export default function SendScreen({ balance, @@ -14,11 +14,18 @@ export default function SendScreen({ handleSendSubmit, wallets, addressSelectorSheetRef, - onDismiss + selectedAddressFromSelector, + onDismiss, }) { + const [sendAmount, setSendAmount] = useState(""); + const [sendAddress, setSendAddress] = useState(""); - const [sendAmount, setSendAmount] = useState(''); - const [sendAddress, setSendAddress] = useState(''); + // Update sendAddress when an address is selected from the selector + useEffect(() => { + if (selectedAddressFromSelector) { + setSendAddress(selectedAddressFromSelector); + } + }, [selectedAddressFromSelector]); const onSend = () => { handleSendSubmit(sendAmount, sendAddress); @@ -31,7 +38,9 @@ export default function SendScreen({ - Send {getNativeTokenInfo().symbol} + + Send {getNativeTokenInfo().symbol} + × @@ -70,9 +79,7 @@ export default function SendScreen({ await addressSelectorSheetRef.current?.present(); }} > - - Select Address - + Select Address {/* Send Button */} - + Send @@ -100,31 +104,31 @@ export default function SendScreen({ const styles = StyleSheet.create({ container: { flex: 1, - backgroundColor: '#000000', + backgroundColor: "#000000", }, header: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", paddingHorizontal: 16, paddingVertical: 16, borderBottomWidth: 1, - borderBottomColor: '#1a1a1a', + borderBottomColor: "#1a1a1a", }, headerBack: { fontSize: 24, - color: '#4A90E2', - fontWeight: '600', + color: "#4A90E2", + fontWeight: "600", }, headerTitle: { fontSize: 18, - fontWeight: '600', - color: '#FFFFFF', + fontWeight: "600", + color: "#FFFFFF", }, headerClose: { fontSize: 32, - color: '#888888', - fontWeight: '300', + color: "#888888", + fontWeight: "300", }, content: { flex: 1, @@ -133,59 +137,59 @@ const styles = StyleSheet.create({ sendBalanceContainer: { marginBottom: 24, padding: 16, - backgroundColor: '#0a0a0a', + backgroundColor: "#0a0a0a", borderRadius: 12, }, sendBalanceLabel: { fontSize: 12, - color: '#888888', + color: "#888888", marginBottom: 4, }, sendBalanceText: { fontSize: 20, - fontWeight: '600', - color: '#4A90E2', + fontWeight: "600", + color: "#4A90E2", }, sendInputContainer: { marginBottom: 20, }, sendInputLabel: { fontSize: 12, - color: '#888888', + color: "#888888", marginBottom: 8, }, sendInput: { - backgroundColor: '#0a0a0a', + backgroundColor: "#0a0a0a", borderRadius: 8, paddingVertical: 12, paddingHorizontal: 16, fontSize: 16, - color: '#FFFFFF', + color: "#FFFFFF", borderWidth: 1, - borderColor: '#333333', + borderColor: "#333333", }, sendAddressHeader: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", marginBottom: 8, }, sendSelectAddressText: { fontSize: 12, - color: '#4A90E2', - fontWeight: '600', + color: "#4A90E2", + fontWeight: "600", }, sendSubmitButton: { paddingVertical: 14, paddingHorizontal: 20, - backgroundColor: '#4A90E2', + backgroundColor: "#4A90E2", borderRadius: 8, - alignItems: 'center', + alignItems: "center", marginTop: 8, }, sendSubmitButtonText: { fontSize: 16, - fontWeight: '600', - color: '#FFFFFF', + fontWeight: "600", + color: "#FFFFFF", }, }); diff --git a/android/yarn.lock b/android/yarn.lock index 8dbf394..2f2c916 100644 --- a/android/yarn.lock +++ b/android/yarn.lock @@ -5015,10 +5015,9 @@ react-native-quick-crypto@^0.7.17: react-native-is-edge-to-edge "^1.2.1" semver "7.7.2" -react-native-safe-area-context@*, react-native-safe-area-context@^5.6.2: +react-native-safe-area-context@*, "react-native-safe-area-context@github:AppAndFlow/react-native-safe-area-context": version "5.6.2" - resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz" - integrity sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg== + resolved "git+ssh://git@github.com/AppAndFlow/react-native-safe-area-context.git#8b2267a4726b7520e82d35f26d23bacce9ec44c9" react-native-screens@^4.18.0: version "4.18.0" @@ -5037,6 +5036,11 @@ react-native-svg@>=14.0.0, react-native-svg@15.12.1: css-tree "^1.1.3" warn-once "0.1.1" +react-native-toast-message@^2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/react-native-toast-message/-/react-native-toast-message-2.3.3.tgz" + integrity sha512-4IIUHwUPvKHu4gjD0Vj2aGQzqPATiblL1ey8tOqsxOWRPGGu52iIbL8M/mCz4uyqecvPdIcMY38AfwRuUADfQQ== + react-native-webview@*, react-native-webview@^13.16.0: version "13.16.0" resolved "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz"