182 lines
5.4 KiB
TypeScript
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,
|
|
},
|
|
});
|