Skip to content

feat(tii)!: interpret the full complex param-type model#34

Merged
scarmuega merged 2 commits into
mainfrom
feat/complex-param-types
Jun 12, 2026
Merged

feat(tii)!: interpret the full complex param-type model#34
scarmuega merged 2 commits into
mainfrom
feat/complex-param-types

Conversation

@scarmuega

Copy link
Copy Markdown
Contributor

Summary

Extends ParamType to interpret every shape tx3c emits into the TII params schema, per the canonical model in the SDK spec's api-surface/args.md. The web-sdk slice of a cross-fleet complex-type parity effort (rust/go/python/web). Builds on the earlier list/tuple + trailing-name $ref work.

Changes

  • Adds unit / utxo / anyAsset / map(value) / record(fields) / variant(cases) kinds. The previous object→custom and oneOf→custom now resolve to structured record / variant, and additionalProperties to map.
  • Resolves #/components/schemas/<Name> refs into the components table and recurses (previously wrapped opaquely without recursing).
  • Never throws — unrecognized shapes (bare string, unresolved object, unknown $ref, array without items/prefixItems) become unknown carrying the raw schema.

Tests

npm test — 131 pass (rewritten paramType.test.ts over the full canonical table incl. both ref forms, nested compounds, map/record/variant, component resolution, and never-throw fallbacks). tsc --noEmit clean.

Cross-checked against the shared fixture sdk-spec/test-vectors/complex-types/complex.tii.

Breaking change

The custom kind is renamed to unknown, and fromJsonSchema / paramsFromSchema no longer throw InvalidParamTypeError (they return unknown). Needs a version bump per sdk-spec/release-policy.md.

🤖 Generated with Claude Code

Extend `ParamType` to interpret every shape `tx3c` emits into the TII params
schema, per the canonical model in the SDK spec's `api-surface/args.md`.

- Add `unit`, `utxo`, `anyAsset`, `map` (value), `record` (fields), and
  `variant` (cases) kinds; the previous `object`→custom and `oneOf`→custom now
  resolve to structured `record`/`variant`, and `additionalProperties` to `map`.
- Resolve `#/components/schemas/<Name>` refs into the components table and
  recurse (previously wrapped opaquely as custom without recursing).
- `fromJsonSchema` never throws: unrecognized shapes (bare `string`, unresolved
  object, unknown `$ref`, array without items/prefixItems) become `unknown`
  carrying the raw schema. A bare `string` is no longer assumed to be untyped.

Builds on the earlier list/tuple + trailing-name `$ref` support.

BREAKING CHANGE: the `custom` kind is renamed to `unknown`, and `fromJsonSchema`
/ `paramsFromSchema` no longer throw `InvalidParamTypeError` (they return
`unknown` instead).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ver invoke path

Behavior-preserving readability pass over the complex-param-type work, mirroring
the rust/go/python siblings — identical kind map, all tests still pass.

- Split fromJsonSchema into a thin dispatcher; extract the $ref / array / object
  arms into refType / arrayType / objectType (joining coreRefType / variantCase).
- Remove the now-dead InvalidParamTypeError (this PR removed its throw sites) and
  the never-wired InvalidParamsSchemaError; go-sdk carries neither.
- Add tests/fixtures/complex.tii and a Protocol.invoke integration test that
  guards components threading (resolved Record field + Variant cases), party
  Address params, and environment-schema params.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@scarmuega

Copy link
Copy Markdown
Contributor Author

Follow-up readability pass (commit 72458e6) — behavior-preserving, same code-quality lens applied to the rust/go/python siblings. Identical kind map, tsc --noEmit clean, 132 tests pass (was 131).

Module cohesion — already good, no change. paramType.ts is already a cohesive, self-contained module (type + factories + interpreter + paramsFromSchema + ParamMap), separate from protocol/invocation/errors/spec. Nothing to move.

Decompose fromJsonSchema. It was a ~76-line function with the $ref, array, and object arms inlined as nested blocks. Reduced to a thin dispatcher that reads as the canonical model from api-surface/args.md; the three arms are now refType / arrayType / objectType, joining the already-extracted coreRefType / variantCase. Each helper falls back to unknown exactly as the inline code did — same fallbacks, same recursion.

Drop dead error classes. This PR removed the four throw new InvalidParamTypeError(...) sites in fromJsonSchema (everything now falls back to unknown), leaving the class unconstructed — removed it. InvalidParamsSchemaError was introduced unused in the spec-compliance commit and has never been thrown in the repo's history — removed it too. go-sdk carries neither error type, so this aligns the surface; the breaking ! bump already covers it.

Close the Protocol.invoke integration gap. paramType.test.ts exercises the interpreter in isolation with hand-built component maps; protocol.test.ts only invoked transfer.tii (all primitives). Nothing drove the two things this PR added at the Protocol level: threading spec.components.schemas into paramsFromSchema, and producing compound ParamTypes from a real TII. Added tests/fixtures/complex.tii (the shared sdk-spec vector) and one invoke('complex') test asserting the compound kinds, lowercased party Addresses, the fee environment param, and — the assertion that actually guards the components threading — asset's resolved Record policy: bytes field and side's two Variant cases.

@scarmuega scarmuega merged commit a44d3a6 into main Jun 12, 2026
7 of 9 checks passed
@scarmuega scarmuega deleted the feat/complex-param-types branch June 12, 2026 19:31
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