Packages

Elixir client library for cryptocurrency exchanges — generated from CCXT specs via compile-time macros.

Current section

Files

Jump to
ccxt_client lib ccxt ws auth sha384_nonce.ex
Raw

lib/ccxt/ws/auth/sha384_nonce.ex

defmodule CCXT.WS.Auth.Sha384Nonce do
@moduledoc """
SHA384 Nonce auth pattern — bitfinex.
Signs `"AUTH{nonce}"` (nonce = `timestamp_ms`) with HMAC-SHA384 hex and
builds a flat auth frame — no nested `args`.
## Example Frame (bitfinex)
%{
"event" => "auth",
"apiKey" => "api_key",
"authSig" => "hex_signature",
"authNonce" => 1699999999999,
"authPayload" => "AUTH1699999999999"
}
## Config
| Key | Default | Purpose |
|---|---|---|
| `:event_value` | `"auth"` | Top-level event field |
| `:timestamp_ms_override` | (unset) | Test-only — freezes the nonce |
"""
@behaviour CCXT.WS.Auth.Behaviour
alias CCXT.Signing
@impl true
def pre_auth(_credentials, _config, _opts), do: {:ok, %{}}
@impl true
def build_auth_message(credentials, config, _opts) do
api_key = credentials.api_key
secret = credentials.secret
nonce = Signing.timestamp_ms_from_config(config)
payload = "AUTH#{nonce}"
signature = payload |> Signing.hmac_sha384(secret) |> Signing.encode_hex()
{:ok,
%{
"event" => Map.get(config, :event_value, "auth"),
"apiKey" => api_key,
"authSig" => signature,
"authNonce" => nonce,
"authPayload" => payload
}}
end
@impl true
def handle_auth_response(response, _state) do
cond do
response["event"] == "auth" and response["status"] == "OK" ->
:ok
response["event"] == "auth" and response["status"] == "FAILED" ->
{:error, {:auth_failed, response["msg"]}}
true ->
{:error, {:auth_failed, response}}
end
end
end