Skip to content

feat(core): add agent-identity extension (ERC-8004) - #91

Open
GentechLabs wants to merge 1 commit into
qntx:mainfrom
GentechLabs:feat/agent-identity-extension
Open

feat(core): add agent-identity extension (ERC-8004)#91
GentechLabs wants to merge 1 commit into
qntx:mainfrom
GentechLabs:feat/agent-identity-extension

Conversation

@GentechLabs

Copy link
Copy Markdown

Implements the gap proposed in #87 — happy to adjust design per maintainer direction.

Summary

Adds an opt-in agent-identity x402 v2 extension to r402-core behind the ext-agent-identity feature flag, binding an optional ERC-8004 agent id to a payment:

  • Advertise — sellers attach info.required plus a JSON schema to PaymentRequired.extensions under the agent-identity key.
  • Verify / Settle — the facilitator validates the client-supplied agentId (length bound, no whitespace/control chars) and surfaces it in the response extensions, so downstream treasuries and compliance hooks can attribute and gate spend per agent instead of per shared wallet.
  • Chain-agnostic — the agent id is an opaque string (eip155:1:0x…, urn:erc8004:agent:42, …). The ERC-8004 registry is EVM-first, but the binding is a plain field, so it composes with any scheme (exact, upto, …).

Follows the existing extension patterns: module shape mirrors payment-identifier, ext-* feature flag wired into all-extensions/full, README feature-table row, CHANGELOG entry. On the open question in #87, the id rides the extension info object rather than a separate signed claim — it survives facilitator settlement without extra round-trips, and signing stays scheme-side.

Testing

  • cargo test -p r402-core --features ext-agent-identity --lib → 95 passed, 0 failed (10 new tests: wire shape, extraction variants, validation rules, hook behavior)
  • cargo clippy -p r402-core --all-features --all-targets → clean
  • cargo fmt (stable) applied

Adds an opt-in `agent-identity` x402 v2 extension to r402-core behind the `ext-agent-identity` feature flag, binding an optional ERC-8004 agent id to a payment. The id is advertised to clients, validated (length, no whitespace/control chars), and surfaced in verify/settle responses so downstream treasuries and compliance hooks can attribute and gate spend per agent rather than per shared wallet. Chain-agnostic: the id is an opaque string (ERC-8004 registry is EVM-first, the binding is a plain field). Composes with any scheme. Refs qntx#87.
@gitctrlx

Copy link
Copy Markdown
Member

Can't merge this.

agent-identity isn't an x402 spec extension, and an unsigned string isn't ERC-8004 — that's https://github.com/qntx/erc8004. on_verify also never actually rejects the payment.

@GentechLabs

Copy link
Copy Markdown
Author

Confirmed on all three points — thanks for the direct review. Re-reading the trait contract after your note: on_verify is decoration by design (Option<ExtensionEntry>), so it structurally can't reject — a status field on the response entry is nothing anyone should trust for payments. And a length-bound opaque string "identity" is a claim, not a credential — an unsigned, unauthenticated attestation, not ERC-8004.

Where we landed, matching your split:

The right home for enforcement is the facilitator's verify step. The extension point the trait doesn't have today is a pre-result hook that can reject: a verifier trait resolved from the registry inside verify, returning Err/invalid VerifyResponse before the (valid) response is assembled — with the ERC-8004 registry read and the payment-hash binding happening there. Without that, any identity payload is just metadata riding along.

Identity resolution belongs in qntx/erc8004 (per your cross-ref). We'd rather build that as an erc8004-side verifier/consumer of this SDK than wedge it into a wire extension.

Plan from here — your call on all of it:

  1. Leave this PR as-is (no pushes) as the record of the wrong shape — or close it; either is fine with us.
  2. If you want the verifier hook in r402-core, we'll spec it against VerifyContext/VerifyResponse and open a smaller PR with a no-op default so existing extensions are untouched.
  3. ERC-8004 resolution + signature binding moves to a verifier behind that hook (or straight into erc8004, your preference).

Noted on us for next time: protocol-level contributions here start at the trait/facilitator layer, not payload decoration.

— GenTech Labs (production multi-facilitator x402 gateway; v1/v2 facilitator quirks)

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.

2 participants