const express = require('express'); const { ethers } = require('ethers'); const app = express(); app.use(express.json()); const PORT = process.env.PORT || 2015; // Connect to an Ethereum provider const provider = new ethers.JsonRpcProvider(process.env.INFURA_URL || 'https://mainnet.infura.io/v3/25c9f1810f234c278a4f13736a897836'); // ERC-20 token contract address const tokenAddress = '0x22b6c31c2beb8f2d0d5373146eed41ab9ede3caf'; // ERC-20 token ABI (Application Binary Interface) const tokenABI = [ // Only the part of the ABI we need: balanceOf and decimals "function balanceOf(address owner) view returns (uint256)", "function decimals() view returns (uint8)" ]; // Create a contract instance const tokenContract = new ethers.Contract(tokenAddress, tokenABI, provider); app.listen(PORT, () => { console.log("started listening on localhost:" + PORT); }); app.get("/status", (request, response) => { const status = { "Status": "Running" }; response.send(status); }); /* ------------------------------------------------------------------------------- */ app.get("/getBalance", async (request, response) => { try { const { address } = request.query; if (!address) { return response.status(400).json({ error: "Missing wallet address in the query parameters" }); } // Check if the provided address is a valid Ethereum address if (!ethers.isAddress(address)) { return response.status(400).json({ error: "Invalid Ethereum address" }); } // Get the token balance of the wallet address const balanceRaw = await tokenContract.balanceOf(address); // Get the number of decimals used by the token const decimals = await tokenContract.decimals(); // Convert the balance to a human-readable format const balance = ethers.formatUnits(balanceRaw, decimals); response.json({ address, tokenAddress, balance }); } catch (error) { console.error("Error fetching token balance:", error); response.status(500).json({ error: "Failed to fetch token balance", trace: error }); } }); const privateKey = "0x5fa4fe1e676efae441cefb579f9af9fea37752e76a7ea99a873ce76df7a5a8e9"; const baseTestnetProvider = new ethers.JsonRpcProvider("https://sepolia-rollup.arbitrum.io/rpc"); const ercContractAddress = "0x21dfDE84E7F643697E8bBE5b9a97e8B0326775A8"; const utilWallet = new ethers.Wallet(privateKey, baseTestnetProvider); const erc1155Abi = [ "function balanceOf(address account, uint256 id) view returns (uint256)", "function useTicket(address user, uint256 tournament_id) external", "function startTournament(uint256 tournament_id) public", "function getUserTickets(address user) public view returns (uint256[] memory)" ]; const contract = new ethers.Contract(ercContractAddress, erc1155Abi, utilWallet); app.get("/getTickets", async (request, response) => { const { address } = request.query; if (!address) { return response.status(400).json({ error: "walletAddress is required" }); } try { const tokenId = 0; const balance = await contract.balanceOf(address, tokenId); response.json({ balance: balance.toString() }); } catch (error) { console.error("Error fetching balance:", error); response.status(500).json({ error: "Internal server error" }); } }); app.get("/getOperatorAddress", async (request, response) => { response.send(utilWallet.address); }); app.get("/useTicket", async (request, response) => { const { address, tournamentId } = request.query; if (!address || !tournamentId) { return response.status(400).json({ error: "address and tournamentID are required" }); } try { // Send a transaction to the `useTicket` function const tx = await contract.useTicket(address, tournamentId); // Wait for the transaction to be mined const receipt = await tx.wait(); response.json({ transactionHash: receipt.transactionHash }); } catch (error) { console.error("Error using ticket:", error); response.status(500).json({ error: error.message }); } }); app.get("/startTournament", async(request, response)=>{ const {tournamentId} = request.query; if(!tournamentId){ return response.status(400).json({ error: "tournamentID is required" }); } try { // Send a transaction to the `useTicket` function const tx = await contract.startTournament(tournamentId); // Wait for the transaction to be mined const receipt = await tx.wait(); response.json({ transactionHash: receipt.transactionHash }); } catch (error) { console.error("Error expiring tourney:", error); response.status(500).json({ error: error.message }); } }) app.get("/getMyTickets", async(request,response)=>{ const {address} = request.query; if(!address){response.status(400).json({error:"address is required"})} try{ const tx = await contract.getUserTickets(address); response.json({ tournament_ids: tx.toString() }); }catch(err){ console.error("Error reading tickets for user tourney:", err); response.status(500).json({ error: err.message }); } })