Skip to content

Commit

Permalink
improvements to governor provider, and more proposal hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
salieflewis committed Jun 29, 2023
1 parent 5b694d6 commit f3719c0
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 58 deletions.
5 changes: 5 additions & 0 deletions .changeset/unlucky-cameras-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@public-assembly/builder-utils': patch
---

Handles BigInt conversion natively on time based data queries. Adjust the GovernorProvider to return an array of stateful proposals and the associated type.
2 changes: 0 additions & 2 deletions apps/router-test/src/app/[tokenId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
'use client'

import { ConnectButton } from '../../components/ConnectButton'
import { AuctionSkeleton } from '../../components/AuctionSkeleton'

export default function Page({ params }: { params: { tokenId: string } }) {
return (
<>
<ConnectButton />
<AuctionSkeleton tokenId={params.tokenId} />
</>
)
Expand Down
12 changes: 7 additions & 5 deletions apps/router-test/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
'use client'

import '@rainbow-me/rainbowkit/styles.css'
import { ConnectButton } from '@rainbow-me/rainbowkit'
import { Providers } from './providers'

export const metadata = {
title: 'wagmi',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
<Providers>
<ConnectButton />
{children}
</Providers>
</body>
</html>
)
Expand Down
28 changes: 24 additions & 4 deletions apps/router-test/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
useHistoricalBids,
useProposalDetailsQuery,
useCurrentAuctionQuery,
useProposalPermissions,
useDaoProposalsQuery,
useGovernorContext,
} from '@public-assembly/builder-utils'
import Link from 'next/link'

Expand All @@ -20,6 +23,23 @@ export default function Page() {

const currentTokenId = auctionState.tokenId

const { proposals } = useGovernorContext()

// console.log('Proposals array:', proposals)

const { daoProposals } = useDaoProposalsQuery({
tokenAddress: '0xd2e7684cf3e2511cc3b4538bb2885dc206583076',
})

const { proposalDetails } = useProposalDetailsQuery({
proposalId: '0x39198d469ff9ca1dbe1c32dc48b93a6d82c86ed8038723a43043f9066ed52bca',
})

const { canVeto, canCancel, canVote } = useProposalPermissions({
proposalId: proposalDetails.proposalId,
timeCreated: proposalDetails.timeCreatedRaw as bigint,
})

// const { tokenName, tokenId, tokenOwner, tokenImage, mintedAt } =
// useHistoricalTokenQuery({
// tokenAddress: '0xd2e7684cf3e2511cc3b4538bb2885dc206583076',
Expand All @@ -41,11 +61,11 @@ export default function Page() {
// tokenAddress: '0xd2e7684cf3e2511cc3b4538bb2885dc206583076',
// })

const { bids } = useCurrentAuctionQuery({
tokenAddress: '0xdf9b7d26c8fc806b1ae6273684556761ff02d422',
})
// const { bids } = useCurrentAuctionQuery({
// tokenAddress: '0xdf9b7d26c8fc806b1ae6273684556761ff02d422',
// })

console.log(bids)
// console.log(bids)

// console.log(minimumBidIncrement)

Expand Down
4 changes: 2 additions & 2 deletions apps/router-test/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
import * as React from 'react'
import { WagmiConfig } from 'wagmi'
import { Hex } from 'viem'
import { ManagerProvider } from '@public-assembly/builder-utils'
import { ManagerProvider, GovernorProvider } from '@public-assembly/builder-utils'
import { chains, config } from '../wagmi'

export function Providers({ children }: { children: React.ReactNode }) {
Expand All @@ -14,7 +14,7 @@ export function Providers({ children }: { children: React.ReactNode }) {
<WagmiConfig config={config}>
<RainbowKitProvider chains={chains}>
<ManagerProvider tokenAddress={process.env.NEXT_PUBLIC_TOKEN_ADDRESS as Hex}>
{mounted && children}
<GovernorProvider>{mounted && children}</GovernorProvider>
</ManagerProvider>
</RainbowKitProvider>
</WagmiConfig>
Expand Down
1 change: 0 additions & 1 deletion apps/router-test/src/components/ConnectButton.tsx

This file was deleted.

20 changes: 17 additions & 3 deletions packages/builder-utils/src/context/GovernorProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
import React, { useContext } from 'react'
import React, { useContext, useEffect, useState } from 'react'
import type { PropsWithChildren } from 'react'
import { useManagerContext } from './ManagerProvider'
import { useDaoProposalsQuery } from '../subgraph'
import { Proposal } from '../subgraph/types/graphql'
import { Hex } from 'viem'
import { getStatefulProposals } from '../lib/getProposalState'

export type StatefulProposal = Omit<Proposal, '__typename' | 'votes'> & {
state: string
}

export interface GovernorReturnTypes {
tokenAddress: Hex
governorAddress: Hex
daoProposals: Proposal[]
proposals: StatefulProposal[]
}

const GovernorContext = React.createContext({} as GovernorReturnTypes)

export function GovernorProvider({ children }: PropsWithChildren) {
const { tokenAddress, governorAddress } = useManagerContext()
const [proposals, setProposals] = useState<StatefulProposal[] | undefined>()

const { daoProposals } = useDaoProposalsQuery({ tokenAddress: tokenAddress })

useEffect(() => {
if (!daoProposals) return
// prettier-ignore
(async () => {
setProposals(await getStatefulProposals(daoProposals, governorAddress))
})()
}, [daoProposals])

return (
<GovernorContext.Provider
value={{
tokenAddress,
governorAddress: governorAddress as Hex,
daoProposals: daoProposals as Proposal[],
proposals: proposals as StatefulProposal[],
}}>
{children}
</GovernorContext.Provider>
Expand Down
1 change: 1 addition & 0 deletions packages/builder-utils/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './useEnsNameOrShorten'
export * from './useHistoricalBids'
export * from './useInterval'
export * from './useMinBidAmount'
export * from './useProposalPermissions'
export * from './useSettle'
export * from './useTokenExplorer'
export * from './useTokenMetadata'
Expand Down
7 changes: 1 addition & 6 deletions packages/builder-utils/src/hooks/useHistoricalBids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ export function useHistoricalBids({
}) {
const { auctionAddress } = useManagerContext()

// const { tokenData } = useDaoTokenQuery({
// tokenId: tokenId,
// tokenAddress: tokenAddress,
// })

const { mintedAtRaw } = useHistoricalTokenQuery({
tokenAddress,
tokenId: BigInt(tokenId),
Expand All @@ -49,7 +44,7 @@ export function useHistoricalBids({
event: parseAbiItem(
'event AuctionBid(uint256 tokenId, address bidder, uint256 amount, bool extended, uint256 endTime)'
),
fromBlock: BigInt(mintedAtRaw),
fromBlock: mintedAtRaw as bigint,
toBlock: 'latest',
})
/**
Expand Down
62 changes: 62 additions & 0 deletions packages/builder-utils/src/hooks/useProposalPermissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { governorAbi } from '../abi'
import { useGovernorContext } from '../context'
import { useState } from 'react'
import { Hex, Hash } from 'viem'
import { useAccount, useContractReads } from 'wagmi'

export function useProposalPermissions({
proposalId,
timeCreated,
}: {
proposalId: Hash
timeCreated: bigint
}) {
const { governorAddress } = useGovernorContext()
const { address } = useAccount()
const [canVeto, setCanVeto] = useState<boolean>(false)
const [canCancel, setCanCancel] = useState<boolean>(false)
const [canVote, setCanVote] = useState<boolean>(false)

const governorContract = {
address: governorAddress,
abi: governorAbi,
}

useContractReads({
contracts: [
{
...governorContract,
functionName: 'vetoer',
},
{
...governorContract,
functionName: 'getProposal',
args: [proposalId],
},
{
...governorContract,
functionName: 'getVotes',
args: [address as Hex, timeCreated],
},
],
onSuccess(proposalPermissions) {
if (proposalPermissions[0].result === address) {
setCanVeto(true)
}

if (proposalPermissions[1].result?.proposer === address) {
setCanCancel(true)
}

if (Number(proposalPermissions[2].result) > 0) {
setCanVote(true)
}
},
})

return {
canVeto,
canCancel,
canVote,
}
}
35 changes: 35 additions & 0 deletions packages/builder-utils/src/lib/getProposalState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { governorAbi } from '../abi'
import { Hash, Hex } from 'viem'
import { readContract } from 'wagmi/actions'

export enum ProposalState {
Pending = 0,
Active = 1,
Canceled = 2,
Defeated = 3,
Succeeded = 4,
Queued = 5,
Expired = 6,
Executed = 7,
Vetoed = 8,
}

export const getProposalState = async (governorAddress: Hex, proposalId: Hash) => {
return (await readContract({
address: governorAddress,
abi: governorAbi,
functionName: 'state',
args: [proposalId],
})) as ProposalState
}

export const getStatefulProposals = async (daoProposals, governorAddress) => {
const statefulProposals = await Promise.all(
daoProposals.map(async (proposal) => {
const state = await getProposalState(governorAddress, proposal.id)
return { ...proposal, state }
})
)

return statefulProposals
}
1 change: 1 addition & 0 deletions packages/builder-utils/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './etherscanLink'
export * from './formatFromUnix'
export * from './getProposalState'
export * from './parseBase64String'
export * from './shortenAddress'
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export function useHistoricalTokenQuery({
tokenImage: historicalToken?.dao?.tokens[0]?.image,
tokenOwner: tokenOwner,
mintedAt: formatFromUnix({ timestamp: historicalToken?.dao?.tokens[0]?.mintedAt }),
mintedAtRaw: historicalToken?.dao?.tokens[0]?.mintedAt,
mintedAtRaw: historicalToken?.dao?.tokens[0]?.mintedAt
? BigInt(historicalToken?.dao?.tokens[0]?.mintedAt)
: '',
error,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,52 @@ export function useProposalDetailsQuery({ proposalId }: { proposalId: string })
const proposer = useEnsNameOrShorten({ address: proposalDetails?.proposal?.proposer })

return {
forVotes: proposalDetails?.proposal?.forVotes,
againstVotes: proposalDetails?.proposal?.againstVotes,
abstainVotes: proposalDetails?.proposal?.abstainVotes,
calldatas: proposalDetails?.proposal?.calldatas,
description: proposalDetails?.proposal?.description,
descriptionHash: proposalDetails?.proposal?.descriptionHash,
executableFrom: formatFromUnix({
timestamp: proposalDetails?.proposal?.executableFrom,
}),
expiresAt: formatFromUnix({ timestamp: proposalDetails?.proposal?.expiresAt }),
proposalId: proposalDetails?.proposal?.proposalId,
proposalNumber: proposalDetails?.proposal?.proposalNumber,
proposalThreshold: proposalDetails?.proposal?.proposalThreshold,
proposer: proposer,
quorumVotes: proposalDetails?.proposal?.quorumVotes,
targets: proposalDetails?.proposal?.targets,
timeCreated: formatFromUnix({ timestamp: proposalDetails?.proposal?.timeCreated }),
title: proposalDetails?.proposal?.title,
values: proposalDetails?.proposal?.values,
voteEnd: formatFromUnix({ timestamp: proposalDetails?.proposal?.voteEnd }),
voteStart: formatFromUnix({ timestamp: proposalDetails?.proposal?.voteStart }),
snapshotBlockNumber: proposalDetails?.proposal?.snapshotBlockNumber,
transactionHash: proposalDetails?.proposal?.transactionHash,
governorAddress: proposalDetails?.proposal?.dao.governorAddress,
tokenAddress: proposalDetails?.proposal?.dao.tokenAddress,
error,
proposalDetails: {
forVotes: proposalDetails?.proposal?.forVotes,
againstVotes: proposalDetails?.proposal?.againstVotes,
abstainVotes: proposalDetails?.proposal?.abstainVotes,
calldatas: proposalDetails?.proposal?.calldatas,
canceled: proposalDetails?.proposal?.canceled,
description: proposalDetails?.proposal?.description,
descriptionHash: proposalDetails?.proposal?.descriptionHash,
executableFrom: formatFromUnix({
timestamp: proposalDetails?.proposal?.executableFrom,
}),
executableFromRaw: proposalDetails?.proposal?.executableFrom
? BigInt(proposalDetails?.proposal?.executableFrom)
: '',
executed: proposalDetails?.proposal?.executed,
expiresAt: formatFromUnix({ timestamp: proposalDetails?.proposal?.expiresAt }),
expiresAtRaw: proposalDetails?.proposal?.expiresAt
? BigInt(proposalDetails?.proposal?.expiresAt)
: '',
proposalId: proposalDetails?.proposal?.proposalId,
proposalNumber: proposalDetails?.proposal?.proposalNumber,
proposalThreshold: proposalDetails?.proposal?.proposalThreshold,
proposer: proposer,
queued: proposalDetails?.proposal?.queued,
quorumVotes: proposalDetails?.proposal?.quorumVotes,
targets: proposalDetails?.proposal?.targets,
timeCreated: formatFromUnix({ timestamp: proposalDetails?.proposal?.timeCreated }),
timeCreatedRaw: proposalDetails?.proposal?.timeCreated
? BigInt(proposalDetails?.proposal?.timeCreated)
: '',
title: proposalDetails?.proposal?.title,
values: proposalDetails?.proposal?.values,
voteEnd: formatFromUnix({ timestamp: proposalDetails?.proposal?.voteEnd }),
voteEndRaw: proposalDetails?.proposal?.voteEnd
? BigInt(proposalDetails?.proposal?.voteEnd)
: '',
voteStart: formatFromUnix({ timestamp: proposalDetails?.proposal?.voteStart }),
voteStartRaw: proposalDetails?.proposal?.voteStart
? BigInt(proposalDetails?.proposal?.voteStart)
: '',
vetoed: proposalDetails?.proposal?.vetoed,
voteCount: proposalDetails?.proposal?.voteCount,
snapshotBlockNumber: proposalDetails?.proposal?.snapshotBlockNumber,
transactionHash: proposalDetails?.proposal?.transactionHash,
governorAddress: proposalDetails?.proposal?.dao.governorAddress,
tokenAddress: proposalDetails?.proposal?.dao.tokenAddress,
},
}
}
1 change: 1 addition & 0 deletions packages/builder-utils/src/subgraph/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './hooks'
export * from './types'
Loading

0 comments on commit f3719c0

Please sign in to comment.