Skip to content

Instantly share code, notes, and snippets.

@Daltonic
Created September 1, 2023 11:41
Show Gist options
  • Save Daltonic/8bcedf4d66664a3218de5260b572a80c to your computer and use it in GitHub Desktop.
Save Daltonic/8bcedf4d66664a3218de5260b572a80c to your computer and use it in GitHub Desktop.
Dapp Votes
import { store } from '@/store'
import { ethers } from 'ethers'
import { globalActions } from '@/store/globalSlices'
import address from '@/artifacts/contractAddress.json'
import abi from '@/artifacts/contracts/DappVotes.sol/DappVotes.json'
import { ContestantStruct, PollParams, PollStruct, TruncateParams } from '@/utils/types'
import { logOutWithCometChat } from './chat'
const { setWallet, setPolls, setPoll, setContestants, setCurrentUser } = globalActions
const ContractAddress = address.address
const ContractAbi = abi.abi
let ethereum: any
let tx: any
if (typeof window !== 'undefined') {
ethereum = (window as any).ethereum
}
const getEthereumContract = async () => {
const accounts = await ethereum?.request?.({ method: 'eth_accounts' })
const provider = accounts?.[0]
? new ethers.providers.Web3Provider(ethereum)
: new ethers.providers.JsonRpcProvider(process.env.NEXT_APP_RPC_URL)
const wallet = accounts?.[0] ? null : ethers.Wallet.createRandom()
const signer = provider.getSigner(accounts?.[0] ? undefined : wallet?.address)
const contract = new ethers.Contract(ContractAddress, ContractAbi, signer)
return contract
}
const connectWallet = async () => {
try {
if (!ethereum) return reportError('Please install Metamask')
const accounts = await ethereum.request?.({ method: 'eth_requestAccounts' })
store.dispatch(setWallet(accounts?.[0]))
} catch (error) {
reportError(error)
}
}
const checkWallet = async () => {
try {
if (!ethereum) return reportError('Please install Metamask')
const accounts = await ethereum.request?.({ method: 'eth_accounts' })
ethereum.on('chainChanged', () => {
window.location.reload()
})
ethereum.on('accountsChanged', async () => {
store.dispatch(setWallet(accounts?.[0]))
await checkWallet()
await logOutWithCometChat()
store.dispatch(setCurrentUser(null))
})
if (accounts?.length) {
store.dispatch(setWallet(accounts[0]))
} else {
store.dispatch(setWallet(''))
reportError('Please connect wallet, no accounts found.')
}
} catch (error) {
reportError(error)
}
}
const createPoll = async (data: PollParams) => {
if (!ethereum) {
reportError('Please install Metamask')
return Promise.reject(new Error('Metamask not installed'))
}
try {
const contract = await getEthereumContract()
const { image, title, description, startsAt, endsAt } = data
const tx = await contract.createPoll(image, title, description, startsAt, endsAt)
await tx.wait()
const polls = await getPolls()
store.dispatch(setPolls(polls))
return Promise.resolve(tx)
} catch (error) {
reportError(error)
return Promise.reject(error)
}
}
const updatePoll = async (id: number, data: PollParams) => {
if (!ethereum) {
reportError('Please install Metamask')
return Promise.reject(new Error('Metamask not installed'))
}
try {
const contract = await getEthereumContract()
const { image, title, description, startsAt, endsAt } = data
const tx = await contract.updatePoll(id, image, title, description, startsAt, endsAt)
await tx.wait()
const poll = await getPoll(id)
store.dispatch(setPoll(poll))
return Promise.resolve(tx)
} catch (error) {
reportError(error)
return Promise.reject(error)
}
}
const deletePoll = async (id: number) => {
if (!ethereum) {
reportError('Please install Metamask')
return Promise.reject(new Error('Metamask not installed'))
}
try {
const contract = await getEthereumContract()
const tx = await contract.deletePoll(id)
await tx.wait()
return Promise.resolve(tx)
} catch (error) {
reportError(error)
return Promise.reject(error)
}
}
const contestPoll = async (id: number, name: string, image: string) => {
if (!ethereum) {
reportError('Please install Metamask')
return Promise.reject(new Error('Metamask not installed'))
}
try {
const contract = await getEthereumContract()
const tx = await contract.contest(id, name, image)
await tx.wait()
const poll = await getPoll(id)
store.dispatch(setPoll(poll))
const contestants = await getContestants(id)
store.dispatch(setContestants(contestants))
return Promise.resolve(tx)
} catch (error) {
reportError(error)
return Promise.reject(error)
}
}
const voteCandidate = async (id: number, cid: number) => {
if (!ethereum) {
reportError('Please install Metamask')
return Promise.reject(new Error('Metamask not installed'))
}
try {
const contract = await getEthereumContract()
const tx = await contract.vote(id, cid)
await tx.wait()
const poll = await getPoll(id)
store.dispatch(setPoll(poll))
const contestants = await getContestants(id)
store.dispatch(setContestants(contestants))
return Promise.resolve(tx)
} catch (error) {
reportError(error)
return Promise.reject(error)
}
}
const getPolls = async (): Promise<PollStruct[]> => {
const contract = await getEthereumContract()
const polls = await contract.getPolls()
return structurePolls(polls)
}
const getPoll = async (id: number): Promise<PollStruct> => {
const contract = await getEthereumContract()
const polls = await contract.getPoll(id)
return structurePolls([polls])[0]
}
const getContestants = async (id: number): Promise<ContestantStruct[]> => {
const contract = await getEthereumContract()
const contestants = await contract.getContestants(id)
return structureContestants(contestants)
}
const truncate = ({ text, startChars, endChars, maxLength }: TruncateParams): string => {
if (text.length > maxLength) {
let start = text.substring(0, startChars)
let end = text.substring(text.length - endChars, text.length)
while (start.length + end.length < maxLength) {
start = start + '.'
}
return start + end
}
return text
}
const formatDate = (timestamp: number): string => {
const date = new Date(timestamp)
const daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
const months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
]
const dayOfWeek = daysOfWeek[date.getUTCDay()]
const month = months[date.getUTCMonth()]
const day = date.getUTCDate()
const year = date.getUTCFullYear()
return `${dayOfWeek}, ${month} ${day}, ${year}`
}
const formatTimestamp = (timestamp: number) => {
const date = new Date(timestamp)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
return `${year}-${month}-${day}T${hours}:${minutes}`
}
const structurePolls = (polls: any[]): PollStruct[] =>
polls
.map((poll) => ({
id: Number(poll.id),
image: poll.image,
title: poll.title,
description: poll.description,
votes: Number(poll.votes),
contestants: Number(poll.contestants),
deleted: poll.deleted,
director: poll.director.toLowerCase(),
startsAt: Number(poll.startsAt),
endsAt: Number(poll.endsAt),
timestamp: Number(poll.timestamp),
voters: poll.voters.map((voter: string) => voter.toLowerCase()),
avatars: poll.avatars,
}))
.sort((a, b) => b.timestamp - a.timestamp)
const structureContestants = (contestants: any[]): ContestantStruct[] =>
contestants
.map((contestant) => ({
id: Number(contestant.id),
image: contestant.image,
name: contestant.name,
voter: contestant.voter.toLowerCase(),
votes: Number(contestant.votes),
voters: contestant.voters.map((voter: string) => voter.toLowerCase()),
}))
.sort((a, b) => b.votes - a.votes)
export {
connectWallet,
checkWallet,
truncate,
formatDate,
formatTimestamp,
createPoll,
updatePoll,
deletePoll,
getPolls,
getPoll,
contestPoll,
getContestants,
voteCandidate,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment