Skip to content

feat(express): verify created addresses against client-supplied trusted keychains#9109

Merged
rajangarg047 merged 1 commit into
masterfrom
rajangarg047/wcn-1055-express-auto-verify-create
Jun 25, 2026
Merged

feat(express): verify created addresses against client-supplied trusted keychains#9109
rajangarg047 merged 1 commit into
masterfrom
rajangarg047/wcn-1055-express-auto-verify-create

Conversation

@rajangarg047

Copy link
Copy Markdown
Contributor

Summary

Adds an opt-in "bring your own trusted keys" check to address creation. When a createAddress request includes trustedKeychains (public key material the caller holds independently), Express locally re-derives each newly created address via coin.deriveAddress and fails the request (400) if it doesn't match the address the service returned — an independent verification folded into the create call, no client-side round-trip.

Why this (and how it differs from the SDK's existing check)

wallet.createAddress already verifies the new address — but using keychains it fetches from the same service (an integrity check; circular). This feature verifies against caller-supplied keys, so a match is an independent trust guarantee.

Key properties:

  • Per-request opt-in. Requests without trustedKeychains are completely unchanged — so other clients/coins are unaffected and no server config/flag is needed.
  • Caller opted in, so an unsupported coin/wallet surfaces a clear 400 rather than silently skipping the requested verification.
  • Works wherever local derivation exists: BTC/UTXO, ETH (MPC + forwarder), SOL.

Scope note

Token (e.g. SPL) deposit addresses derive differently (associated token account) and are not verified here yet — that path depends on token derivation (WCN-1054, PR #9080) and is a fast-follow. Token-address creates (onToken) are skipped rather than mismatched.

Changes

  • express typedRoute: add optional trustedKeychains to the createAddress body (reuses the address/derive keychain union codec).
  • express handler: handleV2CreateAddress runs verifyCreatedAddressesWithTrustedKeys when the field is present.

Context

WCN-1055 (FR-465 Phase 2) — requested by Bullish. Chose the client-supplied-keys approach (vs an operator keystore) so it's a single transparent create call with the full independent-trust guarantee and no server-side key management.

Test plan

  • tsc clean (express src); eslint 0 errors
  • 5 new tests: match → 200 (asserts derive called with the trusted keychains), mismatch → 400, unsupported coin → 400, omitted → no derive call, onToken → skipped
  • OpenAPI regenerates; vacuum 0 errors / 0 warnings with the new field
  • CI

🤖 Generated with Claude Code

@rajangarg047 rajangarg047 requested review from a team as code owners June 24, 2026 17:57
@linear-code

linear-code Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

WCN-1055

Comment thread modules/express/src/clientRoutes.ts Outdated
Comment thread modules/express/src/clientRoutes.ts Outdated
@rajangarg047 rajangarg047 force-pushed the rajangarg047/wcn-1055-express-auto-verify-create branch from d92773f to 16a192b Compare June 24, 2026 21:08
…ed keychains

Add an opt-in "bring your own trusted keys" check to address creation. When the
createAddress request includes trustedKeychains (public key material the caller
holds independently), Express locally re-derives each newly created address via
coin.deriveAddress and fails the request if it does not match what the service
returned — an independent verification folded into the create call, with no
client-side round-trip.

Unlike the SDK's built-in check (which verifies using keychains fetched from the
same service), this uses caller-supplied keys, so a match is an independent trust
guarantee. It is purely per-request opt-in: requests without trustedKeychains are
unchanged, so other clients/coins are unaffected, and no server config is needed.

The caller opted in, so an unsupported coin/wallet surfaces a clear 400 rather than
silently skipping. The createAddress result is modeled as a CreateAddressResult
type (reusing DeriveAddressOptions types) instead of any, and derivation failures
and mismatches alike map to 400.

Token (e.g. SPL) deposit addresses derive differently and are not verified here
yet (follows WCN-1054).

WCN-1055

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rajangarg047 rajangarg047 force-pushed the rajangarg047/wcn-1055-express-auto-verify-create branch from 16a192b to e5129b5 Compare June 24, 2026 21:09
@rajangarg047 rajangarg047 merged commit d426bd5 into master Jun 25, 2026
24 checks passed
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