Add first-class ERC-8004 claim registration tracking#390
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: 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 }); |
There was a problem hiding this comment.
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 👍 / 👎.
| try { | ||
| const registrationsResult = await db.query( | ||
| `select standard, ens, chain_id, registry_address, agent_id, agent_uri, registration_status, | ||
| ensip25_status, verified_at |
There was a problem hiding this comment.
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 👍 / 👎.
| on conflict (standard, ens, chain_id, registry_address) do update | ||
| set claim_id = excluded.claim_id, |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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 👍 / 👎.
Motivation
Description
db/migrations/012_agent_registrations.sqlthat createspublic.agent_registrationswith the requested columns, a foreign key toclaim_requests(claim_id), indexes onclaim_id,ens,standard,registration_status,agent_id, a unique index on(standard, ens, chain_id, registry_address), and a table-localupdated_attrigger.lib/claims/agent-registrations.jswith an idempotentupsertErc8004Registrationhelper andtrackPinnedCardRegistrationhelper that are gated byERC8004_CHAIN_IDandERC8004_REGISTRY_ADDRESS.trackPinnedCardRegistrationfor already-pinned cards and when pinning completes inapi/admin/pin-agent-cards.js, while leavingagent_idand transaction fields null until real evidence exists.registrationsto 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)..env.example(ERC8004_CHAIN_IDandERC8004_REGISTRY_ADDRESS) and make clear tracking does not submit blockchain transactions.Testing
npm testand all tests passed:169tests executed and0failures.npm run check:linkswhich completed successfully and rannode --checkon the modified files (api/admin/pin-agent-cards.jsandlib/claims/agent-registrations.js) with no runtime syntax errors.tests/agent-registrations.test.jsverifying idempotent upsert behavior and configuration-gated tracking, and they passed as part ofnpm test.git diff --checkand link checks and they completed without errors.Codex Task