From a1d2dd26ca89ee2fec9e765f0965d504fdfd5e80 Mon Sep 17 00:00:00 2001 From: ayomaska18 Date: Fri, 25 Oct 2024 20:09:44 +0100 Subject: [PATCH] added get Event price component --- app/page.tsx | 3 + components/sc/getEventPrice.tsx | 44 +++++++++++ contracts/EventManager.sol | 57 ++++++++++++++- lib/ethers.ts | 125 +++++++++++++++++++++++++++++++- 4 files changed, 223 insertions(+), 6 deletions(-) create mode 100644 components/sc/getEventPrice.tsx diff --git a/app/page.tsx b/app/page.tsx index 1d5d4aa..93c0a4c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,6 +1,7 @@ import Image from 'next/image'; import EventCounter from '@/components/sc/eventCounter'; import CreateEvent from '@/components/sc/createEvent'; +import GetEventPrice from '@/components/sc/getEventPrice'; export default function Home() { return ( @@ -29,6 +30,8 @@ export default function Home() { + +
{ + const [eventId, setEventId] = useState(null); + const [priceInFlr, setPriceInFlr] = useState(null); + + const handleGetPrice = async () => { + try { + if (eventId === null) return; + + const contract = getContract(); + const flrPrice = await contract.getEventPriceFlare(eventId); + setPriceInFlr(ethers.utils.formatEther(flrPrice.toString())); + } catch (error) { + console.error('Error fetching event price:', error); + } + }; + + return ( +
+

Get Event Price in FLR

+ setEventId(Number(e.target.value))} + className="border p-2 mb-2" + /> + + {priceInFlr &&

Event Price in FLR: {priceInFlr}

} +
+ ); +}; + +export default GetEventPrice; diff --git a/contracts/EventManager.sol b/contracts/EventManager.sol index 886e6b6..11ae5bb 100644 --- a/contracts/EventManager.sol +++ b/contracts/EventManager.sol @@ -2,14 +2,30 @@ pragma solidity >=0.8.2 <0.9.0; +import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol"; +/* THIS IS A TEST IMPORT, in production use: import {FtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/FtsoV2Interface.sol"; */ +import {TestFtsoV2Interface} from "@flarenetwork/flare-periphery-contracts/coston2/TestFtsoV2Interface.sol"; + contract EventManager { + TestFtsoV2Interface internal ftsoV2; + bytes21[] public feedIds = [ + bytes21(0x01464c522f55534400000000000000000000000000) // FLR/USD + // bytes21(0x014254432f55534400000000000000000000000000), // BTC/USD + // bytes21(0x014554482f55534400000000000000000000000000) // ETH/USD + ]; + + constructor() { + /* THIS IS A TEST METHOD, in production use: ftsoV2 = ContractRegistry.getFtsoV2(); */ + ftsoV2 = ContractRegistry.getTestFtsoV2(); + } + struct Event { string name; string description; uint256 capacity; uint256 ticketsSold; - uint256 ticketPrice; // in USD + uint256 ticketPrice; // in USD cents uint256 eventDate; string[] images; // array of image URLs uint256[] tickets; @@ -32,8 +48,41 @@ contract EventManager { uint256 public eventCounter; uint256 public ticketCounter; - function getTicketPrice() public view returns (uint256) { - // TODO: to be implemented + function getFtsoV2CurrentFeedValues() public view returns ( + uint256[] memory _feedValues, + int8[] memory _decimals, + uint64 _timestamp + ) { + return ftsoV2.getFeedsById(feedIds); + } + + function getFlareFeed() public view returns (uint256 _feedValue, int8 _decimals, uint64 _timestamp) { + uint256[] memory feedValues; + int8[] memory decimals; + uint64 timestamp; + (feedValues, decimals, timestamp) = ftsoV2.getFeedsById(feedIds); + return (feedValues[0], decimals[0], timestamp); + } + + function centsToFlare(uint256 _cents) public view returns (uint256 _flr) { + uint256 feedValue; + int8 decimals; + (feedValue, decimals, ) = getFlareFeed(); + return _cents * power(10, decimals) * 1 ether / 100 / feedValue; + } + + function power(uint base, int8 exponent) public pure returns (uint) { + require(exponent >= 0, "Exponent must be non-negative"); + uint result = 1; + for (int8 i = 0; i < exponent; i++) { + result *= base; + } + return result; + } + + function getEventPriceFlare(uint256 _eventId) public view returns (uint256 _flr) { + require(_eventId < eventCounter, "Invalid event ID"); + return centsToFlare(events[_eventId].ticketPrice); } function createEvent(string memory _name, string memory _description, uint256 _capacity, uint256 _ticketPrice, uint256 _eventDate, string[] memory _images) public { @@ -42,10 +91,12 @@ contract EventManager { } function getEventImages(uint256 _eventId) public view returns (string[] memory) { + require(_eventId < eventCounter, "Invalid event ID"); return events[_eventId].images; } function getEventTickets(uint256 _eventId) public view returns (uint256[] memory) { + require(_eventId < eventCounter, "Invalid event ID"); return events[_eventId].tickets; } diff --git a/lib/ethers.ts b/lib/ethers.ts index b655ba2..bc08861 100644 --- a/lib/ethers.ts +++ b/lib/ethers.ts @@ -2,7 +2,7 @@ import { ethers } from 'ethers'; const FLARE_TESTNET_RPC_URL = 'https://coston2.enosys.global/ext/C/rpc'; -const CONTRACT_ADDRESS = '0xc84C08D4BAd1f43FF053ba590d990E495A64FCd8'; +const CONTRACT_ADDRESS = '0x0B236423274D36C32fb2362cc177756a21A025A3'; export function getFlareProvider() { const flareRpcUrl = FLARE_TESTNET_RPC_URL; @@ -106,6 +106,30 @@ export function getContract() { stateMutability: 'nonpayable', type: 'function', }, + { + inputs: [], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_cents', + type: 'uint256', + }, + ], + name: 'centsToFlare', + outputs: [ + { + internalType: 'uint256', + name: '_flr', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [], name: 'eventCounter', @@ -168,6 +192,25 @@ export function getContract() { stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256', + }, + ], + name: 'feedIds', + outputs: [ + { + internalType: 'bytes21', + name: '', + type: 'bytes21', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [ { @@ -187,6 +230,25 @@ export function getContract() { stateMutability: 'view', type: 'function', }, + { + inputs: [ + { + internalType: 'uint256', + name: '_eventId', + type: 'uint256', + }, + ], + name: 'getEventPriceFlare', + outputs: [ + { + internalType: 'uint256', + name: '_flr', + type: 'uint256', + }, + ], + stateMutability: 'view', + type: 'function', + }, { inputs: [ { @@ -208,7 +270,64 @@ export function getContract() { }, { inputs: [], - name: 'getTicketPrice', + name: 'getFlareFeed', + outputs: [ + { + internalType: 'uint256', + name: '_feedValue', + type: 'uint256', + }, + { + internalType: 'int8', + name: '_decimals', + type: 'int8', + }, + { + internalType: 'uint64', + name: '_timestamp', + type: 'uint64', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'getFtsoV2CurrentFeedValues', + outputs: [ + { + internalType: 'uint256[]', + name: '_feedValues', + type: 'uint256[]', + }, + { + internalType: 'int8[]', + name: '_decimals', + type: 'int8[]', + }, + { + internalType: 'uint64', + name: '_timestamp', + type: 'uint64', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + internalType: 'uint256', + name: 'base', + type: 'uint256', + }, + { + internalType: 'int8', + name: 'exponent', + type: 'int8', + }, + ], + name: 'power', outputs: [ { internalType: 'uint256', @@ -216,7 +335,7 @@ export function getContract() { type: 'uint256', }, ], - stateMutability: 'view', + stateMutability: 'pure', type: 'function', }, {