Skip to content

feat: add governance action modal and integrate queue/execute functions#1784

Open
brunod-e wants to merge 12 commits intodevfrom
feat/add-execute-and-queue-buttons
Open

feat: add governance action modal and integrate queue/execute functions#1784
brunod-e wants to merge 12 commits intodevfrom
feat/add-execute-and-queue-buttons

Conversation

@brunod-e
Copy link
Copy Markdown
Collaborator

No description provided.

@brunod-e brunod-e self-assigned this Mar 25, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anticapture Ready Ready Preview, Comment Apr 10, 2026 5:40pm
anticapture-storybook Ready Ready Preview, Comment Apr 10, 2026 5:40pm

Request Review

@brunod-e brunod-e marked this pull request as draft March 25, 2026 20:55
@claude
Copy link
Copy Markdown

claude bot commented Mar 25, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

@claude
Copy link
Copy Markdown

claude bot commented Apr 6, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 81b161426a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +156 to +160
<Button
className="hidden lg:flex"
onClick={() => setIsQueueModalOpen(true)}
>
Queue Proposal
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restrict governance action buttons to valid states

These CTAs are rendered unconditionally, so users can open queue/execute flows for proposals that are not actionable (for example ongoing or defeated) and even while disconnected. In those cases the modal either fails on-chain with a revert or sits in a waiting state because handleAction exits early when no wallet/account is available, which creates a broken primary flow for proposal pages. Please gate these buttons by both wallet connection and the expected status transitions (succeeded for queue, pending_execution/queued for execute).

Useful? React with 👍 / 👎.

Comment on lines +69 to +72
abi: GovernorQueueAbi,
address,
functionName: "queue",
args: contractArgs,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add DAO-specific action routing before queue calls

This utility always submits OpenZeppelin-style queue/execute(targets,values,calldatas,descriptionHash) calls for every DAO, but at least SHU uses Azorius governance (its ABI exposes executeProposal rather than OZ queue/execute). As a result, governance actions for SHU will fail during simulation/send even when the proposal is otherwise executable. This needs DAO-specific dispatch similar to the vote handler selection logic, or explicit exclusion of unsupported DAOs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68fe14f863

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

| Address
| undefined;
const chain = daoConfig?.daoOverview?.chain;
const { data: walletClient } = useWalletClient({ chainId: chain?.id });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Handle wrong-chain wallets before opening delegation flow

Using useWalletClient({ chainId }) returns no wallet client when the user is connected on a different network; with this change, the modal now enters the waiting state but never progresses because both the effect and action handler require a truthy walletClient. In that scenario users see an indefinite "confirm in wallet" step with no network-switch prompt or error, so delegation is effectively blocked unless they manually discover the chain mismatch.

Useful? React with 👍 / 👎.

account: Address,
): ActionArgs => {
return {
targets: proposalTargets.map((t) => (t ?? "0x") as `0x${string}`),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate null targets instead of coercing to invalid address

This conversion turns missing targets into "0x", which is not a valid address, so any proposal payload containing a null target (the function explicitly accepts (string | null)[]) will fail during simulateContract before transaction submission. That makes queue/execute unusable for those records and hides the underlying data problem behind a low-level address error; input validation with a clear message is safer than placeholder coercion.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93f0ac28b7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}, [address, walletClient, step, action, proposal, daoId, onClose, chain]);

useEffect(() => {
if (!isOpen || !walletClient || step !== "waiting-signature") return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Surface wrong-chain state before auto-submitting action

This effect exits when walletClient is undefined, but the modal still renders the active "confirm in wallet" step; with useWalletClient({ chainId }), that undefined case happens whenever the user is connected on the wrong network. Because the header buttons are gated by address (not chain), users can open queue/execute and get stuck in an indefinite waiting state with no network-switch prompt or error.

Useful? React with 👍 / 👎.

import { mainnet } from "wagmi/chains";
import { mainnet, optimism, scroll } from "wagmi/chains";

const alchemyApiKey = process.env.NEXT_PUBLIC_ALCHEMY_KEY;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will leak the alchemy api key

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key was already exposed in the client-side bundle. Not introduced here. But I did a research here and looks like exposing alchemy key is normal because on alchemy dashboard we relate the key with a specific domain. So, no problems exposing it.

/>
{address &&
proposalStatus === "succeeded" &&
daoId.toUpperCase() !== DaoIdEnum.SHU && (
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is Shutter different??

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SHU uses Azorius governance which has no queue step, proposals go directly to execute

Comment on lines +147 to +149
proposalTargets: (string | null)[],
proposalValues: (string | null)[],
proposalCalldatas: (string | null)[],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can they even be null?

Copy link
Copy Markdown
Collaborator Author

@brunod-e brunod-e Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphql schema returns (Maybe< String >[]). thats why

Comment on lines +165 to +167
proposalTargets: (string | null)[],
proposalValues: (string | null)[],
proposalCalldatas: (string | null)[],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would you have this as null?

Copy link
Copy Markdown
Collaborator Author

@brunod-e brunod-e Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graphql schema returns (Maybe< String >[]). thats why

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bca9397988

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +61 to +63
proposal.targets.filter((t) => t !== null),
proposal.values.filter((v) => v !== null),
(proposal.calldatas ?? []).filter((c) => c !== null),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep governance payload arrays index-aligned

handleAction removes nulls from targets, values, and calldatas independently, which can desynchronize operations whenever one list has a null at a different index. In that scenario, queue/execute can revert on array-length mismatch or submit mismatched target/value/calldata tuples. Because the proposal fields are typed as nullable lists, this is a reachable production path for malformed records; these arrays should be validated and transformed in lockstep (or rejected) instead of filtered separately.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d5bbbae4c2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +79 to +80
case DaoIdEnum.UNISWAP:
case DaoIdEnum.NOUNS: {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Route Lil Nouns actions through GovernorBravo path

This switch only special-cases UNI and NOUNS, so LIL_NOUNS falls into the default OpenZeppelin 4-arg queue/execute path. Fresh evidence: apps/api/src/lib/client.ts maps DaoIdEnum.LIL_NOUNS to NounsClient, and Nouns-style governors expose proposal-id-based queue/execute calls; using the 4-arg call shape here will fail simulation/submission and block governance actions for Lil Nouns proposals.

Useful? React with 👍 / 👎.

Comment on lines +158 to +160
<Button
className="hidden lg:flex"
onClick={() => setIsQueueModalOpen(true)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Expose queue/execute actions on mobile proposal pages

The new queue/execute CTA is desktop-only (hidden lg:flex), and this change does not add any mobile trigger for the new modals (the mobile bottom bar still only wires voting). On mobile viewports, users cannot open queue/execute flows for succeeded/queued proposals, so governance lifecycle actions are unavailable on phones/tablets.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants