DpExchange.Robinhood.Rest (DpExchangeRobinhood v0.1.1)

Copy Markdown View Source

Robinhood Crypto's REST surface — internal.

Every call is signed, including the quotes

There is no anonymous endpoint here. best_bid_ask needs the same Ed25519 signature as an order, which is why this venue declares credential_benefit: :required and why get_price/2 takes credentials.

The price is the ask, and that is worth stating plainly

best_bid_ask returns bid_inclusive_of_sell_spread and ask_inclusive_of_buy_spread — the prices a taker would actually get. When the venue sends no separate price, this package uses the ask as the quote's price, because it is a real number the venue quoted and it is the one a buyer pays.

It is not a mid, and it is not a last trade. A series built from it sits a spread above a mid-based series from another venue, which matters if two venues' prices are ever compared. bid and ask are both carried so a caller can compute whatever it actually wants; nothing here computes a mid, because what a price means is the caller's decision.

No candles, no order book, no volume

Robinhood Crypto publishes no historical-candle endpoint, no order book, and no volume on the quote. Those are :unsupported — and that is the venue's shape, not a gap in this package. Declaring them so lets a consumer route that work elsewhere instead of discovering an empty series.

Summary

Functions

Base URL, overridable for tests.

Best bid and ask for one symbol.

Every tradable pair, canonical.

Functions

base_url(opts)

@spec base_url(keyword()) :: String.t()

Base URL, overridable for tests.

get_price(symbol, credentials, opts)

@spec get_price(String.t(), map(), keyword()) ::
  {:ok, DpExchange.Core.Types.Quote.t()} | {:error, term()} | {:refused, term()}

Best bid and ask for one symbol.

Timestamped from the venue's own timestamp. A quote the venue did not date returns {:error, :missing_venue_timestamp} — the local clock is never substituted, which is what the adapter this replaces did.

get_symbols(credentials, opts)

@spec get_symbols(
  map(),
  keyword()
) :: {:ok, [String.t()]} | {:error, term()} | {:refused, term()}

Every tradable pair, canonical.

The endpoint paginates, so this walks it. Measured by the prior adapter on 2026-08-05: 86 symbols, every one quoted in USD — as seen by that credential. Listings can differ by account tier, so a consumer holding a different key may see a different catalogue.