Configuration for a Layr8 client.
Fields can be supplied explicitly or resolved from environment variables:
LAYR8_NODE_URL— WebSocket URL of the cloud-nodeLAYR8_API_KEY— authentication keyLAYR8_AGENT_DID— agent DID, the address other agents use to reach it (required; the cloud-node rejects a connection without a DID)LAYR8_ATTACH_GRANTS—"false"/"0"turns Verifiable Grant attachment offLAYR8_GRANT_CACHE_MS— how long held grants are cachedLAYR8_GRANT_READ_TIMEOUT_MS— deadline on the credential readLAYR8_REST_TIMEOUT_MS— deadline on every other REST call
HTTP(S) URLs are automatically normalized to WebSocket scheme:
https://→wss://http://→ws://
Example
config = Layr8.Config.resolve!(%{node_url: "wss://node.example.com/plugin_socket/websocket", api_key: "secret"})
Summary
Functions
Default grant cache TTL. Short: a grant minted seconds ago is invisible until it lapses.
Default deadline on the credential read.
Default deadline on every other REST call.
Resolves a config map or struct, filling missing fields from environment variables, normalizing the URL scheme, and validating required fields.
Derives the REST API base URL from a WebSocket URL.
Types
@type t() :: %Layr8.Config{ agent_did: String.t(), api_key: String.t(), attach_grants: boolean(), grant_cache_ms: non_neg_integer(), grant_read_timeout_ms: pos_integer(), node_url: String.t(), rest_timeout_ms: non_neg_integer() }
Functions
Default grant cache TTL. Short: a grant minted seconds ago is invisible until it lapses.
Default deadline on the credential read.
Two seconds, chosen from both ends: it is a JSON GET to the same node this client already holds a WebSocket to, so the honest answer arrives in milliseconds — two seconds survives a cold node, a warming connection pool and a GC pause. And it sits comfortably under the wallet's 5s failure cache, which is measured from the START of the read; a deadline at or above that TTL would leave the failure lapsed the moment it was recorded, so every send would pay the full deadline instead of one per window.
Default deadline on every other REST call.
Thirty seconds, and the number matters less than what it is measured on: this is a deadline on socket INACTIVITY, not on total elapsed time. While the node signs or verifies a credential, no bytes flow — indistinguishable on the wire from a node that has stopped answering — so this WILL cut off a sign that is merely slow. 30s is far above any honest sign against a node this client already holds a WebSocket to, and far below any duration a person watching would still call "working" rather than "hung".
Resolves a config map or struct, filling missing fields from environment variables, normalizing the URL scheme, and validating required fields.
Raises Layr8.Error if required fields are missing.
Derives the REST API base URL from a WebSocket URL.
iex> Layr8.Config.rest_url_from_websocket("wss://node.example.com/plugin_socket/websocket")
"https://node.example.com"
iex> Layr8.Config.rest_url_from_websocket("ws://localhost:4000/plugin_socket/websocket")
"http://localhost:4000"