Skip to content

fix(core): add CommunicationAdapter abstraction for cross-platform transport#124

Open
anthony23991 wants to merge 4 commits intomainfrom
feat/communication-adapter
Open

fix(core): add CommunicationAdapter abstraction for cross-platform transport#124
anthony23991 wants to merge 4 commits intomainfrom
feat/communication-adapter

Conversation

@anthony23991
Copy link
Copy Markdown
Collaborator

Problem: CrossPlatformSigner directly depended on the Communicator class, which uses window.open() / postMessage for browser popup communication. React Native has no popup windows, so the signing flow
couldn't work on mobile.

Solution: Extract a CommunicationAdapter interface, wrap the existing Communicator in a WebCommunicationAdapter, and make CrossPlatformSigner + JAWProvider depend on the interface instead of the concrete
class. Mobile apps can now provide their own adapter (e.g., deep links) by passing communicationAdapter in the SDK preference.

New files:

  • communicator/interface.ts — CommunicationAdapter interface + CommunicationAdapterConfig type. Defines the transport contract: init(), waitForReady(), postRequestAndWaitForResponse(), postMessage(),
    onMessage(), disconnect()
  • communicator/WebCommunicationAdapter.ts — Default adapter wrapping the existing Communicator class. Zero behavior change for web consumers

Core refactor:

  • CrossPlatformSigner.ts — Replaced Communicator dependency with CommunicationAdapter. Added "browser mode" (unencrypted flow) for mobile adapters that don't need DH key exchange. Calls adapter.init?.()
    for adapters that need configuration. Added defensive guards in decryptResponseMessage() for malformed responses
  • signer/utils.ts — createSigner() now accepts adapter instead of communicator, plus apiKey, keysUrl, showTestnets params
  • JAWProvider.ts — Uses preference.communicationAdapter ?? new WebCommunicationAdapter() as the adapter. Passes keysUrl, ens, showTestnets through to the signer

Supporting changes:

  • messages/rpcMessage.ts — Added { unencrypted: RPCResponse } to RPCResponseMessage.content union for mobile adapters returning plaintext responses
  • provider/interface.ts — Added optional communicationAdapter?: CommunicationAdapter to JawProviderPreference
  • provider/eip6963.ts — Added isBrowserEnvironment() check to skip EIP-6963 provider announcement in React Native (navigator.product === 'ReactNative', missing CustomEvent, missing window)
  • account/toJustanAccount.ts — Added getCode() check in getFactoryArgs() to skip factory data when account is already deployed (prevents bundler rejections on re-deploy)
  • communicator/index.ts — Re-exports CommunicationAdapter, CommunicationAdapterConfig, WebCommunicationAdapter
  • index.ts — Exports CommunicationAdapter and CommunicationAdapterConfig types from the public API

Tests:

  • CrossPlatformSigner.test.ts — Replaced vi.mock('communicator') with manual mockAdapter object. Updated all constructor calls, assertions
  • JAWProvider.test.ts — Removed Communicator mock. Updated createSigner assertions to match new params

Zero breaking changes for web consumers. WebCommunicationAdapter is created automatically when no custom adapter is provided. All existing SDK usage (JAW.create(), Mode.CrossPlatform, etc.) works exactly
as before.

Usage:

import { JAW, Mode } from '@jaw.id/core';

const sdk = JAW.create({
apiKey: 'key',
appName: 'My App',
preference: {
mode: Mode.CrossPlatform,
communicationAdapter: new MobileCommunicationAdapter(), // from @jaw/ui-native
},
});

@anthony23991 anthony23991 requested a review from Ghadi8 February 25, 2026 12:02
@vercel
Copy link
Copy Markdown

vercel bot commented Feb 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
jaw-docs Ignored Ignored Mar 13, 2026 9:32am
keys-jaw-id Ignored Ignored Mar 13, 2026 9:32am
playground Ignored Ignored Mar 13, 2026 9:32am

Request Review

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