STA-19: proposal-first ENS trait + subdomain management#50
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9bb1618020
ℹ️ 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".
| const apiKit = new SafeApiKit(getSafeApiKitConfig(parsed.chainId)) | ||
|
|
||
| await apiKit.proposeTransaction({ | ||
| safeAddress: parsed.safeAddress, |
There was a problem hiding this comment.
Gate Safe proposal endpoint with authenticated ownership
The new POST /api/safe/propose handler forwards requests to Safe Transaction Service without any server-side auth/authorization check that the caller is a logged-in founder for the submitted safeAddress. Because this route uses the server SAFE_API_KEY, an anonymous client can repeatedly submit valid signed payloads for arbitrary safes and burn API quota/rate limits, which can block legitimate proposal submissions from your dashboard. Add a session check and ownership validation before calling apiKit.proposeTransaction.
Useful? React with 👍 / 👎.
| const subdomains = await Promise.all( | ||
| names.map(async (name) => { | ||
| const details = await client.readContract({ |
There was a problem hiding this comment.
Deduplicate subdomain labels before fetching records
This code fetches details for every entry returned by getCompanySubdomains as-is, but the contract flow allows duplicates after revoke/recreate (labels are appended on create and never removed on revoke). In that case, the same subdomain is rendered multiple times as active (and later causes duplicate React keys in the list UI), even though it is a single logical record. Deduplicate names before the map (for example via Set) so each label is loaded once.
Useful? React with 👍 / 👎.
Summary
/dashboard/ensfor trait updates (avatar,description,url)SAFE_API_KEY_MISSINGerrorsTechnical Changes
loading.tsx,error.tsxstartupChainAbiwith subdomain methodssafe-api-confighelper for explicit Safe API key wiringValidation
./node_modules/.bin/tsc --noEmityarn run test:unityarn run check(passes; existing warnings only, no errors)Greptile Summary
This PR adds proposal-first ENS management to the
/dashboard/ensroute, allowing founders to propose ENS trait updates (avatar,description,url) and subdomain operations (create,revoke) through Safe multisig proposals with automatic confirmation tracking.Key additions:
/api/safe/proposeroute that accepts Safe transaction proposals from clients and submits them via Safe API Kitsafe-api-confighelper that explicitly validatesSAFE_API_KEYand returns deterministicSAFE_API_KEY_MISSINGerrorsloading.tsx,error.tsx) following Next.js 16 patternsArchitecture highlights:
@safe-global/protocol-kit→ POST to/api/safe/propose→ Safe API Kit submits to queue → UI polls for confirmationSAFE_API_KEYis missing (UI shows informational message, actions disabled)startupChainAbiwith subdomain methods (createSubdomain,revokeSubdomain,getSubdomain,getCompanySubdomains)All changes align with documented system architecture and follow Next.js 16 + React 19 server component patterns.
Confidence Score: 5/5
Important Files Changed
Sequence Diagram
sequenceDiagram participant User participant UI as ENS Traits Card participant Wallet as Privy Wallet participant Client as safe-proposal-client participant API as /api/safe/propose participant SafeKit as Safe API Kit participant Safe as Safe Contract participant ENS as ENS Resolver User->>UI: Edit trait & click "Propose update" UI->>Wallet: Connect wallet (if needed) Wallet-->>UI: Wallet ready UI->>Client: proposeSafeTransactionFromWallet() Client->>Wallet: Initialize Safe protocol-kit Wallet-->>Client: Safe instance Client->>Client: Create Safe transaction Client->>Client: Generate safeTxHash Client->>Wallet: Sign safeTxHash Wallet-->>Client: Signature Client->>API: POST /api/safe/propose Note over API: Validate payload<br/>Check SAFE_API_KEY API->>SafeKit: getSafeApiKitConfig() SafeKit-->>API: Config with API key API->>SafeKit: proposeTransaction() SafeKit->>Safe: Submit proposal to queue Safe-->>SafeKit: Proposal queued SafeKit-->>API: Success API-->>Client: { safeTxHash } Client-->>UI: Success with safeTxHash UI->>UI: Mark as pending UI->>UI: Start 15s refresh interval Note over User,ENS: Later: Founders approve & execute via Safe wallet Safe->>ENS: setText(node, key, value) ENS-->>Safe: Trait updated UI->>UI: Periodic refresh UI->>ENS: Read trait value ENS-->>UI: New value confirmed UI->>UI: Clear pending stateLast reviewed commit: 4263b9f