From 3cfc3c5792616ba2f181badc7c97612a748fa999 Mon Sep 17 00:00:00 2001 From: Sewmina Date: Tue, 31 Dec 2024 10:29:02 +0530 Subject: [PATCH] Embedded wallets done --- app/(tabs)/index.tsx | 261 ++++++++++++++++++++++++---------- app/(tabs)/scanner.tsx | 63 ++++++++ app/(tabs)/shared.tsx | 2 +- components/FirebaseConfig.tsx | 17 +++ package-lock.json | 32 ++++- package.json | 4 +- 6 files changed, 303 insertions(+), 76 deletions(-) create mode 100644 components/FirebaseConfig.tsx diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 1b6d257..77152ab 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Image, StyleSheet, Pressable, Platform, View, Alert } from 'react-native'; +import { Image, StyleSheet, Pressable, Platform, View, Alert, ActivityIndicator, ToastAndroid, Button } from 'react-native'; import { useCameraPermissions } from 'expo-camera'; import Link, { } from 'expo-router/link'; import { ethers } from 'ethers'; @@ -12,9 +12,10 @@ import { CHAIN_ID, CONTRACT_ADDRESS, projectId, providerMetadata } from './share import { contractABI } from './ABI/transfer_contract'; // import { GoogleSignin } from 'react-native-google-signin'; import { GoogleSignin, statusCodes, GoogleSigninButton, isErrorWithCode, User } from '@react-native-google-signin/google-signin'; -import auth from '@react-native-firebase/auth'; - - +import auth, { getAuth, signInWithCredential } from '@react-native-firebase/auth'; +import { app, authInstance } from '@/components/FirebaseConfig'; +import Clipboard from '@react-native-clipboard/clipboard'; +import FontAwesome5 from '@expo/vector-icons/FontAwesome5'; export default function HomeScreen() { const [loading, setLoading] = useState(false); const [transferLoading, setTransferLoading] = useState(false); @@ -25,6 +26,37 @@ export default function HomeScreen() { const isPermissionGranted = Boolean(permission?.granted); const { open, isConnected, address, provider } = useWalletConnectModal(); + const activeAddress = isConnected ? address : embeddedWallet; + const [ethBalance, setEthBalance] = useState(null); + const [usdtBalance, setUsdtBalance] = useState(null); + + useEffect(() => { + const fetchBalances = async () => { + if (activeAddress) { + try { + // Fetch ETH balance + const ethResponse = await fetch( + `http://vps.playpoolstudios.com:30117/ethBalance/${activeAddress}` + ); + const ethData = await ethResponse.json(); + setEthBalance(ethData.ethBalance); + + // Fetch USDT balance + const usdtResponse = await fetch( + `http://vps.playpoolstudios.com:30117/usdtBalance/${activeAddress}` + ); + const usdtData = await usdtResponse.json(); + setUsdtBalance(usdtData.tokenBalance); + } catch (error) { + console.error("Error fetching balances:", error); + setEthBalance(null); + setUsdtBalance(null); + } + } + }; + + fetchBalances(); + }, [activeAddress]); useEffect(() => { setLoading(true); @@ -40,8 +72,8 @@ export default function HomeScreen() { if (userInfo != null) { console.log("Setting firebase user silently"); setFirebaseUser(userInfo.data); - console.log(firebaseUser); + fetchEmbeddedWallet(); } } catch (error) { console.error('Failed to check Google sign-in status:', error); @@ -54,22 +86,21 @@ export default function HomeScreen() { }, []) useEffect(() => { - - const fetchEmbeddedWallet = async () => { - if (firebaseUser == null) { console.log('firebase user is null'); return; } - const googleCredential = auth.GoogleAuthProvider.credential(firebaseUser.idToken); - const userCredential = await auth().signInWithCredential(googleCredential); - const tokenId = await userCredential.user.getIdToken(); - console.log(`tokenId from firebase ${tokenId}`); - const register = await fetch(`http://vps.playpoolstudios.com:30017/signinWithGoogle?tokenId=${tokenId}`) - const registerJson = await register.json(); - console.log(registerJson); - setEmbeddedWallet(registerJson['publicKey']); - } - fetchEmbeddedWallet(); }, [firebaseUser]) + const fetchEmbeddedWallet = async () => { + // console.log(firebaseUser?.user.email); + // const googleCredential = auth.GoogleAuthProvider.credential(firebaseUser?.idToken ?? ""); + // const userCredential = await authInstance.signInWithCredential(googleCredential); + // const tokenId = await userCredential.user.getIdToken(); + // console.log(`tokenId from firebase ${tokenId}`); + if (!firebaseUser) { return; } + const register = await fetch(`http://vps.playpoolstudios.com:30017/signinWithGoogle?tokenId=${firebaseUser?.idToken}`) + const registerJson = await register.json(); + console.log(registerJson); + setEmbeddedWallet(registerJson['pub_key']); + } const connectWallet = async () => { setLoading(true); try { @@ -134,6 +165,8 @@ export default function HomeScreen() { if (type === 'success') { console.log({ data }); setFirebaseUser(data); + fetchEmbeddedWallet(); + } else { // sign in was cancelled by user setTimeout(() => { @@ -173,6 +206,15 @@ export default function HomeScreen() { } } + const copyWalletAddress = () => { + Clipboard.setString(activeAddress ?? ""); + if (Platform.OS === 'android') { + ToastAndroid.show('Wallet address copied!', ToastAndroid.SHORT); + } else { + alert('Wallet address copied!'); + } + }; + return ( <> Welcome to ECPay - {/* Connect Wallet Section */} - { - firebaseUser == null ? - ( - - {loading ? 'Connecting...' : isConnected ? 'Disconnect Wallet' : 'Connect Wallet'} - - ) : (<>)} - {/* Display Wallet Address if Connected */} - {isConnected && ( - - Connected Wallet: - {address} - + {(firebaseUser || isConnected) ? (<> + + + {loading ? ( + + ) : ( + + + + {ethBalance !== null ? `${parseFloat(ethBalance).toFixed(8)}` : 'Loading'} + + + {ethBalance !== null ? 'ETH' : 'Loading'} + + + + + {usdtBalance !== null ? `${parseFloat(usdtBalance).toFixed(3)}` : 'Loading'} + + + {usdtBalance !== null ? 'USDT' : 'Loading'} + + + + + )} + + + + {activeAddress} + + {/* */} + + + ) : ( + <> )} - { - (firebaseUser == null && !isConnected) ? - () - : - (!isConnected) ? - ( - - - Signed in as {firebaseUser?.user.email} - - - {embeddedWallet} - - - Logout - - - - ) - : - (<>) - } - - {/* Link to Scanner */} - {isPermissionGranted ? (isConnected || firebaseUser != null) && ( + {/* Link to Scanner */} + {isPermissionGranted ? (isConnected || firebaseUser != null) && ( [ @@ -256,18 +294,58 @@ export default function HomeScreen() { )} - {/* Transfer ETH Button - - - {transferLoading ? 'Transferring...' : 'Transfer 0.003 ETH'} - - + {/* Connect Wallet Section */} + { + firebaseUser == null ? + ( + + {loading ? 'Connecting...' : isConnected ? 'Disconnect Wallet' : 'Connect Wallet'} + + ) : (<>)} - - - Scanned Ethereum Address: - {''} - */} + + { + (firebaseUser == null && !isConnected) ? + () + : + + (!isConnected) ? + ( + + + Signed in as {firebaseUser?.user.email} + + + + + Logout + + + + ) + : + (<>) + } + + + + {/* Transfer ETH Button + + + {transferLoading ? 'Transferring...' : 'Transfer 0.003 ETH'} + + + + + + Scanned Ethereum Address: + {''} + */} {/* WalletConnect Modal */} @@ -345,4 +423,41 @@ const styles = StyleSheet.create({ borderRadius: 8, alignItems: 'center', }, + title: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 10, + }, + address: { + fontSize: 14, + color: '#888', + marginBottom: 20, + textAlign: 'center', + }, + addressRow: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + balancesContainer: { + flexDirection: 'row', + paddingVertical:20 + }, + balance: { + alignItems: 'center', + marginHorizontal: 20, // Space between the two balance views + }, + value: { + fontSize: 25, // Bigger font for the balance value + fontWeight: 'bold', + }, + label: { + fontSize: 14, // Smaller font for ETH/USDT labels + color: 'gray', + }, }); diff --git a/app/(tabs)/scanner.tsx b/app/(tabs)/scanner.tsx index 5e6cc5d..932f616 100644 --- a/app/(tabs)/scanner.tsx +++ b/app/(tabs)/scanner.tsx @@ -8,6 +8,7 @@ import { CHAIN_ID, CONTRACT_ADDRESS, TOKEN_CONTRACT_ADDRESS } from "./shared"; import { useWalletConnectModal } from "@walletconnect/modal-react-native"; import { contractABI } from "./ABI/transfer_contract"; import { erc20ABI } from "./ABI/erc20_contract"; +import { GoogleSignin, User } from "@react-native-google-signin/google-signin"; export default function Home() { const qrLock = useRef(false); @@ -17,6 +18,8 @@ export default function Home() { const [modalVisible, setModalVisible] = useState(false); const [scannedAddress, setScannedAddress] = useState("0xE09865aaCd816729C19E4BeA4caFf247704De9fE"); const [dollarValue, setDollarValue] = useState("400"); + const [firebaseUser, setFirebaseUser] = useState(); + const [isLoading, setIsLoading]= useState(false); useEffect(() => { const subscription = AppState.addEventListener("change", (nextAppState) => { @@ -26,6 +29,21 @@ export default function Home() { appState.current = nextAppState; }); + const checkSignInStatus = async () => { + try { + const userInfo = await GoogleSignin.signInSilently(); + + if (userInfo != null) { + console.log("Setting firebase user silently"); + setFirebaseUser(userInfo.data); + } + } catch (error) { + console.error('Failed to check Google sign-in status:', error); + } finally { + } + }; + checkSignInStatus(); + transferEth(); return () => { @@ -37,9 +55,21 @@ export default function Home() { const isValidEthAddress = (address:string) => /^0x[a-fA-F0-9]{40}$/.test(address); + const transferEthRemtoe = async () => { + setIsLoading(true); + const response =await fetch(`http://vps.playpoolstudios.com:30117/sendTransaction?tokenId=${firebaseUser?.idToken}&receiver=${scannedAddress}&amount=${dollarValue}`); + console.log(await response.text()); + setIsLoading(false); + navigation.goBack(); + } + const transferEth = async () => { if (!provider || !isConnected) { console.error("Wallet not connected."); + + if(firebaseUser!=null){ + transferEthRemtoe(); + } return; } @@ -119,6 +149,17 @@ export default function Home() { /> + {/* Loading Modal */} + {isLoading && ( + + + + Loading... + + + + )} + =0.60 <1.0" } }, + "node_modules/@react-native-clipboard/clipboard": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.15.0.tgz", + "integrity": "sha512-YDMC3E956jn9zE11uKGcQDKS1SO9q72iNHxZyrKY5y9XYwZcA9vo3Xk74+zRnf7cM48drDO0s9lyAPUlOvyhrw==", + "license": "MIT", + "workspaces": [ + "example" + ], + "peerDependencies": { + "react": ">= 16.9.0", + "react-native": ">= 0.61.5", + "react-native-macos": ">= 0.61.0", + "react-native-windows": ">= 0.61.0" + }, + "peerDependenciesMeta": { + "react-native-macos": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + } + }, "node_modules/@react-native-community/cli": { "version": "15.1.3", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-15.1.3.tgz", @@ -22462,6 +22488,10 @@ "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", "license": "MIT" }, + "node_modules/undefined": { + "resolved": "@expo/vector-icons/FontAwesome5", + "link": true + }, "node_modules/undici": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", diff --git a/package.json b/package.json index e6e49e8..dbd692f 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "dependencies": { "@expo/vector-icons": "^14.0.2", "@react-native-async-storage/async-storage": "1.23.1", + "@react-native-clipboard/clipboard": "^1.15.0", "@react-native-community/netinfo": "11.4.1", "@react-native-firebase/app": "^21.6.1", "@react-native-firebase/auth": "^21.6.1", @@ -58,7 +59,8 @@ "react-native-screens": "~4.4.0", "react-native-svg": "15.8.0", "react-native-web": "~0.19.13", - "react-native-webview": "13.12.5" + "react-native-webview": "13.12.5", + "undefined": "@expo/vector-icons/FontAwesome5" }, "devDependencies": { "@babel/core": "^7.25.2",