Skip to content

Instantly share code, notes, and snippets.

@Daltonic
Created August 25, 2022 10:43

Revisions

  1. Daltonic created this gist Aug 25, 2022.
    271 changes: 271 additions & 0 deletions Genesis.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,271 @@
    import abi from './abis/src/contracts/Genesis.sol/Genesis.json'
    import address from './abis/contractAddress.json'
    import { getGlobalState, setGlobalState } from './store'
    import { ethers } from 'ethers'
    import { logOutWithCometChat } from './CometChat'

    const { ethereum } = window
    const contractAddress = address.address
    const contractAbi = abi.abi

    const getEtheriumContract = () => {
    const connectedAccount = getGlobalState('connectedAccount')

    if (connectedAccount) {
    const provider = new ethers.providers.Web3Provider(ethereum)
    const signer = provider.getSigner()
    const contract = new ethers.Contract(contractAddress, contractAbi, signer)

    return contract
    } else {
    return getGlobalState('contract')
    }
    }

    const isWallectConnected = async () => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const accounts = await ethereum.request({ method: 'eth_accounts' })

    window.ethereum.on('chainChanged', (chainId) => {
    window.location.reload()
    })

    window.ethereum.on('accountsChanged', async () => {
    setGlobalState('connectedAccount', accounts[0])
    await logOutWithCometChat()
    await isWallectConnected()
    })

    if (accounts.length) {
    setGlobalState('connectedAccount', accounts[0])
    } else {
    alert('Please connect wallet.')
    console.log('No accounts found.')
    }
    } catch (error) {
    reportError(error)
    }
    }

    const connectWallet = async () => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const accounts = await ethereum.request({ method: 'eth_requestAccounts' })
    setGlobalState('connectedAccount', accounts[0])
    } catch (error) {
    reportError(error)
    }
    }

    const createProject = async ({
    title,
    description,
    imageURL,
    cost,
    expiresAt,
    }) => {
    try {
    if (!ethereum) return alert('Please install Metamask')

    const contract = getEtheriumContract()
    cost = ethers.utils.parseEther(cost)
    await contract.createProject(title, description, imageURL, cost, expiresAt)

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const updateProject = async ({
    id,
    title,
    description,
    imageURL,
    expiresAt,
    }) => {
    try {
    if (!ethereum) return alert('Please install Metamask')

    const contract = getEtheriumContract()
    await contract.updateProject(id, title, description, imageURL, expiresAt)

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const backProject = async (id, amount) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const connectedAccount = getGlobalState('connectedAccount')
    const contract = getEtheriumContract()
    amount = ethers.utils.parseEther(amount)

    await contract.backProject(id, {
    from: connectedAccount,
    value: amount._hex,
    })

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const refundProject = async (id) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const connectedAccount = getGlobalState('connectedAccount')
    const contract = getEtheriumContract()

    await contract.requestRefund(id, {
    from: connectedAccount,
    })

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const payoutProject = async (id) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const connectedAccount = getGlobalState('connectedAccount')
    const contract = getEtheriumContract()

    await contract.payOutProject(id, {
    from: connectedAccount,
    })

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const getBackers = async (id) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const contract = getEtheriumContract()
    let backers = await contract.getBackers(id)

    setGlobalState('backers', structuredBackers(backers))
    } catch (error) {
    reportError(error)
    }
    }

    const deleteProject = async (id) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const contract = getEtheriumContract()
    await contract.deleteProject(id)

    await loadProjects() // The blockchain is too slow for this...
    window.location.reload() // That's why we used this...
    } catch (error) {
    reportError(error)
    }
    }

    const loadProject = async (id) => {
    try {
    if (!ethereum) return alert('Please install Metamask')
    const contract = getEtheriumContract()
    let project = await contract.getProject(id)
    project = structuredProjects([project])[0]

    setGlobalState('project', project)
    await getBackers(id)
    console.log("Project Loaded...")
    } catch (error) {
    alert(JSON.stringify(error.message))
    reportError(error)
    }
    }

    const loadProjects = async () => {
    try {
    if (!ethereum) return alert('Please install Metamask')

    const contract = getEtheriumContract()
    const projects = await contract.getProjects()
    const stats = await contract.stats()

    setGlobalState('stats', structureStats(stats))
    setGlobalState('projects', structuredProjects(projects))
    } catch (error) {
    reportError(error)
    }
    }

    const structuredBackers = (backers) =>
    backers
    .map((backer) => ({
    owner: backer.owner,
    refunded: backer.refunded,
    timestamp: new Date(backer.timestamp.toNumber() * 1000).toJSON(),
    contribution: parseInt(backer.contribution._hex) / 10 ** 18,
    }))
    .reverse()

    const structuredProjects = (projects) =>
    projects
    .map((project) => ({
    id: project.id.toNumber(),
    owner: project.owner,
    title: project.title,
    description: project.description,
    timestamp: new Date(project.timestamp.toNumber()).getTime(),
    expiresAt: new Date(project.expiresAt.toNumber()).getTime(),
    date: toDate(project.expiresAt.toNumber() * 1000),
    imageURL: project.imageURL,
    raised: parseInt(project.raised._hex) / 10 ** 18,
    cost: parseInt(project.cost._hex) / 10 ** 18,
    backers: project.backers.toNumber(),
    status: project.status,
    }))
    .reverse()

    const toDate = (timestamp) => {
    const date = new Date(timestamp)
    const dd = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`
    const mm =
    date.getMonth() + 1 > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`
    const yyyy = date.getFullYear()
    return `${yyyy}-${mm}-${dd}`
    }

    const structureStats = (stats) => ({
    totalProjects: stats.totalProjects.toNumber(),
    totalBacking: stats.totalBacking.toNumber(),
    totalDonations: parseInt(stats.totalDonations._hex) / 10 ** 18,
    })

    const reportError = (error) => {
    console.log(error.message)
    throw new Error('No ethereum object.')
    }

    export {
    getEtheriumContract,
    isWallectConnected,
    connectWallet,
    createProject,
    updateProject,
    deleteProject,
    loadProjects,
    loadProject,
    backProject,
    payoutProject,
    refundProject,
    }