useGovernance
Governance operations including proposals and voting. All data comes from context.
Usage
typescript
import { useGovernance } from 'levr-sdk/client'
function GovernanceInterface() {
const {
// Mutations
proposeTransfer,
proposeBoost,
vote,
executeProposal,
claimAirdrop,
// Helpers
buildProposeTransferConfig,
buildProposeBoostConfig,
buildExecuteProposalConfig,
// Loading states
isReady,
isProposing,
isVoting,
isExecuting,
isClaiming,
} = useGovernance({
proposalId: 123n, // Optional: for dynamic proposal query
cycleId: 5n, // Optional: for cycle proposals
onVoteSuccess: (receipt) => {
console.log('Voted!', receipt)
},
onExecuteProposalSuccess: (receipt) => {
console.log('Executed!', receipt)
},
})
const handleProposeTransfer = () => {
const config = buildProposeTransferConfig({
recipient: '0x...',
amount: '1000',
description: 'Fund development team',
})
proposeTransfer.mutate(config)
}
const handleVote = (proposalId: bigint, support: boolean) => {
vote.mutate({ proposalId, support })
}
// Get data from context
const { data: user } = useUser()
const { data: project } = useProject()
const { data: airdrop } = useAirdropStatus()
// Find treasury airdrop
const treasuryRecipient = airdrop?.recipients.find(r => r.isTreasury)
return (
<div>
<h2>Governance</h2>
<p>Current Cycle: {project?.governanceStats?.currentCycleId.toString()}</p>
<p>Treasury: {project?.treasury}</p>
<p>Your Voting Power: {user?.votingPower} Token Days</p>
{treasuryRecipient?.isAvailable && (
<button onClick={() => claimAirdrop.mutate(treasuryRecipient)} disabled={isClaiming}>
Claim {treasuryRecipient.availableAmount.formatted} Tokens
</button>
)}
{/* Batch claim all available recipients */}
{airdrop?.recipients.some(r => r.isAvailable) && (
<button
onClick={() => claimAirdropBatch.mutate(airdrop.recipients.filter(r => r.isAvailable))}
disabled={isClaiming}
>
Claim All Available Airdrops
</button>
)}
<button onClick={handleProposeTransfer} disabled={isProposing}>
Propose Transfer
</button>
</div>
)
}Options
Query parameters (optional):
proposalId: Proposal ID for dynamic proposal querycycleId: Cycle ID for cycle proposals queryuserAddress: Custom user address for vote receipts
Callback parameters (optional):
onProposeTransferSuccess: Callback after successful transfer proposalonProposeBoostSuccess: Callback after successful boost proposalonVoteSuccess: Callback after successful voteonExecuteProposalSuccess: Callback after successful executiononClaimAirdropSuccess: Callback after successful airdrop claim
Mutations
proposeTransfer.mutate(config): Propose a treasury transferproposeBoost.mutate(config): Propose staking boostvote.mutate({ proposalId, support }): Vote on a proposalexecuteProposal.mutate(config): Execute a passed proposalclaimAirdrop.mutate(recipient): Claim airdrop for a single recipientclaimAirdropBatch.mutate(recipients): Claim airdrops for multiple recipients in one transaction
Data Access
All governance data comes from user, project, and airdropStatus context queries:
typescript
import { useUser, useProject, useAirdropStatus } from 'levr-sdk/client'
const { data: user } = useUser()
const { data: project } = useProject()
const { data: airdrop } = useAirdropStatus()
// From project context
project?.governanceStats?.currentCycleId // Current governance cycle
project?.governanceStats?.activeProposalCount.transfer // Active transfers
project?.governanceStats?.activeProposalCount.boost // Active boosts
project?.governor // Governor contract address
project?.treasury // Treasury contract address
project?.factory // Factory contract address
// From user context
user?.votingPower // User's voting power in Token Days (string)
// From airdrop context (multi-recipient support)
airdrop?.recipients // Array of all recipients
airdrop?.recipients[0].isAvailable // Is this recipient available
airdrop?.recipients[0].availableAmount // Available amount for recipient
airdrop?.recipients[0].proof // Merkle proof for recipient
airdrop?.recipients.find((r) => r.isTreasury) // Find treasury recipient