Core concepts

Architecture

How the client, the host, the transport and storage fit together.

Two sides of the bridge

  • The game (client). Runs in an iframe and uses @hydraone-sdk/core. It talks to the host shell over postMessage.
  • The host. Runs in the page that embeds the game, for example the HydraOne App Center, and uses @hydraone-sdk/host. It owns the wallet connection, so the game never sees private keys.

Opened in a normal browser tab, a game has no host to talk to, and init() rejects with ERR_NOT_IN_IFRAME.

flowchart TB
    subgraph Host["HydraOne App Center (host shell)"]
        HW[Wallet connection, CIP-30]
        HS[Host storage]
        HC[Device controls and overlays]
    end

    subgraph Game["Game iframe"]
        C[WalletBridgeClient]
        A[GameAuthManager]
        T1[PostMessageTransport]
        S[IStorage adapters]
        C --> T1
        A --> C
        A --> S
    end

    T1 <-->|postMessage, origin checked| Host
    S -->|HostStorageRelayAdapter| T1

Core pieces

PieceRole
WalletBridgeClientPublic entry point. Owns the connection state, request timeouts and host events.
ITransportPort with send, onMessage and optional destroy. Everything above it is transport-agnostic.
PostMessageTransportIframe transport with origin and source validation and request/response correlation.
IStoragePort for async key-value storage.
GameAuthManagerCIP-8 login and JWT lifecycle on top of a client and a storage.

Ports (ITransport, IStorage) keep the core free of browser details. That is why the client can be tested against any transport, including a mock.

Next steps