@eternl/node-bridge
v0.42.0
Published
Minimal local Cardano node socket bridge for Eternl web and extension connections
Keywords
Readme
@eternl/node-bridge
A small local WebSocket-to-node-socket relay for Eternl. Run it next to an already running cardano-node or Dingo node, find it in Eternl's Custom connection modal, and click Connect. Manual import of its printed connection details remains available in the collapsed manual section. No bridge credential, bridge ID, pairing file, wallet key or Atlas checkout is required to use the published package. Node compatibility still requires separate verification in Eternl.
Run
Requires Node.js 22 or newer and access to the node's local socket and public configuration/genesis files. Version 0.42.0 is prepared for the first public package release and remains unpublished. The package-runner examples below apply after publication. The matching Eternl connection flow is required (older pairing-based builds are incompatible).
npx @eternl/[email protected] --socket "/path/to/node.socket" --node-config "/path/to/config.json"Equivalent runners:
pnpm dlx @eternl/[email protected] --socket "/path/to/node.socket" --node-config "/path/to/config.json"
bunx @eternl/[email protected] --socket "/path/to/node.socket" --node-config "/path/to/config.json"
npm exec --package=@eternl/[email protected] -- eternl-node-bridge --socket "/path/to/node.socket" --node-config "/path/to/config.json"The node config's ShelleyGenesisFile is resolved relative to that config. Alternatively pass --genesis /path/to/shelley-genesis.json, including when the node configuration uses another format. CARDANO_NODE_SOCKET_PATH can replace --socket for either node implementation. The bridge derives magic and system start from the selected genesis and computes SHA-256 of its exact bytes for a stable local chain fingerprint. This fingerprint is not cardano-node's ShelleyGenesisHash field/algorithm. Eternl cross-checks node queries before using that chain's storage.
Compatibility cannot be inferred from a socket or network magic. Add the node's actual --node-version and Eternl --profile when known. For the verified Musashi development node, for example:
npx @eternl/[email protected] --socket "/path/to/node.socket" --node-config "/path/to/config.json" --node-version 11.1.0.164 --profile cardano-node-musashi-2026w40aSelect Dingo explicitly with --node-type dingo; omitted --node-type means cardano-node. Only these two exact values are accepted. The choice controls public implementation metadata and the default label, not the forwarded bytes. Current local Musashi validation uses the separately patched Dingo 0.83.0-eternl.1 build because upstream 0.83.0 omits resolved Leios transactions from some local block responses. The bridge does not contain or install this node patch. From the Atlas checkout:
node packages/node-bridge/dist/cli.mjs --node-type dingo --socket "/path/to/dingo.socket" --genesis "/path/to/shelley-genesis.json" --node-version 0.83.0-eternl.1 --profile dingo-musashi-0.83.0-eternl.1This example declares the intended test profile; it does not establish end-to-end Dingo compatibility. Live node query and recovery verification and matching frontend support are separate acceptance gates. Unknown version/profile values remain unknown and Eternl must resolve supported compatibility before synchronizing. The relay does not probe the node release, negotiate ledger protocols or enable unverified node implementations or ledger profiles.
Keep the command running. Open Eternl's Custom connection modal or select Find local nodes. The modal checks loopback ports 7781–7785 plus saved endpoints (at most 12 distinct endpoints, two simultaneous probes) and can preselect one compatible result for a new connection. Discovery advertises configuration only; Connect still verifies the node and chain. If discovery is unavailable, expand Manual connection and saved settings and paste the complete JSON line following Connection details. The line contains public endpoint and node metadata only. Saved settings can be reused after reload, but Connect remains explicit. Ctrl-C stops the bridge and its connections; it never stops the selected node. The bridge does not install or start a node or a background service.
Origins and options
The listener defaults to ws://127.0.0.1:7781/bridge. Default allowed origins are https://eternl.io and the production extension chrome-extension://kmhcihpebfmpgmihbkipmjlmmioameka. For an unpacked/beta extension, add --origin chrome-extension://YOUR_ACTUAL_EXTENSION_ID; for development use --origin http://localhost:9000. Repeat the option for additional exact origins. Wildcard origins are rejected. An ID from another installation does not authorize yours.
Use --port NUMBER when 7781 is occupied; ports 7782–7785 are also discovered by default. For other ports, import the updated output once so the saved endpoint can be probed. --label TEXT sets the connection label. --network-magic NUMBER optionally cross-checks the genesis value. --help lists all options. Missing/inaccessible sockets, invalid public metadata and unavailable ports fail without claiming readiness. A listening bridge does not prove node synchronization or wallet readiness.
The website may need the browser's local-network permission. CSP, secure-page loopback access and extension permissions are independent of this relay. Do not disable browser protections or ignore certificate errors; use a supported Eternl deployment/browser. Actual website and extension integration acceptance is separate from package transport tests.
Local trust boundary
This package intentionally uses no bearer authentication. It binds to loopback, validates exact WebSocket Origin/Host/path values, opens only configured sockets and bounds messages, queues, timeouts and connections. This excludes unapproved websites; it does not authenticate local software, which can forge Origin headers. Use it only on a trusted local machine. It is not a LAN/public node gateway or isolation between local users.
All forwarded bytes are opaque node-to-client protocol data. Wallet signing stays in Eternl. The bridge has no ledger decoder, transaction builder, history index, wallet store, arbitrary path-selection API, credential store or private @eternl/* runtime dependency. Its sole runtime dependency is ws.
Library and wire contract
The root export provides startNodeBridge, runBridgeCommand and option types for Node hosts. @eternl/node-bridge/connection is browser-safe and exposes parsing/formatting of the bounded public connection block and protocol constants. NodeMetadata.implementation accepts only cardano-node or dingo; the supplied nodeVersion and profileId remain public claims for the consumer to verify. Never import the Node root into a browser bundle.
After WebSocket admission, a discovery client can send one text message:
{"type":"discover","protocol":"eternl-node-bridge","version":1}The bridge returns type: "discovered", the same protocol/version and a nodes array of configured public metadata, then closes the probe. It does not open a node socket. Discovery uses the same exact Origin/Host/path admission, timeouts and message bounds as connection setup. No socket paths or endpoint redirects are advertised. parseDiscoveryResponse in the browser-safe connection export validates the bounded response and unique node IDs. Advertised configuration is not verified chain state or readiness. Older bridges without discovery still support manual connection.
The complete discovery response must fit the default 16,384-byte control limit, and the browser parser enforces that same ceiling. The CLI advertises one node. Library hosts can configure up to 64 nodes, but an oversized aggregate response closes the probe without returning metadata or opening a node socket; explicit connection to an individual configured node remains available.
To connect, the client opens a new WebSocket and sends:
{"type":"connect","protocol":"eternl-node-bridge","version":1,"nodeId":"node"}Once the configured socket connects, the server replies with type: "connected", the same protocol/version, and the selected public node metadata. No filesystem path is returned. The remaining messages are binary fragments of a single ordered byte stream. Extra control messages, unsupported versions, unknown aliases or limit violations close the connection. Each reconnect starts a new stream and protocol handshake.
Source and publication
The bounded relay was extracted from packages/custom-network-backend/src/bridge/server.ts. Pairing/credential logic and private query dependencies were excluded. New CLI/config parsing and the public connection contract live in separate files. Tests use temporary echo sockets and synthetic public configuration, not wallet secrets or private fixtures.
Public access is explicitly authorized for this package. Licensed under BUSL-1.1 by Tastenkunst GmbH (Germany), Additional Use Grant: None; each version changes to GPL v2 or later four years after its first public distribution. See LICENSE; commercial licensing: https://tastenkunst.com/.
