/** * SDK glue. The {@link createShadeBridgeFromShade} helper turns any Shade- * shaped object into a {@link ShadeBridge} suitable for * `WebRtcSignalingChannel`. Kept in its own file so the package can be * consumed standalone (e.g. by tests with a memory bridge) without * pulling in the full SDK type tree. */ import type { ShadeBridge } from './signaling.js'; /** * Minimal shape of `Shade` we depend on. The real `@shade/sdk` `Shade` * class satisfies this structurally; declaring it locally avoids a * circular dependency on `@shade/sdk` in this package's `package.json`. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export interface ShadeLike { readonly myAddress: string; // The real SDK returns a `ShadeEnvelope`; we accept anything because the // bridge just hands it back to `deliverControlEnvelope`. // eslint-disable-next-line @typescript-eslint/no-explicit-any send(address: string, plaintext: string): Promise; onMessage(handler: (from: string, plaintext: string) => void | Promise): () => void; /** * Optional. When present (the real SDK provides it), the bridge calls * `deliverControlEnvelope` after `send()` so the encrypted envelope * actually reaches the peer over HTTP. When absent (memory tests or * custom transports), `send()` alone is enough. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any deliverControlEnvelope?: (peer: string, envelope: any) => Promise; } /** * Adapt a `Shade`-shaped instance to the {@link ShadeBridge} interface used * by `WebRtcSignalingChannel`. Each `bridge.send` calls * `shade.send(plaintext)` to ratchet-encrypt the signaling JSON, then — * when available — `shade.deliverControlEnvelope(...)` to actually ship the * envelope to the peer. */ export function createShadeBridgeFromShade(shade: ShadeLike): ShadeBridge { return { myAddress: shade.myAddress, async send(peerAddress: string, plaintext: string): Promise { const envelope = await shade.send(peerAddress, plaintext); if (shade.deliverControlEnvelope !== undefined) { await shade.deliverControlEnvelope(peerAddress, envelope); } }, onMessage(handler) { return shade.onMessage(handler); }, }; }