Skip to content

sdk: require ox >= 0.14.12 for Schema 2 service codes - #16

Open
GigaHierz wants to merge 1 commit into
mainfrom
GigaHierz/review-issues-open-prs
Open

GigaHierz wants to merge 1 commit into
mainfrom
GigaHierz/review-issues-open-prs

Conversation

@GigaHierz

Copy link
Copy Markdown
Collaborator

Closes #15.

The problem

sdk/package.json declared "ox": "^0.14.8", but the ERC-8021 Schema 2 service role (the CBOR s key) only landed in ox 0.14.12. Verified by unpacking the published tarballs and diffing erc8021/Attribution.ts:

ox version serviceCodes
0.14.8, 0.14.11 absent — getSchemaId checks appCode / walletCode / codeRegistry only
0.14.12+ present — getSchemaId also checks serviceCodes

toDataSuffix branches on getSchemaId and ignores the explicit id: 2 we pass, so on a tree resolving ox 0.14.8–0.14.11 toRoleDataSuffix corrupted tags silently:

  1. service-only tag → Schema 0 selected → the Schema 0 encoder reads attribution.codes (never set for a role attribution) → empty 00 00 <marker> suffix;
  2. app + service tag → Schema 2 selected, but the 0.14.8 CBOR builder never reads serviceCodes → the s codes are dropped.

Not breaking in-repo (the lockfile resolves 0.14.20), and toRoleDataSuffix has never shipped — 0.4.0 is merged but unpublished, so this lands before the release rather than as a fix on top of it. The exposure is any consumer whose tree constrains ox lower.

Changes

  • sdk/package.json: ox floor ^0.14.8^0.14.12; lockfile specifier refreshed (resolution stays 0.14.20, which satisfies the new range). Deliberately not widened to || ^1.xviem still resolves ox on the 0.14 line, so staying there avoids a duplicate ox install for consumers.
  • sdk/src/index.ts: toRoleDataSuffix now decodes the suffix it just encoded and throws if the roles don't round-trip, naming the ox floor in the error. A consumer who forces an older ox through an override or a stale transitive pin now fails loudly instead of emitting a corrupt tag. One decode per encode; encoding happens once per transaction.
  • sdk/tests/roles.test.ts: adds the missing service-only round-trip (byte-identical to ox's own Schema 2 encoding, correct schema byte and marker) and a wallet+service round-trip — the suite previously never covered a Schema 2 tag without an app or wallet code.
  • sdk/tests/ox-floor.test.ts (new): mocks ox/erc8021 back to pre-0.14.12 behaviour and asserts both corruption modes now throw, with an app+wallet case as a positive control. Confirmed the two corruption assertions fail when the guard is removed.

Verification

pnpm install --frozen-lockfile, pnpm typecheck, pnpm test (54 passing across 5 files), pnpm build all clean locally; pnpm why ox shows a single ox 0.14.20 in the tree.

🤖 Generated with Claude Code

`sdk/package.json` declared `ox: ^0.14.8`, but the ERC-8021 Schema 2
service role (the CBOR `s` key) only landed in ox 0.14.12. Verified
against the published tarballs: in 0.14.8 and 0.14.11, `getSchemaId`
checks `appCode` / `walletCode` / `codeRegistry` only, and `toDataSuffix`
branches on it while ignoring the explicit `id` we pass.

On a tree that resolves ox 0.14.8-0.14.11 that produced two silent
corruptions:

- a service-only tag selected Schema 0, whose encoder reads
  `attribution.codes` (never set for a role attribution), emitting an
  empty `00 00 <marker>` suffix;
- an app+service tag encoded as Schema 2 but dropped the `s` codes.

Changes:

- raise the floor to `^0.14.12` (lockfile still resolves 0.14.20, which
  the new range satisfies; `viem` also stays on the 0.14 line, so no
  duplicate ox);
- self-check the encoded suffix in `toRoleDataSuffix` and throw if the
  roles don't round-trip, so a consumer who forces an older ox via an
  override or a stale transitive pin fails loudly instead of emitting a
  corrupt tag;
- add the missing service-only and wallet+service round-trip vectors,
  plus a test that mocks ox back to pre-0.14.12 behaviour and asserts the
  guard fires.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

x402 watch 2026-08-10: action needed

1 participant