Layr8.Client (layr8 v0.2.6)

Copy Markdown View Source

Main entry point for interacting with the Layr8 platform.

Lifecycle

# 1. Start the client
{:ok, client} = Layr8.Client.start_link(%{
  node_url: "wss://node.example.com/plugin_socket/websocket",
  api_key: "my-api-key"
})

# 2. Register message handlers BEFORE connect
:ok = Layr8.Client.handle(client, "https://example.com/proto/1.0/request", fn msg ->
  {:reply, %Layr8.Message{type: "https://example.com/proto/1.0/response", body: %{text: "pong"}}}
end)

# 3. Connect to the cloud-node
:ok = Layr8.Client.connect(client)

# 4. Send messages
:ok = Layr8.Client.send(client, %Layr8.Message{
  type: "https://example.com/proto/1.0/request",
  to: ["did:example:bob"],
  body: %{text: "ping"}
})

# 5. Request/response
{:ok, response} = Layr8.Client.request(client, %Layr8.Message{
  type: "https://example.com/proto/1.0/request",
  to: ["did:example:bob"],
  body: %{text: "ping"}
})

# 6. Shut down
:ok = Layr8.Client.close(client)

Events

Subscribe to lifecycle events by passing callbacks in start_link/1 opts:

  • :on_disconnect(reason :: term() -> any())
  • :on_reconnect(() -> any())

Credentials & Presentations

Credential and presentation operations use the REST API (no WebSocket required):

{:ok, jwt} = Layr8.Client.sign_credential(client, credential, issuer_did: "did:example:alice")

Summary

Functions

Returns a specification to start this module under a supervisor.

Gracefully shuts down the client.

Establishes the WebSocket connection and joins the Phoenix channel.

Returns the agent's DID — either provided in config or assigned by the node on connect.

Retrieves a stored credential by ID.

Registers a handler for a DIDComm message type.

Registers a catch-all handler invoked when no specific handler matches.

Lists stored credentials for a holder. Defaults: holder = did/1.

Sends a DIDComm message and waits for a correlated response (matched by thread ID).

Sends a DIDComm message.

Signs a W3C Verifiable Credential. Defaults: issuer = did/1, format = "compact_jwt".

Signs a W3C Verifiable Presentation. Defaults: holder = did/1, format = "compact_jwt".

Starts the Layr8 Client GenServer.

Stores a signed credential JWT for a holder. Defaults: holder = did/1.

Verifies a signed credential. Defaults: verifier = did/1.

Verifies a signed presentation. Defaults: verifier = did/1.

Types

start_opts()

@type start_opts() :: %{
  optional(:node_url) => String.t(),
  optional(:api_key) => String.t(),
  optional(:agent_did) => String.t(),
  optional(:on_disconnect) => (term() -> any()),
  optional(:on_reconnect) => (-> any()),
  optional(:did_spec) => map()
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close(pid)

@spec close(pid()) :: :ok

Gracefully shuts down the client.

connect(pid)

@spec connect(pid()) :: :ok

Establishes the WebSocket connection and joins the Phoenix channel.

Blocks until the join is acknowledged. Returns :ok on success or raises on error.

did(pid)

@spec did(pid()) :: String.t()

Returns the agent's DID — either provided in config or assigned by the node on connect.

get_credential(pid, id)

@spec get_credential(pid(), String.t()) :: {:ok, map()} | {:error, term()}

Retrieves a stored credential by ID.

handle(pid, msg_type, fun)

@spec handle(pid(), String.t(), Layr8.Handler.handler_fn()) :: :ok

Registers a handler for a DIDComm message type.

Must be called before connect/1. Raises Layr8.AlreadyConnectedError if called after.

Handler Signature

fn msg -> {:reply, %Layr8.Message{...}} | :noreply | :pass | {:error, reason} end

handle_all(pid, fun)

@spec handle_all(pid(), Layr8.Handler.handler_fn()) :: :ok

Registers a catch-all handler invoked when no specific handler matches.

Must be called before connect/1. Raises Layr8.AlreadyConnectedError if called after.

Handler Signature

fn msg -> {:reply, %Layr8.Message{...}} | :noreply | :pass | {:error, reason} end

list_credentials(pid, opts \\ [])

@spec list_credentials(
  pid(),
  keyword()
) :: {:ok, [map()]} | {:error, term()}

Lists stored credentials for a holder. Defaults: holder = did/1.

request(pid, msg, opts \\ [])

@spec request(pid(), Layr8.Message.t() | map(), keyword()) :: {:ok, Layr8.Message.t()}

Sends a DIDComm message and waits for a correlated response (matched by thread ID).

Returns {:ok, Layr8.Message.t()} or raises Layr8.ProblemReportError / Layr8.NotConnectedError.

Options

  • :timeout — milliseconds to wait for a reply (default 30s)
  • :parent_thread — set pthid for nested thread correlation

send(pid, msg, opts \\ [])

@spec send(pid(), Layr8.Message.t() | map(), keyword()) :: :ok

Sends a DIDComm message.

By default waits for server acknowledgment. Pass fire_and_forget: true to skip.

Returns :ok or raises Layr8.NotConnectedError.

sign_credential(pid, credential, opts \\ [])

@spec sign_credential(pid(), map(), keyword()) :: {:ok, String.t()} | {:error, term()}

Signs a W3C Verifiable Credential. Defaults: issuer = did/1, format = "compact_jwt".

sign_presentation(pid, credentials, opts \\ [])

@spec sign_presentation(pid(), [String.t()], keyword()) ::
  {:ok, String.t()} | {:error, term()}

Signs a W3C Verifiable Presentation. Defaults: holder = did/1, format = "compact_jwt".

start_link(opts \\ %{})

@spec start_link(start_opts()) :: GenServer.on_start()

Starts the Layr8 Client GenServer.

Accepts the same keys as Layr8.Config.resolve!/1 plus:

  • :on_disconnect — called with the disconnect reason
  • :on_reconnect — called after successful reconnection

Raises Layr8.Error if required config fields are missing.

store_credential(pid, jwt, opts \\ [])

@spec store_credential(pid(), String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}

Stores a signed credential JWT for a holder. Defaults: holder = did/1.

verify_credential(pid, signed, opts \\ [])

@spec verify_credential(pid(), String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}

Verifies a signed credential. Defaults: verifier = did/1.

verify_presentation(pid, signed, opts \\ [])

@spec verify_presentation(pid(), String.t(), keyword()) ::
  {:ok, map()} | {:error, term()}

Verifies a signed presentation. Defaults: verifier = did/1.