-
-
Save Daltonic/8bcedf4d66664a3218de5260b572a80c to your computer and use it in GitHub Desktop.
Dapp Votes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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