Skip to content

feat(facade): unified Tx3ClientBuilder for §3.3/§3.6 parity#29

Merged
scarmuega merged 3 commits into
mainfrom
feat/unified-builder
May 24, 2026
Merged

feat(facade): unified Tx3ClientBuilder for §3.3/§3.6 parity#29
scarmuega merged 3 commits into
mainfrom
feat/unified-builder

Conversation

@scarmuega

Copy link
Copy Markdown
Contributor

Summary

Ports the unified-builder pattern from rust-sdk (already on codegen-v1beta0-4-g761a685) into web-sdk so the §3.3/§3.6 facade rows of sdks/parity-matrix.md flip ❌→✅.

  • New Tx3ClientBuilder (with Protocol.client() + fromParts(...) seeders, trp / trpEndpoint / withHeader / withProfile / withParty / withParties / withPartyUnchecked / withEnvValue setters, single build() terminal).
  • Tx3Client now owns the deconstructed protocol parts; withProfile is builder-only (removed from the built client per §3.6); tx(name) throws UnknownTxError at call site.
  • TxBuilder is source-agnostic — both dynamic and codegen flows drive the same resolve() path.
  • New BuilderError family + MissingTrpEndpointError; UnknownPartyError re-parented from ResolutionErrorBuilderError (still Tx3Error-rooted, still instanceof-discriminable).
  • Codegen template (.trix/client-lib/protocol.ts.hbs) now wraps Tx3ClientBuilder.fromParts(...); per-party setters route through withPartyUnchecked; profiles emitted as individual SdkProfile consts with a typed Profile string-union.
  • Top-level re-exports add Tx3ClientBuilder, Profile, BuilderError, MissingTrpEndpointError.

Spec references: sdks/sdk-spec/api-surface/facade.md §3.3, §3.4, §3.6; sdks/sdk-spec/codegen/generated-surface.md §C.3a–d.

Breaking changes

  • new Tx3Client(protocol, trp) is gone — construct via protocol.client()...build() instead.
  • Tx3Client.withProfile(name) removed — call withProfile on the builder (switching profiles now requires a new client).
  • tx(name) throws UnknownTxError synchronously instead of deferring to resolve().
  • UnknownPartyError's parent class changed (ResolutionErrorBuilderError); both still extend Tx3Error.
  • Client-side MissingParamsError pre-flight removed (TRP server still emits MissingTxArgError).

Test plan

  • npm run type-check clean
  • npm run test:unit120/120 pass (12 new builder-pattern tests)
  • tx3c codegen against sdk/tests/fixtures/transfer.tii renders all expected symbols (Tx3ClientBuilder, fromParts, TransferParams, TRANSFER_TIR, per-party withSender/withReceiver/withMiddleman)
  • codegen-check.sh will fail in CI until this lands on npm — the script installs tx3-sdk@latest, which is still v0.11.0 without Tx3ClientBuilder. Expected for a template flip (same situation when rust-sdk landed this pattern).

🤖 Generated with Claude Code

scarmuega and others added 3 commits May 24, 2026 12:45
….6 parity

Adds Tx3ClientBuilder with the two seeding entry points (Protocol.client() for
the dynamic flow and Tx3ClientBuilder.fromParts(...) for the codegen flow),
the mandatory trp/trpEndpoint setters, optional withProfile / withParty /
withParties / withPartyUnchecked / withHeader / withEnvValue, and a single
build() terminal that throws MissingTrpEndpointError, UnknownProfileError, or
UnknownPartyError. New BuilderError class family under Tx3Error makes the
builder errors discriminable via instanceof.

Removes withProfile from the built Tx3Client (profile selection is builder-
only per §3.6) and makes tx(name) throw UnknownTxError at the call site
instead of deferring to resolve(). Late-binding withParty / withPartyUnchecked
/ withParties still available on the built client.

TxBuilder is now source-agnostic: it holds the TIR envelope, env, parties,
and args directly, so the dynamic and codegen flows drive an identical
resolve() path. Removes the client-side MissingParamsError pre-flight (TRP's
MissingTxArgError already covers this server-side); the class is kept exported
for forward compat.

Codegen template now wraps Tx3ClientBuilder.fromParts(...) instead of
re-implementing client state. The generated Client adds only the typed
per-tx params, per-tx methods, per-party setters (routing through
withPartyUnchecked), embedded TIR / profile constants, and a typed Profile
union when profiles are declared.

Top-level re-exports add Tx3ClientBuilder, Profile, BuilderError,
MissingTrpEndpointError.

Tests rewritten against the new builder API; 120/120 pass.

Spec: sdks/sdk-spec/api-surface/facade.md §3.3, §3.4, §3.6;
      sdks/sdk-spec/codegen/generated-surface.md §C.3a–d.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updates the quick-start example to use protocol.client()...build() instead
of new Tx3Client(protocol, trp). Expands the concepts table with
Tx3ClientBuilder, Profile, and BuilderError. Adds a fromParts walkthrough
under "Skipping the runtime .tii (codegen flow)" and rewrites the CIP-30
example to drive the builder.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The e2e harness still constructed Tx3Client directly via the removed
`new Tx3Client(protocol, trp).withProfile(...)` shape. Routes through
`protocol.client().trpEndpoint(...).withProfile(...).withHeader(...).build()`
instead; `dmtr-api-key` is now attached via the builder's `withHeader` setter
rather than a separately-constructed TrpClient.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@scarmuega scarmuega merged commit 54345ae into main May 24, 2026
2 of 3 checks passed
scarmuega added a commit that referenced this pull request May 24, 2026
Aligns the web-sdk package version with the fleet's 0.12 release train
(rust-sdk workspace is already at 0.12.0). The unified Tx3ClientBuilder
landed in #29 and is a breaking change — per
sdks/sdk-spec/release-policy.md any change to MAJOR or MINOR must be
coordinated across all SDKs.

Co-authored-by: Claude Opus 4.7 (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.

1 participant