An address on a venue's withdrawal allow-list.
Why this is in the contract at all
Two venues in this family gate withdrawals behind an allow-list: a withdrawal to an address that is not on it is refused, whatever the balance. A facade that could not express the list would leave a caller unable to tell "this withdrawal failed" from "this withdrawal was never going to work", and unable to do anything about the second.
:status and :active_from are the whole point
Adding an address is not the same as being able to use it. Venues impose a waiting period between approval and first use — the point of an allow-list being that an attacker who takes an account cannot immediately add their own address and drain it.
So an address can be on the list and still unusable:
:pending— requested, not yet usable:active— usable now:rejected— refused
:active_from is when a :pending address becomes usable, where the venue states it.
nil does not mean "usable now" — it means the venue did not say, and a caller
planning a withdrawal against an unstated activation is planning against a guess.
Summary
Types
@type status() :: :pending | :active | :rejected
@type t() :: %DpExchange.Core.Types.ApprovedAddress{ active_from: DateTime.t() | nil, address: String.t(), asset: String.t() | nil, label: String.t() | nil, network: String.t(), provider: atom(), requested_at: DateTime.t() | nil, status: status() }
Functions
Builds a t/0, failing closed if a required field is absent or nil.
@enforce_keys guards presence, not nil — see DpExchange.Core.Types.Validate.
@spec usable?(t(), DateTime.t()) :: boolean() | nil
Whether this address can be withdrawn to as at now.
Returns nil when the address is :pending and the venue stated no activation time —
unknown, not usable. The only safe reading of an unstated activation is to ask the
venue again rather than to attempt the withdrawal.