ecpay_expo/app/(tabs)/scanner.tsx
2024-12-22 22:22:06 +05:30

182 lines
5.4 KiB
TypeScript

import React, { useState, useEffect, useRef } from "react";
import { Modal, View, Text, Button, TextInput, SafeAreaView, StatusBar, Platform, StyleSheet, AppState } from "react-native";
import { CameraView } from "expo-camera";
import { Stack, useNavigation } from "expo-router"; // Updated import for navigation
import { Overlay } from "./Overlay";
import { ethers } from "ethers";
import { CHAIN_ID, CONTRACT_ADDRESS, contractABI } from "./shared";
import { useWalletConnectModal } from "@walletconnect/modal-react-native";
export default function Home() {
const qrLock = useRef(false);
const appState = useRef(AppState.currentState);
const navigation = useNavigation(); // Hook for navigation
const [modalVisible, setModalVisible] = useState(false);
const [scannedAddress, setScannedAddress] = useState("");
const [dollarValue, setDollarValue] = useState("");
useEffect(() => {
const subscription = AppState.addEventListener("change", (nextAppState) => {
if (appState.current.match(/inactive|background/) && nextAppState === "active") {
qrLock.current = false;
}
appState.current = nextAppState;
});
return () => {
subscription.remove();
};
}, []);
const { open, isConnected, address, provider } = useWalletConnectModal();
const isValidEthAddress = (address:string) => /^0x[a-fA-F0-9]{40}$/.test(address);
const transferEth = async () => {
if (!provider || !isConnected) {
console.error("Wallet not connected.");
return;
}
try {
const ethersProvider = new ethers.providers.Web3Provider(provider);
const network = await ethersProvider.getNetwork();
if (network.chainId !== CHAIN_ID) {
console.log(`Switching from ${network.chainId} to ${CHAIN_ID} (Arbitrum Sepolia)...`);
await provider.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: `0x${CHAIN_ID.toString(16)}` }],
});
console.log(`Switched to chain ID: ${CHAIN_ID}`);
}
const signer = ethersProvider.getSigner();
const contract = new ethers.Contract(CONTRACT_ADDRESS, contractABI, signer);
const priceResponse = await fetch("http://vps.playpoolstudios.com:28328/getMarkPriceETH");
const priceJson = await priceResponse.json();
const price = priceJson['price'];
const ethValue = parseFloat(dollarValue) / price; // Convert dollars to ETH assuming 1 ETH = $3600
console.log(`Converted ${dollarValue} THB to ${ethValue} ETH`);
console.log("Requesting contract call");
const tx = await contract.transferETH(scannedAddress, {
value: ethers.utils.parseEther(ethValue.toFixed(18).toString()),
});
console.log("Transaction sent:", tx.hash);
await tx.wait();
console.log("Transaction confirmed:", tx.hash);
// Navigate back after the transaction is confirmed
navigation.goBack();
} catch (error) {
console.error("Transfer failed:", error);
}
};
return (
<SafeAreaView style={StyleSheet.absoluteFillObject}>
<Stack.Screen
options={{
title: "Overview",
headerShown: false,
}}
/>
{Platform.OS === "android" ? <StatusBar hidden /> : null}
<CameraView
style={StyleSheet.absoluteFillObject}
facing="back"
onBarcodeScanned={({ data }) => {
if (data && !qrLock.current) {
qrLock.current = true;
setScannedAddress(data); // Save the scanned address
setModalVisible(true); // Open the popup/modal
}
}}
/>
<Overlay />
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => setModalVisible(false)} // Close modal on back action
>
<View style={styles.modalContainer}>
<View style={styles.modalContent}>
<Text style={styles.title}>Enter Amount</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="0.00"
keyboardType="numeric"
value={dollarValue}
onChangeText={setDollarValue}
/>
<Text style={styles.dollarSign}> THB</Text>
</View>
<Button title="Transfer ETH" onPress={transferEth} color="#4CAF50" />
<View style={styles.spacer} />
<Button title="Close" onPress={() => setModalVisible(false)} color="#F44336" />
</View>
</View>
</Modal>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
modalContainer: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "rgba(0,0,0,0.5)",
},
modalContent: {
width: "80%",
backgroundColor: "white",
borderRadius: 10,
padding: 20,
alignItems: "center",
elevation: 5,
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
},
title: {
fontSize: 20,
fontWeight: "bold",
marginBottom: 10,
},
inputContainer: {
flexDirection: "row",
alignItems: "center",
marginBottom: 20,
},
dollarSign: {
fontSize: 18,
marginRight: 5,
color: "#333",
},
input: {
borderWidth: 1,
borderColor: "#ccc",
borderRadius: 5,
padding: 10,
width: "70%",
fontSize: 16,
textAlign: "left",
},
spacer: {
height: 10,
},
});