Skip to content

fix(runner): harden ERC8004 identity ensure roster sync#554

Merged
riyannode merged 3 commits into
mainfrom
fix/runner-erc8004-identity-harden
Jun 18, 2026
Merged

fix(runner): harden ERC8004 identity ensure roster sync#554
riyannode merged 3 commits into
mainfrom
fix/runner-erc8004-identity-harden

Conversation

@riyannode

Copy link
Copy Markdown
Owner

Summary

Harden ERC-8004 identity ensure flow with 7 fixes and 16 new test cases.

Fixes

Fix 1: Console roster token field normalization

  • ConsoleRosterEntry type now accepts both token_id (snake_case) and tokenId (camelCase)
  • Merge logic extracts token ID from either field
  • Undefined token IDs are no longer added to the dedupe set

Fix 2: Replace totalSupply/ownerOf scan with Transfer event log scanning

  • scanExistingIdentityOnChain() now uses eth_getLogs with Transfer event signature
  • Scans mints where from=0x0 and to=walletAddress
  • Chunks getLogs by ≤ 10,000 block ranges
  • Configurable start block via ARCLAYER_ERC8004_SCAN_FROM_BLOCK env var (fallback: block 40,000,000)
  • Deduplicates tokenIds and verifies current ownership with ownerOf

Fix 3: Fail closed when on-chain scan fails

  • If autoRegister=true and on-chain scan throws, blocks mint to avoid duplicates
  • Returns clear failure message: "On-chain identity scan failed. Auto-register blocked to avoid duplicate mint."

Fix 4: Retry Console sync after pending tx confirmation

  • After confirming pending tx with tokenId, attempts Console roster sync
  • Handles sync retryable, success, and permanent failure cases

Fix 5: Honor --confirm-second-mint

  • When confirmSecondMint=true AND autoRegister=true, skips single-identity reuse
  • Proceeds to second mint path after showing existing tokenId(s)

Fix 6: Honor explicit ARCLAYER_AGENT_ID when multiple identities

  • New selectedAgentId parameter on ensureIdentity
  • When multiple identities found, selects matching tokenId if selectedAgentId matches
  • Passes config.agentId from index.ts CLI command

Fix 7: Respect configured Console URL in syncToConsole

  • syncToConsole now uses this.config.consoleUrl ?? process.env.ARCLAYER_CONSOLE_URL
  • Same pattern already used in registerErc8004WithApproval

Test Coverage

16 new tests in identity-ensure.test.ts:

  1. Console roster camelCase tokenId — accepted
  2. Console roster snake_case token_id — accepted
  3. Malformed Console row without tokenId/token_id — ignored safely
  4. On-chain scan failure + autoRegister=true blocks mint
  5. On-chain scan failure does not call registerFn
  6. Transfer log scan finds tokenId without totalSupply
  7. getLogs chunking ≤ 10,000 block ranges
  8. Transferred-away token is ignored after ownerOf verification
  9. Pending tx finalized triggers Console sync
  10. Sync retryable after finalize reports retryable
  11. Sync success after finalize writes confirmed identity
  12. confirmSecondMint=true allows second mint path
  13. confirmSecondMint=false reuses existing identity
  14. Multiple identities + configured selectedAgentId selects matching token
  15. Multiple identities + no selectedAgentId fails clearly
  16. selectedAgentId that doesn't match returns clear error

Test Results

  • @arclayer/runner tests: 725 passed (18 test files)
  • @arclayer/runner build: success
  • @arclayer/langchain-adapter tests: 105 passed (4 test files)

Fix 1: Console roster token field normalization
- Accept both camelCase (tokenId) and snake_case (token_id) from Console
- Skip undefined token IDs in merge logic

Fix 2: Replace totalSupply/ownerOf scan with Transfer event log scanning
- Use eth_getLogs with Transfer event topic instead of totalSupply()
- Chunk getLogs by <= 10,000 block ranges
- Configurable start block via ARCLAYER_ERC8004_SCAN_FROM_BLOCK
- Dedupe tokenIds and verify current ownership with ownerOf

Fix 3: Fail closed when on-chain scan fails
- Block auto-register when on-chain scan throws to avoid duplicate mint
- Return clear failure message

Fix 4: Retry Console sync after pending tx confirmation
- Call syncToConsoleFn after finalizeResult.confirmed with tokenId
- Handle retryable and permanent sync failures

Fix 5: Honor --confirm-second-mint
- When confirmSecondMint=true AND autoRegister=true, skip single-identity
  reuse and proceed to second mint path

Fix 6: Honor explicit ARCLAYER_AGENT_ID when multiple identities
- Add selectedAgentId parameter to ensureIdentity
- Select matching tokenId when found in on-chain set
- Pass config.agentId from index.ts

Fix 7: Respect configured Console URL in syncToConsole
- Use this.config.consoleUrl ?? process.env.ARCLAYER_CONSOLE_URL
  (same pattern as registerErc8004WithApproval)

Tests: 16 new test cases covering all fixes
@netlify

netlify Bot commented Jun 18, 2026

Copy link
Copy Markdown

Deploy Preview for rainbow-macaron-5d0d9a ready!

Name Link
🔨 Latest commit 5d0d07c
🔍 Latest deploy log https://app.netlify.com/projects/rainbow-macaron-5d0d9a/deploys/6a33cf6649f46d00082831eb
😎 Deploy Preview https://deploy-preview-554--rainbow-macaron-5d0d9a.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
arcwork Ready Ready Preview, Comment Jun 18, 2026 11:00am

Request Review

- getLogs chunk failure now throws instead of silent continue
- getBlockNumber failure in real RPC mode now throws (bounded fallback only in test override mode)
- balanceOf > 0 but no currently-owned tokens after scan throws incomplete scan error
- Added tests: getLogs chunk error blocks auto-register, getBlockNumber failure blocks scan, incomplete scan blocks auto-register, provider tokenId 782224 read-first path safe

@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: b118774d2f

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

Comment thread apps/arclayer-runner/src/identity-ensure.ts Outdated
Comment thread apps/arclayer-runner/src/identity-ensure.ts
Comment thread apps/arclayer-runner/src/identity-ensure.ts Outdated
Comment thread apps/arclayer-runner/src/identity-ensure.ts
…, P2 durable sync pending, P3 selectedAgentId single identity

P1: scanExistingIdentityOnChain now uses Transfer(*, wallet, tokenId) wildcard
instead of Transfer(0x0, wallet, tokenId) so identities minted to another
wallet and later transferred in are discovered.

P2: When Console sync returns retryable after pending tx finalizes, a durable
consoleSync.status=pending marker is written to identity.json. On next run,
Step 1 retries the sync before exiting via already_confirmed. Success clears
the marker.

P3: Single discovered identity now checks selectedAgentId match. If
ARCLAYER_AGENT_ID is set but does not match the wallet-owned tokenId, the
run fails with a clear mismatch message instead of silently confirming.

Tests: 12 new test cases covering all three fixes.
@riyannode
riyannode merged commit 25ce4a0 into main Jun 18, 2026
12 checks passed
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.

1 participant