View Source Hyperliquid.Api.SubscriptionEndpoint (hyperliquid v0.2.2)
DSL for defining WebSocket subscription endpoints.
This macro reduces boilerplate while preserving explicit Ecto schemas for event validation and optional storage configuration.
Usage
defmodule Hyperliquid.Api.Subscription.L2Book do
use Hyperliquid.Api.SubscriptionEndpoint,
request_type: "l2Book",
params: [:coin],
optional_params: [:nSigFigs, :mantissa],
storage: [
cache: [enabled: true, key_pattern: "l2book:{{coin}}"]
]
@primary_key false
embedded_schema do
field :coin, :string
field :levels, {:array, {:array, :any}}
field :time, :integer
end
def changeset(event \ %__MODULE__{}, attrs) do
event
|> cast(attrs, [:coin, :levels, :time])
end
endGenerated Functions
build_request/1- Build and validate subscription request__subscription_info__/0- Returns metadata for the manager__storage_config__/0- Returns storage configurationgenerate_subscription_key/1- Generate unique key for this subscription variantbuild_cache_key/1- Generate cache key from event data (if cache enabled)extract_records/1- Extract records from event for storage (if postgres enabled)
Options
:request_type- Required. The subscription type (e.g., "l2Book"):params- List of required parameters as atoms:optional_params- List of optional parameters as atoms:connection_type- Connection routing strategy::shared- Can share connection with other subscriptions (default):dedicated- Needs its own connection per parameter variant:user_grouped- Must share connection with other subs for same user
:doc- Short description of the subscription:key_fields- Fields to include in subscription key (default: all params):ws_url- Custom WebSocket URL function (e.g.,&Hyperliquid.Config.rpc_ws_url/0):storage- Storage configuration (see below)
Storage Options
The :storage option accepts a keyword list with the following backends:
Postgres Storage
storage: [
postgres: [
enabled: true,
table: "trades",
extract: :trades, # optional: field containing nested records to store
fields: [:coin, :side, :px] # optional: only store these fields
]
]Cache Storage
storage: [
cache: [
enabled: true,
ttl: :timer.minutes(5), # optional TTL
key_pattern: "l2book:{{coin}}", # template with {{field}} placeholders
fields: [:coin, :levels] # optional: only cache these fields
]
]Both backends can be enabled simultaneously.
Partial Storage (fields option)
Use the fields option to save only specific fields from complex events.
This is useful for subscriptions like webData2 that contain both user-specific
data and market data, where you only want to persist certain parts:
storage: [
postgres: [
enabled: true,
table: "user_snapshots",
fields: [:user, :clearinghouse_state, :open_orders, :spot_state]
]
]
Summary
Functions
Extract specific fields from an event map.
If fields is nil or empty, returns the full event. Supports both atom and string keys, and handles nested structs/embeds.
Examples
iex> extract_fields(%{a: 1, b: 2, c: 3}, [:a, :b])
%{a: 1, b: 2}
iex> extract_fields(%{user: "0x123", data: %{x: 1}}, nil)
%{user: "0x123", data: %{x: 1}}
Interpolate a key pattern with event data.
Replaces {{field}} placeholders with actual values from the event.
Examples
iex> interpolate_key_pattern("trades:{{coin}}:{{time}}", %{coin: "BTC", time: 123})
"trades:BTC:123"
iex> interpolate_key_pattern("l2book:{{coin}}", %{"coin" => "ETH"})
"l2book:ETH"