Add managed ENS publication helper#388
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cc71e58231
ℹ️ 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 { buildSignerRecords, CANONICALIZATION, resolveRequiredSignerRecords, compareSignerRecords } = require('./signer-records'); | ||
|
|
||
| const APPROVED_MANAGED_PARENTS = ['attestagent.eth', 'approveagent.eth', 'verifyagent.eth', 'authorizeagent.eth']; |
There was a problem hiding this comment.
Accept generated trust parents in the managed allow-list
For CL-mode claims submitted with the current Trust Verification pack, public/claim.html selects all TRUST_PARENTS in order, and the first generated tenant signer is *.signagent.eth; this allow-list omits signagent.eth (and several other generated trust parents), so buildManagedEnsPublicationPackage() rejects those normal managed claims as MANAGED_PARENT_NOT_APPROVED before operators can prepare TXT records. Please keep this list aligned with the generated managed parents or the helper is unusable for the default trust pack.
Useful? React with 👍 / 👎.
|
|
||
| async function prepareManagedEnsPublication(){if(!s.selected){s.error='Request failed: 400';renderDetail();return;}s.error=null;const r=await fetch('/api/admin/prepare-managed-ens-publication',{method:'POST',headers:headers(),body:JSON.stringify({claimId:s.selected})});const d=await r.json().catch(()=>({}));if(!r.ok||!d.ok){s.error=d?.status||'MANAGED_ENS_PUBLICATION_PREPARE_FAILED';renderDetail();return;}s.managedEnsPublication=d.publication;await loadDetail(s.selected);} | ||
| async function verifyManagedEnsPublication(){if(!s.selected){s.error='Request failed: 400';renderDetail();return;}s.error=null;const r=await fetch('/api/admin/verify-managed-ens-publication',{method:'POST',headers:headers(),body:JSON.stringify({claimId:s.selected})});const d=await r.json().catch(()=>({}));if(!r.ok||!d.ok){s.error=d?.status||'MANAGED_ENS_PUBLICATION_VERIFY_FAILED';renderDetail();return;}s.managedEnsPublication=null;await loadDetail(s.selected);} | ||
| function txtRecordBlocks(claim){const records=(s.managedEnsPublication&&s.managedEnsPublication.required_txt_records)||claim.managed_ens_required_txt_records||claim.tenant_signer_txt_records||{};return Object.entries(records).map(([k,v])=>`<div class='panel' style='margin:8px 0'><div><strong>${k}</strong> <button class='btn btn-muted copy-url' data-url='${String(v).replaceAll("'",''')}'>Copy value</button></div><pre class='mono' style='white-space:pre-wrap;overflow-wrap:anywhere;'>${v}</pre></div>`).join('')||'<p class="muted">Prepare TXT records to display required values.</p>';} |
There was a problem hiding this comment.
Clear cached TXT records when loading another claim
When an operator prepares claim A and then opens claim B, loadDetail() does not clear s.managedEnsPublication, and this expression always prefers the cached package over the loaded claim's records. The detail panel can therefore display/copy A's TXT values for B until a verification clears the cache or the page reloads, risking publication of the wrong ENS records.
Useful? React with 👍 / 👎.
| 'cl.capability': 'attest', | ||
| 'cl.runtime': 'https://runtime.commandlayer.org', | ||
| 'cl.verifier': 'https://runtime.commandlayer.org/verify', | ||
| 'cl.trust_verification_entry': 'https://runtime.commandlayer.org/trust-verification/attest/v1.0.0', |
There was a problem hiding this comment.
Derive agent records from the signer capability
For managed claims whose signer is one of the other allowed parents, such as acme.approveagent.eth or acme.verifyagent.eth, the publication package still tells the operator to publish cl.capability=attest and the attest trust-verification entry. That makes the helper emit incorrect TXT guidance for valid non-attest managed signer names, so these values should be derived from the signer parent/capability instead of hard-coded.
Useful? React with 👍 / 👎.
| } | ||
| return res.status(200).json({ ok: true, claim_id: claimId, verification }); | ||
| } catch (error) { | ||
| try { await db.query(`update claim_requests set managed_ens_publication_status = 'failed', managed_ens_publication_error = $2, updated_at = now() where claim_id = $1`, [claimId, error.message]); } catch (_) {} |
There was a problem hiding this comment.
Store a bounded error code for resolver failures
When the ENS/RPC resolver throws, this catch persists the raw error.message into managed_ens_publication_error, and api/claims/status.js returns that field to claim-token callers. Unlike the existing signer-record verifier, which stores fixed error codes, this can expose arbitrary provider exception text in claimant-visible status after a transient resolver failure; persist a stable code instead.
Useful? React with 👍 / 👎.
| `update claim_requests | ||
| set managed_ens_publication_status = $2, managed_ens_publication_error = $3, | ||
| tenant_signer_verification_error = $3, updated_at = now() |
There was a problem hiding this comment.
Keep signer status in sync on failed verification
When live TXT records are present but mismatched, this branch records only the managed publication status/error and leaves tenant_signer_record_status at its previous value (commonly records_generated). Since both the public pipeline and admin list read tenant_signer_record_status for ENS record state, an operator-run failed verification still surfaces stale signer-record status instead of records_mismatch/records_unavailable; update it the same way the existing signer-record verifier does.
Useful? React with 👍 / 👎.
Motivation
Description
db/migrations/011_managed_ens_publication.sqlto addmanaged_ens_publication_status,managed_ens_parent_namespace,managed_ens_publication_instructions,managed_ens_required_txt_records,managed_ens_verified_at, andmanaged_ens_publication_errortoclaim_requestsusingalter table if exists/add column if not exists.lib/claims/managed-ens-publication.jswithbuildManagedEnsPublicationPackage(claim)andverifyManagedEnsPublication(claim)that validate managed-namespace safety, build the publication package (signer ENS, parent namespace, required TXT records, agent records, and operator instructions), and verify live TXT records by reusing the existing signer-record resolver/comparator.POST /api/admin/prepare-managed-ens-publicationandPOST /api/admin/verify-managed-ens-publicationwhich require admin auth, load the claim, persist publication state/records/instructions, and update verification status based on live TXT checks without broadcasting transactions.api/admin/run-activation-pipeline.jsandapi/claims/status.js, and add UI controls and record display topublic/admin/claims.htmlfor preparing and verifying TXT records.tests/managed-ens-publication.test.jscovering preparation, safety validations (mode, missing ENS, root ENS rejection, unapproved parent, receipt signer mismatch), successful verification updates, failed verification behavior, and public status exposure.activation_mode = managed_namespace, enforces approved managed parents, rejects tenant root ENS and mismatchedcl.receipt.signer, requires public key/kid/canonicalization, and performs no onchain writes, transaction signing, wallet connections, or private key custody.Testing
npm test -- --test-reporter=specand all tests passed (166 tests, 0 failures).node --test tests/managed-ens-publication.test.jsduring development and the new tests passed.npm run check:linksand confirmed local links/assets resolved successfully.Codex Task