Skip to content

Add first-class ERC-8004 claim registration tracking#390

Merged
GsCommand merged 1 commit into
mainfrom
codex/add-erc-8004-registration-tracking-to-claim
Jul 21, 2026
Merged

Add first-class ERC-8004 claim registration tracking#390
GsCommand merged 1 commit into
mainfrom
codex/add-erc-8004-registration-tracking-to-claim

Conversation

@GsCommand

Copy link
Copy Markdown
Contributor

Motivation

  • Provide a first-class, additive place to track external registry/discovery registrations (initially ERC-8004) for claimed ENS agents without changing existing tables or claim flows.
  • Make ERC-8004/ENSIP-25 discovery metadata available to admin and authenticated claim views so operators can see registration state and verification timestamps.
  • Ensure tracking is purely observational and configuration-gated so no onchain transactions or verification claims are made by this change.

Description

  • Add a new additive migration db/migrations/012_agent_registrations.sql that creates public.agent_registrations with the requested columns, a foreign key to claim_requests(claim_id), indexes on claim_id, ens, standard, registration_status, agent_id, a unique index on (standard, ens, chain_id, registry_address), and a table-local updated_at trigger.
  • Add lib/claims/agent-registrations.js with an idempotent upsertErc8004Registration helper and trackPinnedCardRegistration helper that are gated by ERC8004_CHAIN_ID and ERC8004_REGISTRY_ADDRESS.
  • Integrate tracking into card pinning flow by invoking trackPinnedCardRegistration for already-pinned cards and when pinning completes in api/admin/pin-agent-cards.js, while leaving agent_id and transaction fields null until real evidence exists.
  • Expose tracked registrations in API responses by adding registrations to the admin claim detail (api/admin/claim.js) and authenticated claim status (api/claims/status.js), and add a registrations section to the admin claim detail UI (public/admin/claims.html).
  • Document the runtime config variables in .env.example (ERC8004_CHAIN_ID and ERC8004_REGISTRY_ADDRESS) and make clear tracking does not submit blockchain transactions.

Testing

  • Ran the full test suite with npm test and all tests passed: 169 tests executed and 0 failures.
  • Executed npm run check:links which completed successfully and ran node --check on the modified files (api/admin/pin-agent-cards.js and lib/claims/agent-registrations.js) with no runtime syntax errors.
  • Added unit tests tests/agent-registrations.test.js verifying idempotent upsert behavior and configuration-gated tracking, and they passed as part of npm test.
  • Ran repository checks with git diff --check and link checks and they completed without errors.

Codex Task

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
commandlayer-commandlayer-org Ready Ready Preview, Comment Jul 21, 2026 2:02am
commandlayer-org Ready Ready Preview, Comment Jul 21, 2026 2:02am
commandlayer-org111 Ready Ready Preview, Comment Jul 21, 2026 2:02am

Request Review

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

Copy link
Copy Markdown

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: 35607af7cd

ℹ️ 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".

where id = $1`,
[row.id, cid, ipfsUri, gatewayUrl, hash, provider]
);
await trackPinnedCardRegistration({ ...row, card_cid: cid, card_ipfs_uri: ipfsUri });

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 observational tracking out of the pinning failure path

When ERC-8004 configuration is enabled and this database upsert fails—for example, during a transient database error or before migration 012 is applied—the exception is handled as an IPFS failure even though Pinata and the preceding agent_cards update already succeeded. The catch then changes the card to pin_status = 'error', returns 502, and leaves the claim unpaid-to-pinned transition incomplete; subsequent requests detect the populated CID as already pinned and do not repair the claim status. Registration tracking is documented as observational, so its failure must not corrupt or block the successful pinning flow.

Useful? React with 👍 / 👎.

Comment thread api/claims/status.js
try {
const registrationsResult = await db.query(
`select standard, ens, chain_id, registry_address, agent_id, agent_uri, registration_status,
ensip25_status, verified_at

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 Return the ENSIP-25 verification timestamp

When an ENSIP-25 verifier populates the new ensip25_verified_at column, this authenticated status response omits that value and instead returns the separate generic verified_at field alongside ensip25_status. Clients therefore see a missing or unrelated timestamp for an ENSIP-25 verification; select ensip25_verified_at (or both timestamp fields) so the newly tracked proof state is observable.

Useful? React with 👍 / 👎.

Comment on lines +15 to +16
on conflict (standard, ens, chain_id, registry_address) do update
set claim_id = excluded.claim_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 Keep registration evidence scoped to its original claim

When a second claim contains the same ENS name, chain, and registry as an earlier claim—which the claim intake permits because ENS is not unique across claims—this conflict handler reassigns the existing registration row to the new claim while intentionally preserving its agent_id, transaction hash, statuses, and verification timestamps. The new claimant then receives the previous claim's registration evidence through the authenticated status API, while the original claim loses the row; include the claim in the conflict identity or create/reset a claim-scoped row rather than transferring verified evidence.

Useful? React with 👍 / 👎.

const allPinned = cardsResult.rows.every((r) => r.card_cid && r.card_ipfs_uri && r.card_sha256);
if (allPinned) return res.status(200).json({ ok: true, status: 'ALREADY_PINNED', claimId, cards: cardsResult.rows });
if (allPinned) {
await Promise.all(cardsResult.rows.map(trackPinnedCardRegistration));

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 Backfill registrations through the main activation workflow

For an existing claim whose cards were pinned before this deployment, the main admin “Run activation pipeline” path checks cardsPinned in api/admin/run-activation-pipeline.js:79-83 and deliberately skips pinAgentCards, so this newly added all-pinned backfill is never reached. Such claims continue to show no registration metadata unless an operator knows to invoke the separate pin endpoint manually; perform the tracking from the orchestration path or provide an explicit migration/backfill so the normal workflow populates these rows.

Useful? React with 👍 / 👎.

@GsCommand
GsCommand deleted the codex/add-erc-8004-registration-tracking-to-claim branch July 21, 2026 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant