Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/keys-secp256r1-export.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@agentcommercekit/keys": patch
---

Build the `./secp256r1` subpath export. The export was declared in `package.json`
but its entry was missing from `tsdown.config.ts`, so `dist/curves/secp256r1.{js,d.ts}`
were never emitted and importing `@agentcommercekit/keys/secp256r1` failed (and
`publint` flagged the missing files). Added the build entry so the export resolves.
42 changes: 42 additions & 0 deletions .changeset/web-identity-schemas-adoption.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
"@agentcommercekit/did": major
"@agentcommercekit/jwt": major
"@agentcommercekit/vc": major
"@agentcommercekit/caip": major
"@agentcommercekit/ack-id": major
"@agentcommercekit/ack-pay": major
"agentcommercekit": major
---

Adopt [`web-identity-schemas`](https://github.com/catena-labs/web-identity-schemas)
as the source of truth for DID/JWT/VC validation schemas and DID/JWT types, and
**drop Zod v3 support**.

Breaking changes:

- **Zod v3 is no longer supported.** The `./schemas/zod/v3` and `./schemas/zod/v4`
subpath exports are removed; each package now exports a single `./schemas/zod`
(Zod v4). The `zod` optional peer range is now `^4.0.0`. Import from
`@agentcommercekit/<pkg>/schemas/zod` instead of `.../schemas/zod/v3` or
`.../schemas/zod/v4`.
- **DID validation is stricter.** `didUriSchema` and `isDidUri` now enforce the
full DID-core syntax (via `web-identity-schemas`' `DidSchema`/`isDid`) instead of
a permissive `startsWith("did:")` check. Malformed DIDs that previously passed
are now rejected (and validation error details have changed).
- `DidUri` and `JwtString` are now re-exported from `web-identity-schemas` (`Did`
and `JwtString` respectively). They remain structurally compatible; `JwtString`
widens to `string`.
- **VC validation is stricter.** `credentialSchema` (and the `isCredential` guard
built on it) is now backed by w-i-s' `CredentialV1Schema`, which enforces the VC
Data Model v1.1 shape: the `@context` must start with the v1 core URI, `type`
must include `"VerifiableCredential"`, `issuanceDate` must be an ISO-8601
datetime, and `id` must be a URI. Loosely-shaped objects that the previous
hand-rolled schema accepted may now be rejected. ACK-issued credentials (always
v1) are unaffected, and the credential-verification path
(`parseJwtCredential`/`verifyParsedCredential`) is unchanged — it still uses a
separate structural guard, not this authoring schema.

`web-identity-schemas` is now a dependency of `did`, `jwt`, and `vc`. The VC
credential schema is now backed by w-i-s' `CredentialV1Schema` while preserving
ACK's issuer-normalization and `JwtProof2020` handling. CAIP, payment, A2A,
controller-claim, and `JwtProof2020` schemas remain hand-rolled.
8 changes: 3 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,15 @@ agentcommercekit (umbrella re-export)

### Dual Validation Schemas

Valibot is primary (runtime dependency); Zod is an optional peer everywhere. Most packages expose schemas through three files / four export paths:
Valibot is primary (runtime dependency); Zod (v4) is an optional peer everywhere. Standards-tracked DID/JWT/VC schemas come from the [`web-identity-schemas`](https://github.com/catena-labs/web-identity-schemas) package; ACK only hand-rolls the schemas w-i-s doesn't cover (CAIP, payment, A2A, controller-claim, JwtProof2020). Each package exposes schemas through two files / two export paths:

```
src/schemas/
├── valibot.ts → ./schemas/valibot
└── zod/
├── v3.ts → ./schemas/zod/v3 AND ./schemas/zod (alias)
└── v4.ts → ./schemas/zod/v4
└── zod.ts → ./schemas/zod (zod v4 only; zod v3 is not supported)
```

Adding a new type requires updating all three schema files **and** the `exports` map in `package.json` **and** the entry array in `tsdown.config.ts`. (`keys` is the exception — it exports curve-specific files and encoding, no schemas.)
Adding a new type requires updating both schema files **and** the `exports` map in `package.json` **and** the entry array in `tsdown.config.ts`. (`keys` is the exception — it exports curve-specific files and encoding, no schemas.)
Comment on lines +44 to +52

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language tag to the example fence.

The fenced block at Line 46 is missing a language identifier, which triggers MD040 in markdownlint.

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 46-46: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` around lines 44 - 52, The fenced code block in AGENTS.md
displaying the directory structure (starting with `src/schemas/` and showing the
valibot.ts and zod.ts files) is missing a language identifier on the opening
triple backticks, which violates the MD040 markdownlint rule. Add an appropriate
language tag such as `text` or `bash` to the opening backticks of this code
fence to resolve the linting error.

Source: Linters/SAST tools


### Dependencies

Expand Down
2 changes: 1 addition & 1 deletion demos/e2e/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Agent 1 (Client Agent):
)
logJson(await parseJwtCredential(ownershipVc1, resolver))
log(`
colors.dim("This VC, issued by User 1, proves they control Agent 1.")}
${colors.dim("This VC, issued by User 1, proves they control Agent 1.")}

${successMessage("User 1 and Agent 1 (Client) setup complete")}

Expand Down
27 changes: 14 additions & 13 deletions demos/skyfire-kya/src/kya-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ import {
type JwtString,
type Keypair,
} from "agentcommercekit"
import { jwtPayloadSchema } from "agentcommercekit/schemas/zod/v4"
import { jwtPayloadSchema } from "agentcommercekit/schemas/zod"
import { decodeJwt } from "jose"
import * as z from "zod/v4"
import * as z from "zod"

const skyfireKyaJwtPayloadSchema = z.object({
...jwtPayloadSchema.shape,
ssi: z.string(),
jti: z.string(),
bid: z.object({
agentName: z.string(),
ownerId: z.string(),
nameFirst: z.string(),
nameLast: z.string(),
}),
})
const skyfireKyaJwtPayloadSchema = z
.object({
ssi: z.string(),
jti: z.string(),
bid: z.object({
agentName: z.string(),
ownerId: z.string(),
nameFirst: z.string(),
nameLast: z.string(),
}),
})
.and(jwtPayloadSchema)

export type SkyfireKyaJwtPayload = z.output<typeof skyfireKyaJwtPayloadSchema>

Expand Down
5 changes: 0 additions & 5 deletions examples/issuer/src/routes/credentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,7 @@ describe("POST /credentials/controller", () => {
error: "Invalid request",
issues: [
{
kind: "schema",
type: "custom",
expected: "unknown",
received: '"not-a-valid-did"',
input: "not-a-valid-did",
message: "Invalid DID format",
path: [{ key: "controller", value: "not-a-valid-did" }],
},
],
Expand Down
5 changes: 0 additions & 5 deletions examples/issuer/src/routes/receipts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,7 @@ describe("POST /credentials/receipts", () => {
error: "Invalid request",
issues: [
{
kind: "schema",
type: "custom",
expected: "unknown",
received: '"invalid-did"',
input: "invalid-did",
message: "Invalid DID format",
path: [{ key: "payerDid", value: "invalid-did" }],
},
],
Expand Down
5 changes: 2 additions & 3 deletions packages/ack-id/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ isControllerClaim(credential.credentialSubject)

// Valibot schema
import { controllerClaimSchema } from "@agentcommercekit/ack-id/schemas/valibot"
// Zod v3 schema
import { controllerClaimSchema } from "@agentcommercekit/ack-id/schemas/zod/v3"
import { controllerClaimSchema } from "@agentcommercekit/ack-id/schemas/zod/v4"
// Zod schema
import { controllerClaimSchema } from "@agentcommercekit/ack-id/schemas/zod"
```

## A2A Support
Expand Down
26 changes: 5 additions & 21 deletions packages/ack-id/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,8 @@
"default": "./dist/schemas/valibot.js"
},
"./schemas/zod": {
"types": "./dist/schemas/zod/v3.d.ts",
"default": "./dist/schemas/zod/v3.js"
},
"./schemas/zod/v3": {
"types": "./dist/schemas/zod/v3.d.ts",
"default": "./dist/schemas/zod/v3.js"
},
"./schemas/zod/v4": {
"types": "./dist/schemas/zod/v4.d.ts",
"default": "./dist/schemas/zod/v4.js"
"types": "./dist/schemas/zod.d.ts",
"default": "./dist/schemas/zod.js"
},
"./a2a": {
"types": "./dist/a2a/index.d.ts",
Expand All @@ -53,16 +45,8 @@
"default": "./dist/a2a/schemas/valibot.js"
},
"./a2a/schemas/zod": {
"types": "./dist/a2a/schemas/zod/v3.d.ts",
"default": "./dist/a2a/schemas/zod/v3.js"
},
"./a2a/schemas/zod/v3": {
"types": "./dist/a2a/schemas/zod/v3.d.ts",
"default": "./dist/a2a/schemas/zod/v3.js"
},
"./a2a/schemas/zod/v4": {
"types": "./dist/a2a/schemas/zod/v4.d.ts",
"default": "./dist/a2a/schemas/zod/v4.js"
"types": "./dist/a2a/schemas/zod.d.ts",
"default": "./dist/a2a/schemas/zod.js"
}
},
"publishConfig": {
Expand Down Expand Up @@ -91,7 +75,7 @@
},
"peerDependencies": {
"@a2a-js/sdk": "^0.2.2",
"zod": "^3.25.0"
"zod": "^4.0.0"
},
"peerDependenciesMeta": {
"@a2a-js/sdk": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as z from "zod/v4"
import * as z from "zod"

const roleSchema = z.enum(["agent", "user"])

Expand Down
52 changes: 0 additions & 52 deletions packages/ack-id/src/a2a/schemas/zod/v3.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { z } from "zod/v3"
import * as z from "zod"

export const controllerClaimSchema = z.object({
id: z.string(),
Expand Down
6 changes: 0 additions & 6 deletions packages/ack-id/src/schemas/zod/v4.ts

This file was deleted.

6 changes: 2 additions & 4 deletions packages/ack-id/tsdown.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ export default defineConfig({
entry: [
"src/index.ts",
"src/schemas/valibot.ts",
"src/schemas/zod/v3.ts",
"src/schemas/zod/v4.ts",
"src/schemas/zod.ts",
"src/a2a/index.ts",
"src/a2a/schemas/zod/v3.ts",
"src/a2a/schemas/zod/v4.ts",
"src/a2a/schemas/zod.ts",
"src/a2a/schemas/valibot.ts",
],
dts: true,
Expand Down
5 changes: 2 additions & 3 deletions packages/ack-pay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,8 @@ isPaymentReceiptCredential(credential)

// Valibot schema
import { paymentRequestSchema } from "@agentcommercekit/ack-pay/schemas/valibot"
// Zod v3 schema
import { paymentRequestSchema } from "@agentcommercekit/ack-pay/schemas/zod/v3"
import { paymentRequestSchema } from "@agentcommercekit/ack-pay/schemas/zod/v4"
// Zod schema
import { paymentRequestSchema } from "@agentcommercekit/ack-pay/schemas/zod"
```

## Agent Commerce Kit Version
Expand Down
14 changes: 3 additions & 11 deletions packages/ack-pay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,8 @@
"default": "./dist/index.js"
},
"./schemas/zod": {
"types": "./dist/schemas/zod/v3.d.ts",
"default": "./dist/schemas/zod/v3.js"
},
"./schemas/zod/v3": {
"types": "./dist/schemas/zod/v3.d.ts",
"default": "./dist/schemas/zod/v3.js"
},
"./schemas/zod/v4": {
"types": "./dist/schemas/zod/v4.d.ts",
"default": "./dist/schemas/zod/v4.js"
"types": "./dist/schemas/zod.d.ts",
"default": "./dist/schemas/zod.js"
},
"./schemas/valibot": {
"types": "./dist/schemas/valibot.d.ts",
Expand Down Expand Up @@ -67,7 +59,7 @@
"zod": "catalog:"
},
"peerDependencies": {
"zod": "^3.25.0"
"zod": "^4.0.0"
},
"peerDependenciesMeta": {
"zod": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { didUriSchema } from "@agentcommercekit/did/schemas/zod/v4"
import { jwtStringSchema } from "@agentcommercekit/jwt/schemas/zod/v4"
import * as z from "zod/v4"
import { didUriSchema } from "@agentcommercekit/did/schemas/zod"
import { jwtStringSchema } from "@agentcommercekit/jwt/schemas/zod"
import * as z from "zod"

const urlOrDidUri = z.union([z.url(), didUriSchema])

Expand Down
33 changes: 0 additions & 33 deletions packages/ack-pay/src/schemas/zod/v3.ts

This file was deleted.

7 changes: 1 addition & 6 deletions packages/ack-pay/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { defineConfig } from "tsdown/config"

export default defineConfig({
entry: [
"src/index.ts",
"src/schemas/zod/v3.ts",
"src/schemas/zod/v4.ts",
"src/schemas/valibot.ts",
],
entry: ["src/index.ts", "src/schemas/zod.ts", "src/schemas/valibot.ts"],
dts: true,
silent: true,
})
2 changes: 1 addition & 1 deletion packages/agentcommercekit/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ This package only contains re-exports. If you need to add new functionality, add

- `src/index.ts` - Main re-exports
- `src/schemas/valibot.ts` - Aggregated valibot schemas
- `src/schemas/zod/v3.ts` / `v4.ts` - Aggregated zod schemas
- `src/schemas/zod.ts` - Aggregated zod schemas
- `src/a2a/` - A2A re-exports
Loading
Loading