Skip to content

feat(APP-1165): Add native Safe governance proposals - #1437

Open
thekidnamedkd wants to merge 8 commits into
safe-biz-logicfrom
app-1165-safe-process-identity
Open

thekidnamedkd wants to merge 8 commits into
safe-biz-logicfrom
app-1165-safe-process-identity

Conversation

@thekidnamedkd

@thekidnamedkd thekidnamedkd commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

Implements APP-1165. Stacked on #1397; base branch is safe-biz-logic.

Safes with DAO Execute permission appear as governance processes. Their Proposals tab pages through stored pending and executed DAO transactions from backend #1587. SAFE-<nonce> labels are display-only; links identify the Safe and transaction hash, so competing transactions remain separate. Old hash links also look up superseded and removed transactions.

Creation uses the action-only wizard. Details show decoded DAO.execute actions and reuse the multisig voting presentation, with Safe envelope review and owner signing inside Aragon. Decoded actions are checked against the transaction's local action tuples; pending or mismatched decoding falls back to raw actions. Process settings and members reuse the Safe-body views. Assets and Transactions are unchanged.

The list verifies DAO.execute targets, including known MultiSend batches, and reports stale, partial or unindexed reads. Pagination remains usable when a backend page has no matching DAO actions or the next request fails. Signing retains fresh queue/history reconciliation and checks the reviewed hash, owner, chain and nonce.

Dependencies: #1397 supplies the Safe review/signing primitives. Backend #1587 is merged and its stored transaction/actions endpoints responded successfully in development. Native process discovery requires Execute-grant indexing from backend #1588; historical grants need registration/backfill.

Verification:

  • App TypeScript check passed.
  • 56 affected Jest suites passed, 442 tests.
  • Scoped Biome check passed for 23 changed TypeScript files.
  • Live development API checks covered stored pagination, retired states and decoded actions.
  • Browser smoke used the real DAO Proposals route with browser-only process/transaction fixtures: filtered-empty first page, More, hash-addressed detail navigation, DAO actions, Safe owners and approvals. The invalid fixture hash correctly displayed the signing prohibition. No signature or chain transaction was sent; reloading removed the fixtures.
  • Earlier browser smoke covered the metadata-free wizard and disconnected-wallet connection. Existing development CSP/Permissions-Policy/WalletConnect warnings remain.
  • Live native/linked-account acceptance remains blocked on indexed process data. The backend integration-fixture DAO is still admin-only in the DAO API and its Safe stored endpoint returns 404. Linked-account routing has unit coverage; fixture smoke is not a substitute for this live-data check.
  • CodeQL passed for 07cf805a5. Application and preview workflows have not started for this commit; their earlier results do not verify this update.

Type of Change

  • Minor: Feature (non-breaking change which adds new functionality)

Developer Checklist:

  • Manually smoke tested the functionality in a preview or locally
  • Confirmed there are no new warnings or errors in the browser console
  • (For User Stories only) Double-checked that all Acceptance Criteria are satisfied
  • Confirmed there are no new warnings on automated tests
  • Merged and published any dependent changes in downstream modules
  • Selected the correct base branch
  • Commented the code in hard-to-understand areas
  • Followed the code style guidelines of this project
  • Reviewed that the Files Changed in Github’s UI reflect my intended changes
  • Confirmed the pipeline checks are not failing

Review Checklist:

  • (For User Stories only) Tested in a preview or locally that all Acceptance Criteria are satisfied
  • Confirmed that changes follow the code style guidelines of this project

@thekidnamedkd
thekidnamedkd requested a review from a team as a code owner September 30, 2026 18:58
@linear-code

linear-code Bot commented Sep 30, 2026

Copy link
Copy Markdown

APP-1165

@thekidnamedkd
thekidnamedkd added this pull request to stack #1438 September 30, 2026 18:58
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

🚀 Preview Deployment: View Here

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

E2E results (preview)

Smoke

Base URL https://app-next-er6ptxihr-aragon-app.vercel.app
Suite smoke
Playwright result ✅ passed
Summary 86 passed
HTML report View report
GitHub job ✅ completed

View run #5450

@thekidnamedkd thekidnamedkd changed the title feat: Add native Safe governance proposals feat(APP-1165): Add native Safe governance proposals Oct 2, 2026

@milosh86 milosh86 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just a couple of comments for now, I have more to check

link: `${baseUrl}/members`,
icon: IconType.APP_MEMBERS,
hidden: !(isSupported && hasBodyPlugin),
hidden: !(isSupported && (hasBodyPlugin || hasSafeProcess)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we just mark safe plugin with isBody: true on the backend?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah, now after reviewing the previous PR, I get that in the context of a workspace a Safe always is both a process and a body, but in the context of a DAO, it could be one or another. Also it seems that if it has EXECUTE permission and it is added as a process then it should automatically be a body too. In the other case, if it is a body in a SPP process, then it's just a body.


const { result, isLoading } = useSimulateProposalCreation({
plugin: process,
enabled: process.interfaceType !== PluginInterfaceType.SAFE,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can GOVERNANCE_BUILD_CREATE_PROPOSAL_DATA slot be implemented for Safe so we don't have this branching logic?

useEffect(() => {
checkWalletConnected();
}, [checkWalletConnected]);
if (enabled || checkWalletConnection) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isn't checkWalletConnection always non-null?

*/
fullExecuteOnly?: boolean;
/** Include native Safe accounts in proposal creation only. */
allowNativeSafe?: boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

do we have a case where we don't want to show Safe process?


return (
<Page.Container>
<SafeDaoProposalDetails

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

An important question for workspaces: how much is this implementation tied to DAO? Is it easy to make a SafeProposalDetails which works for any Safe transaction?

Another question, does it make sense to port some of the safeTransaction->proposal mapping to backend so we consume a common abstraction?

This branch was successfully deployed

1 active deployment
preview — bed19953 Deployed Oct 7, 2026 by thekidnamedkd via deploy / deploy #5450
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants