Introduce subgraph (#176)

This commit is contained in:
Szymon Szlachtowicz 2021-08-02 13:42:11 +02:00 committed by GitHub
parent c7ce5544cf
commit 0dfeb056a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 4040 additions and 70 deletions

View File

@ -32,8 +32,6 @@ export const CardCommunity = ({
const [showRemoveModal, setShowRemoveModal] = useState(false)
const [showConfirmModal, setShowConfirmModal] = useState(false)
const isDisabled = community.votingHistory.length === 0
const setNewModal = (val: boolean) => {
setShowConfirmModal(val)
setShowRemoveModal(false)
@ -48,6 +46,7 @@ export const CardCommunity = ({
setShowRemoveModal(true)
}
}, [])
const isDisabled = community.votingHistory.length === 0
return (
<CardCommunityBlock className={customStyle ? 'notModal' : ''}>

View File

@ -15,6 +15,48 @@ import { BigNumber } from 'ethers'
import { useProposeWarning } from '../../hooks/useProposeWarning'
import { PublicKeyInput } from '../PublicKeyInput'
interface ProposeBlockProps {
setShowConfirmModal: (val: boolean) => void
communityFound: CommunityDetail
send: (...args: any[]) => void
}
function ProposeBlock({ setShowConfirmModal, communityFound, send }: ProposeBlockProps) {
const [proposingAmount, setProposingAmount] = useState(0)
const warning = useProposeWarning(communityFound)
return (
<div>
<ProposingData>
<CardCommunity community={communityFound} />
<WarningWrap>{warning.text && <Warning icon={warning.icon} text={warning.text} />}</WarningWrap>
{communityFound.validForAddition && (
<VoteProposeWrap>
<VotePropose
setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount}
disabled={!communityFound}
/>
</VoteProposeWrap>
)}
</ProposingData>
{!communityFound.validForAddition ? (
<ConfirmBtn onClick={() => setShowConfirmModal(false)}>
OK, lets move on! <span>🤙</span>
</ConfirmBtn>
) : (
<ProposingBtn
disabled={!proposingAmount || !!warning.text}
onClick={() => send(1, communityFound.publicKey, BigNumber.from(proposingAmount))}
>
Confirm vote to add community
</ProposingBtn>
)}
</div>
)
}
interface ProposeModalProps {
setShowConfirmModal: (val: boolean) => void
setCommunityFound: (community: CommunityDetail | undefined) => void
@ -22,14 +64,11 @@ interface ProposeModalProps {
}
export function ProposeModal({ setShowConfirmModal, setCommunityFound, communityFound }: ProposeModalProps) {
const [proposingAmount, setProposingAmount] = useState(0)
const [publicKey, setPublicKey] = useState('')
const loading = useCommunityDetails(publicKey, setCommunityFound)
const { votingContract } = useContracts()
const { send, state } = useContractFunction(votingContract, 'initializeVotingRoom')
const warning = useProposeWarning(communityFound)
useEffect(() => {
if (state.status === 'Mining') {
setShowConfirmModal(true)
@ -42,37 +81,21 @@ export function ProposeModal({ setShowConfirmModal, setCommunityFound, community
<PublicKeyInput publicKey={publicKey} setPublicKey={setPublicKey} />
</WrapperBottomMid>
<ProposingData>
{communityFound ? <CardCommunity community={communityFound} /> : loading && publicKey && <CommunitySkeleton />}
<WarningWrap>{warning.text && <Warning icon={warning.icon} text={warning.text} />}</WarningWrap>
{communityFound && communityFound.validForAddition && publicKey && (
<VoteProposeWrap>
<VotePropose
setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount}
disabled={!communityFound}
/>
</VoteProposeWrap>
)}
{!publicKey && (
<ProposingInfo>
<span></span>
<InfoText>To propose a community, it must have at least 42 members and have a ENS domain.</InfoText>
</ProposingInfo>
)}
</ProposingData>
{communityFound && !communityFound.validForAddition ? (
<ConfirmBtn onClick={() => setShowConfirmModal(false)}>
OK, lets move on! <span>🤙</span>
</ConfirmBtn>
{communityFound ? (
<ProposeBlock communityFound={communityFound} send={send} setShowConfirmModal={setShowConfirmModal} />
) : (
<ProposingBtn
disabled={!communityFound || !proposingAmount || !!warning.text}
onClick={() => send(1, publicKey, BigNumber.from(proposingAmount))}
>
Confirm vote to add community
</ProposingBtn>
<>
<ProposingData>
{!publicKey && (
<ProposingInfo>
<span></span>
<InfoText>To propose a community, it must have at least 42 members and have a ENS domain.</InfoText>
</ProposingInfo>
)}
{loading && publicKey && <CommunitySkeleton />}
</ProposingData>
<ProposingBtn disabled={true}>Confirm vote to add community</ProposingBtn>
</>
)}
</ColumnFlexDiv>
)

View File

@ -24,6 +24,42 @@ import { ConnectMobile } from './ConnectMobile'
import { InfoText, ProposingInfo, VoteProposeWrap, WarningWrap } from '../components/card/ProposeModal'
import { HistoryLink } from './CardVoteMobile'
interface ProposeBlockProps {
communityFound: CommunityDetail
proposingAmount: number
setProposingAmount: (amount: number) => void
send: (...args: any) => void
}
function ProposeBlock({ communityFound, proposingAmount, setProposingAmount, send }: ProposeBlockProps) {
const warning = useProposeWarning(communityFound)
return (
<>
<MobileBlock>
<WarningWrap>{warning.text && <Warning icon={warning.icon} text={warning.text} />}</WarningWrap>
{communityFound.validForAddition && (
<VoteProposeWrap>
<ProposingHeadingMobile>{` Add ${communityFound.name}?`}</ProposingHeadingMobile>
<VotePropose
setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount}
disabled={!communityFound}
/>
</VoteProposeWrap>
)}
</MobileBlock>
{communityFound.validForAddition && (
<ProposingBtn
disabled={!communityFound || !proposingAmount || !!warning.text}
onClick={() => send(1, communityFound.publicKey, BigNumber.from(proposingAmount))}
>
Confirm vote to add community
</ProposingBtn>
)}
</>
)
}
export function ProposeMobile() {
const [proposingAmount, setProposingAmount] = useState(0)
const [communityFound, setCommunityFound] = useState<CommunityDetail | undefined>(undefined)
@ -32,8 +68,6 @@ export function ProposeMobile() {
const { votingContract } = useContracts()
const { send } = useContractFunction(votingContract, 'initializeVotingRoom')
const warning = useProposeWarning(communityFound)
const [showHistory, setShowHistory] = useState(false)
const isDisabled = communityFound ? communityFound.votingHistory.length === 0 : false
@ -59,32 +93,22 @@ export function ProposeMobile() {
</MobileTop>
</HeaderVotingMobile>
<MobileBlock>
<WarningWrap>{warning.text && <Warning icon={warning.icon} text={warning.text} />}</WarningWrap>
{communityFound && communityFound.validForAddition && publicKey && (
<VoteProposeWrap>
<ProposingHeadingMobile>{` Add ${communityFound.name}?`}</ProposingHeadingMobile>
<VotePropose
setProposingAmount={setProposingAmount}
proposingAmount={proposingAmount}
disabled={!communityFound}
/>
</VoteProposeWrap>
)}
{!publicKey && (
{!publicKey && (
<MobileBlock>
<ProposingInfo>
<span></span>
<InfoText>To propose a community, it must have at least 42 members and have a ENS domain.</InfoText>
</ProposingInfo>
)}
</MobileBlock>
{communityFound && communityFound.validForAddition && (
<ProposingBtn
disabled={!communityFound || !proposingAmount || !!warning.text}
onClick={() => send(1, publicKey, BigNumber.from(proposingAmount))}
>
Confirm vote to add community
</ProposingBtn>
</MobileBlock>
)}
{communityFound && (
<ProposeBlock
communityFound={communityFound}
proposingAmount={proposingAmount}
send={send}
setProposingAmount={setProposingAmount}
/>
)}
<HistoryWrap>
{!isDisabled && communityFound && (

View File

@ -4,13 +4,59 @@ import { useWakuFeature } from '../providers/wakuFeature/provider'
import { BigNumber } from 'ethers'
import { CommunityDetail } from '../models/community'
import { useEffect, useState } from 'react'
import { useConfig } from '../providers/config'
import { useEthers } from '@usedapp/core'
export function useCommunities(publicKeys: string[]) {
const { communitiesDetails, dispatch } = useCommunitiesProvider()
const { featureVotes } = useWakuFeature()
const { config } = useConfig()
const { chainId } = useEthers()
const [returnCommunities, setReturnCommunities] = useState<(CommunityDetail | undefined)[]>([])
useEffect(() => {
publicKeys.forEach((publicKey) => {
if (publicKey) {
const setCommunity = async () => {
const communityDetail = await getCommunityDetails(publicKey)
if (communityDetail) {
try {
const response = await fetch(config.contracts?.[chainId ?? 3]?.subgraph, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
query: `{votingRooms(where:{community: "${publicKey}"}){id,result,type,community,timestamp}}`,
}),
})
const votingRooms = (await response.json())?.data?.votingRooms.sort((a: any, b: any) =>
a.timestamp > b.timestamp ? 1 : -1
)
if (votingRooms && votingRooms.length > 0) {
const votingHistory = votingRooms.map((room: any) => {
return {
ID: parseInt(room.id),
type: room.type === 1 ? 'Add' : 'Remove',
result: room.result ? 'Passed' : 'Failed',
date: new Date(Number.parseInt(room.timestamp) * 1000),
}
})
dispatch({ ...communityDetail, votingHistory })
} else {
dispatch({ ...communityDetail, votingHistory: [] })
}
} catch {
dispatch({ ...communityDetail, votingHistory: [] })
}
}
}
setCommunity()
}
})
}, [JSON.stringify(publicKeys)])
useEffect(() => {
setReturnCommunities(
publicKeys.map((publicKey) => {
@ -22,15 +68,6 @@ export function useCommunities(publicKeys: string[]) {
return { ...detail, featureVotes: BigNumber.from(0) }
}
} else {
if (publicKey) {
const setCommunity = async () => {
const communityDetail = await getCommunityDetails(publicKey)
if (communityDetail) {
dispatch(communityDetail)
}
}
setCommunity()
}
return undefined
}
})

View File

@ -4,7 +4,7 @@ import { CommunityDetail } from '../models/community'
import { useAvailableAmount } from './useAvailableAmount'
import { useContracts } from './useContracts'
export function useProposeWarning(communityFound: CommunityDetail | undefined) {
export function useProposeWarning(communityFound: CommunityDetail) {
const availableAmount = useAvailableAmount()
const [warning, setWarning] = useState({ icon: '', text: '' })

View File

@ -17,11 +17,13 @@ interface EnvConfigs {
const contracts = {
3: {
subgraph: '',
votingContract: '0xF6fb0EBfa21958440e2AA8ee603DFDc885C4F694',
directoryContract: '0x56dF4644483Dbb5607d0eB162Aa64536bD5c2C24',
tokenContract: '0x80ee48b5ba5c3EA556b7fF6D850d2fB2c4bc7412',
},
1337: {
subgraph: 'http://localhost:8000/subgraphs/name/HistorySubgraph',
votingContract: process.env.GANACHE_VOTING_CONTRACT ?? '0x0000000000000000000000000000000000000000',
directoryContract: process.env.GANACHE_DIRECTORY_CONTRACT ?? '0x0000000000000000000000000000000000000000',
tokenContract: process.env.GANACHE_TOKEN_CONTRACT ?? '0x0000000000000000000000000000000000000000',

View File

@ -0,0 +1,233 @@
[
{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "roomId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "voter",
"type": "address"
}
],
"name": "VoteCast",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "roomId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "publicKey",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "passed",
"type": "bool"
},
{
"indexed": false,
"internalType": "enum VotingContract.VoteType",
"name": "voteType",
"type": "uint8"
}
],
"name": "VotingRoomFinalized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "roomId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "publicKey",
"type": "address"
}
],
"name": "VotingRoomStarted",
"type": "event"
},
{
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "activeVotingRooms",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{ "internalType": "address", "name": "voter", "type": "address" },
{
"internalType": "uint256",
"name": "roomIdAndType",
"type": "uint256"
},
{ "internalType": "uint256", "name": "sntAmount", "type": "uint256" },
{ "internalType": "bytes32", "name": "r", "type": "bytes32" },
{ "internalType": "bytes32", "name": "vs", "type": "bytes32" }
],
"internalType": "struct VotingContract.SignedVote[]",
"name": "votes",
"type": "tuple[]"
}
],
"name": "castVotes",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "address", "name": "", "type": "address" }],
"name": "communityVotingId",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "directory",
"outputs": [
{ "internalType": "contract Directory", "name": "", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "roomId", "type": "uint256" }
],
"name": "finalizeVotingRoom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getActiveVotingRooms",
"outputs": [
{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "publicKey", "type": "address" }
],
"name": "getCommunityVoting",
"outputs": [
{ "internalType": "uint256", "name": "startBlock", "type": "uint256" },
{ "internalType": "uint256", "name": "endAt", "type": "uint256" },
{
"internalType": "enum VotingContract.VoteType",
"name": "voteType",
"type": "uint8"
},
{ "internalType": "bool", "name": "finalized", "type": "bool" },
{ "internalType": "address", "name": "community", "type": "address" },
{ "internalType": "uint256", "name": "totalVotesFor", "type": "uint256" },
{
"internalType": "uint256",
"name": "totalVotesAgainst",
"type": "uint256"
},
{ "internalType": "uint256", "name": "roomNumber", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "enum VotingContract.VoteType",
"name": "voteType",
"type": "uint8"
},
{ "internalType": "address", "name": "publicKey", "type": "address" },
{ "internalType": "uint256", "name": "voteAmount", "type": "uint256" }
],
"name": "initializeVotingRoom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "roomId", "type": "uint256" }
],
"name": "listRoomVoters",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "contract Directory",
"name": "_address",
"type": "address"
}
],
"name": "setDirectory",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"name": "votingRoomMap",
"outputs": [
{ "internalType": "uint256", "name": "startBlock", "type": "uint256" },
{ "internalType": "uint256", "name": "endAt", "type": "uint256" },
{
"internalType": "enum VotingContract.VoteType",
"name": "voteType",
"type": "uint8"
},
{ "internalType": "bool", "name": "finalized", "type": "bool" },
{ "internalType": "address", "name": "community", "type": "address" },
{ "internalType": "uint256", "name": "totalVotesFor", "type": "uint256" },
{
"internalType": "uint256",
"name": "totalVotesAgainst",
"type": "uint256"
},
{ "internalType": "uint256", "name": "roomNumber", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,577 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
import {
ethereum,
JSONValue,
TypedMap,
Entity,
Bytes,
Address,
BigInt
} from "@graphprotocol/graph-ts";
export class VoteCast extends ethereum.Event {
get params(): VoteCast__Params {
return new VoteCast__Params(this);
}
}
export class VoteCast__Params {
_event: VoteCast;
constructor(event: VoteCast) {
this._event = event;
}
get roomId(): BigInt {
return this._event.parameters[0].value.toBigInt();
}
get voter(): Address {
return this._event.parameters[1].value.toAddress();
}
}
export class VotingRoomFinalized extends ethereum.Event {
get params(): VotingRoomFinalized__Params {
return new VotingRoomFinalized__Params(this);
}
}
export class VotingRoomFinalized__Params {
_event: VotingRoomFinalized;
constructor(event: VotingRoomFinalized) {
this._event = event;
}
get roomId(): BigInt {
return this._event.parameters[0].value.toBigInt();
}
get publicKey(): Address {
return this._event.parameters[1].value.toAddress();
}
get passed(): boolean {
return this._event.parameters[2].value.toBoolean();
}
get voteType(): i32 {
return this._event.parameters[3].value.toI32();
}
}
export class VotingRoomStarted extends ethereum.Event {
get params(): VotingRoomStarted__Params {
return new VotingRoomStarted__Params(this);
}
}
export class VotingRoomStarted__Params {
_event: VotingRoomStarted;
constructor(event: VotingRoomStarted) {
this._event = event;
}
get roomId(): BigInt {
return this._event.parameters[0].value.toBigInt();
}
get publicKey(): Address {
return this._event.parameters[1].value.toAddress();
}
}
export class VotingContract__getCommunityVotingResult {
value0: BigInt;
value1: BigInt;
value2: i32;
value3: boolean;
value4: Address;
value5: BigInt;
value6: BigInt;
value7: BigInt;
constructor(
value0: BigInt,
value1: BigInt,
value2: i32,
value3: boolean,
value4: Address,
value5: BigInt,
value6: BigInt,
value7: BigInt
) {
this.value0 = value0;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
this.value5 = value5;
this.value6 = value6;
this.value7 = value7;
}
toMap(): TypedMap<string, ethereum.Value> {
let map = new TypedMap<string, ethereum.Value>();
map.set("value0", ethereum.Value.fromUnsignedBigInt(this.value0));
map.set("value1", ethereum.Value.fromUnsignedBigInt(this.value1));
map.set(
"value2",
ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(this.value2))
);
map.set("value3", ethereum.Value.fromBoolean(this.value3));
map.set("value4", ethereum.Value.fromAddress(this.value4));
map.set("value5", ethereum.Value.fromUnsignedBigInt(this.value5));
map.set("value6", ethereum.Value.fromUnsignedBigInt(this.value6));
map.set("value7", ethereum.Value.fromUnsignedBigInt(this.value7));
return map;
}
}
export class VotingContract__votingRoomMapResult {
value0: BigInt;
value1: BigInt;
value2: i32;
value3: boolean;
value4: Address;
value5: BigInt;
value6: BigInt;
value7: BigInt;
constructor(
value0: BigInt,
value1: BigInt,
value2: i32,
value3: boolean,
value4: Address,
value5: BigInt,
value6: BigInt,
value7: BigInt
) {
this.value0 = value0;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
this.value5 = value5;
this.value6 = value6;
this.value7 = value7;
}
toMap(): TypedMap<string, ethereum.Value> {
let map = new TypedMap<string, ethereum.Value>();
map.set("value0", ethereum.Value.fromUnsignedBigInt(this.value0));
map.set("value1", ethereum.Value.fromUnsignedBigInt(this.value1));
map.set(
"value2",
ethereum.Value.fromUnsignedBigInt(BigInt.fromI32(this.value2))
);
map.set("value3", ethereum.Value.fromBoolean(this.value3));
map.set("value4", ethereum.Value.fromAddress(this.value4));
map.set("value5", ethereum.Value.fromUnsignedBigInt(this.value5));
map.set("value6", ethereum.Value.fromUnsignedBigInt(this.value6));
map.set("value7", ethereum.Value.fromUnsignedBigInt(this.value7));
return map;
}
}
export class VotingContract extends ethereum.SmartContract {
static bind(address: Address): VotingContract {
return new VotingContract("VotingContract", address);
}
activeVotingRooms(param0: BigInt): BigInt {
let result = super.call(
"activeVotingRooms",
"activeVotingRooms(uint256):(uint256)",
[ethereum.Value.fromUnsignedBigInt(param0)]
);
return result[0].toBigInt();
}
try_activeVotingRooms(param0: BigInt): ethereum.CallResult<BigInt> {
let result = super.tryCall(
"activeVotingRooms",
"activeVotingRooms(uint256):(uint256)",
[ethereum.Value.fromUnsignedBigInt(param0)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toBigInt());
}
communityVotingId(param0: Address): BigInt {
let result = super.call(
"communityVotingId",
"communityVotingId(address):(uint256)",
[ethereum.Value.fromAddress(param0)]
);
return result[0].toBigInt();
}
try_communityVotingId(param0: Address): ethereum.CallResult<BigInt> {
let result = super.tryCall(
"communityVotingId",
"communityVotingId(address):(uint256)",
[ethereum.Value.fromAddress(param0)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toBigInt());
}
directory(): Address {
let result = super.call("directory", "directory():(address)", []);
return result[0].toAddress();
}
try_directory(): ethereum.CallResult<Address> {
let result = super.tryCall("directory", "directory():(address)", []);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toAddress());
}
getActiveVotingRooms(): Array<BigInt> {
let result = super.call(
"getActiveVotingRooms",
"getActiveVotingRooms():(uint256[])",
[]
);
return result[0].toBigIntArray();
}
try_getActiveVotingRooms(): ethereum.CallResult<Array<BigInt>> {
let result = super.tryCall(
"getActiveVotingRooms",
"getActiveVotingRooms():(uint256[])",
[]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toBigIntArray());
}
getCommunityVoting(
publicKey: Address
): VotingContract__getCommunityVotingResult {
let result = super.call(
"getCommunityVoting",
"getCommunityVoting(address):(uint256,uint256,uint8,bool,address,uint256,uint256,uint256)",
[ethereum.Value.fromAddress(publicKey)]
);
return new VotingContract__getCommunityVotingResult(
result[0].toBigInt(),
result[1].toBigInt(),
result[2].toI32(),
result[3].toBoolean(),
result[4].toAddress(),
result[5].toBigInt(),
result[6].toBigInt(),
result[7].toBigInt()
);
}
try_getCommunityVoting(
publicKey: Address
): ethereum.CallResult<VotingContract__getCommunityVotingResult> {
let result = super.tryCall(
"getCommunityVoting",
"getCommunityVoting(address):(uint256,uint256,uint8,bool,address,uint256,uint256,uint256)",
[ethereum.Value.fromAddress(publicKey)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(
new VotingContract__getCommunityVotingResult(
value[0].toBigInt(),
value[1].toBigInt(),
value[2].toI32(),
value[3].toBoolean(),
value[4].toAddress(),
value[5].toBigInt(),
value[6].toBigInt(),
value[7].toBigInt()
)
);
}
listRoomVoters(roomId: BigInt): Array<Address> {
let result = super.call(
"listRoomVoters",
"listRoomVoters(uint256):(address[])",
[ethereum.Value.fromUnsignedBigInt(roomId)]
);
return result[0].toAddressArray();
}
try_listRoomVoters(roomId: BigInt): ethereum.CallResult<Array<Address>> {
let result = super.tryCall(
"listRoomVoters",
"listRoomVoters(uint256):(address[])",
[ethereum.Value.fromUnsignedBigInt(roomId)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toAddressArray());
}
owner(): Address {
let result = super.call("owner", "owner():(address)", []);
return result[0].toAddress();
}
try_owner(): ethereum.CallResult<Address> {
let result = super.tryCall("owner", "owner():(address)", []);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(value[0].toAddress());
}
votingRoomMap(param0: BigInt): VotingContract__votingRoomMapResult {
let result = super.call(
"votingRoomMap",
"votingRoomMap(uint256):(uint256,uint256,uint8,bool,address,uint256,uint256,uint256)",
[ethereum.Value.fromUnsignedBigInt(param0)]
);
return new VotingContract__votingRoomMapResult(
result[0].toBigInt(),
result[1].toBigInt(),
result[2].toI32(),
result[3].toBoolean(),
result[4].toAddress(),
result[5].toBigInt(),
result[6].toBigInt(),
result[7].toBigInt()
);
}
try_votingRoomMap(
param0: BigInt
): ethereum.CallResult<VotingContract__votingRoomMapResult> {
let result = super.tryCall(
"votingRoomMap",
"votingRoomMap(uint256):(uint256,uint256,uint8,bool,address,uint256,uint256,uint256)",
[ethereum.Value.fromUnsignedBigInt(param0)]
);
if (result.reverted) {
return new ethereum.CallResult();
}
let value = result.value;
return ethereum.CallResult.fromValue(
new VotingContract__votingRoomMapResult(
value[0].toBigInt(),
value[1].toBigInt(),
value[2].toI32(),
value[3].toBoolean(),
value[4].toAddress(),
value[5].toBigInt(),
value[6].toBigInt(),
value[7].toBigInt()
)
);
}
}
export class ConstructorCall extends ethereum.Call {
get inputs(): ConstructorCall__Inputs {
return new ConstructorCall__Inputs(this);
}
get outputs(): ConstructorCall__Outputs {
return new ConstructorCall__Outputs(this);
}
}
export class ConstructorCall__Inputs {
_call: ConstructorCall;
constructor(call: ConstructorCall) {
this._call = call;
}
}
export class ConstructorCall__Outputs {
_call: ConstructorCall;
constructor(call: ConstructorCall) {
this._call = call;
}
}
export class CastVotesCall extends ethereum.Call {
get inputs(): CastVotesCall__Inputs {
return new CastVotesCall__Inputs(this);
}
get outputs(): CastVotesCall__Outputs {
return new CastVotesCall__Outputs(this);
}
}
export class CastVotesCall__Inputs {
_call: CastVotesCall;
constructor(call: CastVotesCall) {
this._call = call;
}
get votes(): Array<CastVotesCallVotesStruct> {
return this._call.inputValues[0].value.toTupleArray<
CastVotesCallVotesStruct
>();
}
}
export class CastVotesCall__Outputs {
_call: CastVotesCall;
constructor(call: CastVotesCall) {
this._call = call;
}
}
export class CastVotesCallVotesStruct extends ethereum.Tuple {
get voter(): Address {
return this[0].toAddress();
}
get roomIdAndType(): BigInt {
return this[1].toBigInt();
}
get sntAmount(): BigInt {
return this[2].toBigInt();
}
get r(): Bytes {
return this[3].toBytes();
}
get vs(): Bytes {
return this[4].toBytes();
}
}
export class FinalizeVotingRoomCall extends ethereum.Call {
get inputs(): FinalizeVotingRoomCall__Inputs {
return new FinalizeVotingRoomCall__Inputs(this);
}
get outputs(): FinalizeVotingRoomCall__Outputs {
return new FinalizeVotingRoomCall__Outputs(this);
}
}
export class FinalizeVotingRoomCall__Inputs {
_call: FinalizeVotingRoomCall;
constructor(call: FinalizeVotingRoomCall) {
this._call = call;
}
get roomId(): BigInt {
return this._call.inputValues[0].value.toBigInt();
}
}
export class FinalizeVotingRoomCall__Outputs {
_call: FinalizeVotingRoomCall;
constructor(call: FinalizeVotingRoomCall) {
this._call = call;
}
}
export class InitializeVotingRoomCall extends ethereum.Call {
get inputs(): InitializeVotingRoomCall__Inputs {
return new InitializeVotingRoomCall__Inputs(this);
}
get outputs(): InitializeVotingRoomCall__Outputs {
return new InitializeVotingRoomCall__Outputs(this);
}
}
export class InitializeVotingRoomCall__Inputs {
_call: InitializeVotingRoomCall;
constructor(call: InitializeVotingRoomCall) {
this._call = call;
}
get voteType(): i32 {
return this._call.inputValues[0].value.toI32();
}
get publicKey(): Address {
return this._call.inputValues[1].value.toAddress();
}
get voteAmount(): BigInt {
return this._call.inputValues[2].value.toBigInt();
}
}
export class InitializeVotingRoomCall__Outputs {
_call: InitializeVotingRoomCall;
constructor(call: InitializeVotingRoomCall) {
this._call = call;
}
}
export class SetDirectoryCall extends ethereum.Call {
get inputs(): SetDirectoryCall__Inputs {
return new SetDirectoryCall__Inputs(this);
}
get outputs(): SetDirectoryCall__Outputs {
return new SetDirectoryCall__Outputs(this);
}
}
export class SetDirectoryCall__Inputs {
_call: SetDirectoryCall;
constructor(call: SetDirectoryCall) {
this._call = call;
}
get _address(): Address {
return this._call.inputValues[0].value.toAddress();
}
}
export class SetDirectoryCall__Outputs {
_call: SetDirectoryCall;
constructor(call: SetDirectoryCall) {
this._call = call;
}
}

View File

@ -0,0 +1,137 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
import {
TypedMap,
Entity,
Value,
ValueKind,
store,
Address,
Bytes,
BigInt,
BigDecimal
} from "@graphprotocol/graph-ts";
export class ExampleEntity extends Entity {
constructor(id: string) {
super();
this.set("id", Value.fromString(id));
}
save(): void {
let id = this.get("id");
assert(id !== null, "Cannot save ExampleEntity entity without an ID");
assert(
id.kind == ValueKind.STRING,
"Cannot save ExampleEntity entity with non-string ID. " +
'Considering using .toHex() to convert the "id" to a string.'
);
store.set("ExampleEntity", id.toString(), this);
}
static load(id: string): ExampleEntity | null {
return store.get("ExampleEntity", id) as ExampleEntity | null;
}
get id(): string {
let value = this.get("id");
return value.toString();
}
set id(value: string) {
this.set("id", Value.fromString(value));
}
get roomId(): BigInt {
let value = this.get("roomId");
return value.toBigInt();
}
set roomId(value: BigInt) {
this.set("roomId", Value.fromBigInt(value));
}
get voter(): Bytes {
let value = this.get("voter");
return value.toBytes();
}
set voter(value: Bytes) {
this.set("voter", Value.fromBytes(value));
}
}
export class VotingRoom extends Entity {
constructor(id: string) {
super();
this.set("id", Value.fromString(id));
}
save(): void {
let id = this.get("id");
assert(id !== null, "Cannot save VotingRoom entity without an ID");
assert(
id.kind == ValueKind.STRING,
"Cannot save VotingRoom entity with non-string ID. " +
'Considering using .toHex() to convert the "id" to a string.'
);
store.set("VotingRoom", id.toString(), this);
}
static load(id: string): VotingRoom | null {
return store.get("VotingRoom", id) as VotingRoom | null;
}
get id(): string {
let value = this.get("id");
return value.toString();
}
set id(value: string) {
this.set("id", Value.fromString(value));
}
get community(): Bytes {
let value = this.get("community");
return value.toBytes();
}
set community(value: Bytes) {
this.set("community", Value.fromBytes(value));
}
get type(): i32 {
let value = this.get("type");
return value.toI32();
}
set type(value: i32) {
this.set("type", Value.fromI32(value));
}
get timestamp(): BigInt | null {
let value = this.get("timestamp");
if (value === null || value.kind == ValueKind.NULL) {
return null;
} else {
return value.toBigInt();
}
}
set timestamp(value: BigInt | null) {
if (value === null) {
this.unset("timestamp");
} else {
this.set("timestamp", Value.fromBigInt(value as BigInt));
}
}
get result(): boolean {
let value = this.get("result");
return value.toBoolean();
}
set result(value: boolean) {
this.set("result", Value.fromBoolean(value));
}
}

View File

@ -0,0 +1,16 @@
{
"name": "test",
"license": "UNLICENSED",
"scripts": {
"codegen": "graph codegen",
"build": "graph build",
"deploy": "graph deploy --node https://api.studio.thegraph.com/deploy/ HistorySubgraph",
"create-local": "graph create --node http://localhost:8020/ HistorySubgraph",
"remove-local": "graph remove --node http://localhost:8020/ HistorySubgraph",
"deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 HistorySubgraph"
},
"dependencies": {
"@graphprotocol/graph-cli": "0.21.1",
"@graphprotocol/graph-ts": "0.20.0"
}
}

View File

@ -0,0 +1,13 @@
type ExampleEntity @entity {
id: ID!
roomId: BigInt! # uint256
voter: Bytes! # address
}
type VotingRoom @entity {
id: ID!
community: Bytes!
type: Int
timestamp: BigInt
result: Boolean
}

View File

@ -0,0 +1,61 @@
import { BigInt } from "@graphprotocol/graph-ts"
import {
VotingContract,
VoteCast,
VotingRoomFinalized,
VotingRoomStarted
} from "../generated/VotingContract/VotingContract"
import { VotingRoom, ExampleEntity } from "../generated/schema"
export function handleVoteCast(event: VoteCast): void {
// Entities can be loaded from the store using a string ID; this ID
// needs to be unique across all entities of the same type
// Entities only exist after they have been saved to the store;
// `null` checks allow to create entities on demand
const entity = new ExampleEntity(event.params.voter.toHex())
// Entity fields can be set based on event parameters
entity.roomId = event.params.roomId
entity.voter = event.params.voter
// Entities can be written to the store with `.save()`
entity.save()
// Note: If a handler doesn't require existing field values, it is faster
// _not_ to load the entity from the store. Instead, create it fresh with
// `new Entity(...)`, set the fields that should be updated and save the
// entity back to the store. Fields that were not set or unset remain
// unchanged, allowing for partial updates to be applied.
// It is also possible to access smart contracts from mappings. For
// example, the contract that has emitted the event can be connected to
// with:
//
// let contract = Contract.bind(event.address)
//
// The following functions can then be called on this contract to access
// state variables and other data:
//
// - contract.activeVotingRooms(...)
// - contract.communityVotingId(...)
// - contract.directory(...)
// - contract.getActiveVotingRooms(...)
// - contract.getCommunityVoting(...)
// - contract.listRoomVoters(...)
// - contract.owner(...)
// - contract.votingRoomMap(...)
}
export function handleVotingRoomFinalized(event: VotingRoomFinalized): void {
const entity = new VotingRoom(event.params.roomId.toHex())
entity.community = event.params.publicKey
entity.type = event.params.voteType
entity.result = event.params.passed
entity.timestamp = event.block.timestamp
entity.save()
}
export function handleVotingRoomStarted(event: VotingRoomStarted): void {}

View File

@ -0,0 +1,29 @@
specVersion: 0.0.2
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: VotingContract
network: ganache
source:
address: "0x49affC885564c28B317237232a8bc3628989dD7B"
abi: VotingContract
mapping:
kind: ethereum/events
apiVersion: 0.0.4
language: wasm/assemblyscript
entities:
- VoteCast
- VotingRoomFinalized
- VotingRoomStarted
abis:
- name: VotingContract
file: ./abis/VotingContract.json
eventHandlers:
- event: VoteCast(uint256,address)
handler: handleVoteCast
- event: VotingRoomFinalized(uint256,address,bool,uint8)
handler: handleVotingRoomFinalized
- event: VotingRoomStarted(uint256,address)
handler: handleVotingRoomStarted
file: ./src/mapping.ts

File diff suppressed because it is too large Load Diff