# `DigitalToken`
[🔗](https://github.com/kipcole9/digital_token/blob/v2.0.0/lib/digital_token.ex#L1)

Functions to validate, search and retrieve digital token
data sourced from the [DTIF registry](https://dtif.org).

# `short_name`

```elixir
@type short_name() :: String.t()
```

A digital token may have zero or more short
names associated with it. They are arbitrary
strings, usually three or four characters in
length. For example "BTC", "ETH" and "DOGE".

# `short_name_map`

```elixir
@type short_name_map() :: %{required({token_id(), token_type()}) =&gt; token_id()}
```

A mapping from a short name to token
identifier.

# `symbol_map`

```elixir
@type symbol_map() :: %{required(token_id()) =&gt; String.t()}
```

A mapping of digital token identifiers
to a currency symbol for that token.

# `t`

```elixir
@type t() :: %DigitalToken{
  header: map(),
  informative: map(),
  metadata: map(),
  normative: map()
}
```

The structure of data matching that hosted in
the [DTIF registry](https://dtif.org)/

# `token_id`

```elixir
@type token_id() :: String.t()
```

token_id is a random 9-character
string defined by the [dtif registry](https://dtif.org)
that uniquely identifies a digital token.

# `token_map`

```elixir
@type token_map() :: %{required(token_id()) =&gt; t()}
```

A mapping of digital token identifiers
to the registry data for that token.

# `token_type`

```elixir
@type token_type() :: :native | :auxiliary | :distributed | :fungible
```

The type of a token

# `get_token`

```elixir
@spec get_token(token_id() | short_name()) :: {:ok, t()} | {:error, {module(), any()}}
```

Returns the registry data for a given token
identifier.

## Arguments

* `id` is any token identifier or short name

## Returns

* `{:ok, registry_data}` or

* `{:error, {exception, id}}`

## Example

    DigitalToken.get_token("BTC")
    #=> {:ok,
     %DigitalToken{
       header: %{
         dlt_type: :blockchain,
         dti: "4H95J0R2X",
         dti_type: :native,
         template_version: #Version<1.0.0>
       },
       informative: %{
         long_name: "Bitcoin",
         public_distributed_ledger_indication: false,
         short_names: ["BTC", "XBT"],
         unit_multiplier: 100000000,
         url: "https://github.com/bitcoin/bitcoin"
       },
       metadata: %{
         .....

# `get_token!`

```elixir
@spec get_token!(token_id() | short_name()) :: t() | no_return()
```

Returns the registry data for a given token
identifier.

## Arguments

* `id` is any token identifier or short name

## Returns

* `registry_data` or

* raises an exception

## Example

    DigitalToken.get_token("BTC")
    #=> %DigitalToken{
       header: %{
         dlt_type: :blockchain,
         dti: "4H95J0R2X",
         dti_type: :native,
         template_version: #Version<1.0.0>
       },
       informative: %{
         long_name: "Bitcoin",
         public_distributed_ledger_indication: false,
         short_names: ["BTC", "XBT"],
         unit_multiplier: 100000000,
         url: "https://github.com/bitcoin/bitcoin"
       },
       metadata: %{
         .....

# `is_digital_token`
*macro* 

# `long_name`

```elixir
@spec long_name(token_id()) :: {:ok, String.t()} | {:error, {module(), String.t()}}
```

Returns the long name of a digital token.

## Arguments

* `token_id` is any valid digital token identifier.

## Returns

* `{:ok, long_name}` where `long_name` is the token's
  registered name.

* `{:error, {exception, reason}}`

## Examples

    iex> DigitalToken.long_name "BTC"
    {:ok, "Bitcoin"}

    iex> DigitalToken.long_name "4H95J0R2X"
    {:ok, "Bitcoin"}

    iex> DigitalToken.long_name "TV5T68SZJ"
    {:ok, "Terra Classic"}

# `search`

```elixir
@spec search(String.t()) :: [{token_id(), token_type()}]
```

Returns a list of all tokens matching the given short name or long name.

Since many tokens share the same short name (e.g. "ETH" appears as
a native token, as wrapped tokens on various chains, and in fungible
groups), this function returns all matches to support disambiguation.

## Arguments

* `name` is a short name (e.g. `"BTC"`) or long name (e.g. `"Bitcoin"`).

## Returns

* A list of `{token_id, dti_type}` tuples, or an empty list if no
  tokens match.

## Examples

    iex> [{id, :native}] = DigitalToken.search("Bitcoin") |> Enum.filter(fn {_, t} -> t == :native end)
    iex> id
    "4H95J0R2X"

    iex> DigitalToken.search("Nothing")
    []

# `search`

```elixir
@spec search(String.t(), token_type()) :: [{token_id(), token_type()}]
```

Returns a list of all tokens matching the given name and token type.

This is useful to narrow results when a short name like `"ETH"` maps to
many tokens across different types.

## Arguments

* `name` is a short name (e.g. `"BTC"`) or long name (e.g. `"Bitcoin"`).

* `dti_type` is one of `:native`, `:auxiliary`, `:distributed`, or `:fungible`.

## Returns

* A list of `{token_id, dti_type}` tuples matching both the name and
  the type, or an empty list if no tokens match.

## Examples

    iex> DigitalToken.search("ETH", :native) |> length() > 1
    true

    iex> DigitalToken.search("BTC", :native)
    [{"4H95J0R2X", :native}]

    iex> DigitalToken.search("Nothing", :native)
    []

# `short_name`

```elixir
@spec short_name(token_id()) :: {:ok, String.t()} | {:error, {module(), String.t()}}
```

Returns the short name of a digital token.

## Arguments

* `token_id` is any valid digital token identifier.

## Returns

* `{:ok, short_name}` where `short_name` is either
  the first short name in `token.informative.short_names` or
  the token long name if there are no short names.

* `{:error, {exception, reason}}`

## Examples

    iex> DigitalToken.short_name "BTC"
    {:ok, "BTC"}

    iex> DigitalToken.short_name "4H95J0R2X"
    {:ok, "BTC"}

    iex> DigitalToken.short_name "TV5T68SZJ"
    {:ok, "LUNC"}

# `short_names`

```elixir
@spec short_names() :: short_name_map()
```

Returns a mapping of digital token short
names to digital token identifiers.

# `symbol`

```elixir
@spec symbol(token_id(), 1..4) :: {:ok, String.t()} | {:error, {module(), String.t()}}
```

Returns a currency symbol used in number formatting.

## Arguments

* `token_id` is any valid digital token identifier.

* `style` is a number in the range `1` to `4` as follows:
    * `1` is the token's symbol, if it exists
    * `2` is the token's short name as a proxy for a currency code
    * `3` is the token's long name
    * `4` is the token's symbol as a proxy for a narrow currency symbol

## Returns

* `{:ok, symbol}` or

* `{:error, {exception, reason}}`

## Examples

    iex> DigitalToken.symbol "BTC", 1
    {:ok, "₿"}

    iex> DigitalToken.symbol "BTC", 2
    {:ok, "BTC"}

    iex> DigitalToken.symbol "BTC", 3
    {:ok, "Bitcoin"}

    iex> DigitalToken.symbol "BTC", 4
    {:ok, "₿"}

    iex> DigitalToken.symbol "ETH", 4
    {:ok, "Ξ"}

    iex> DigitalToken.symbol "DOGE", 4
    {:ok, "Ð"}

    iex> DigitalToken.symbol "DODGY", 4
    {:error, {DigitalToken.UnknownTokenError, "DODGY"}}

# `symbols`

```elixir
@spec symbols() :: symbol_map()
```

Returns a mapping of digital token identifiers
names to a currency symbol.

# `tokens`

```elixir
@spec tokens() :: token_map()
```

Returns a map of the digital tokens in the
[dtif registry](https://dtif.org).

# `validate_token`

```elixir
@spec validate_token(token_id() | short_name(), Keyword.t()) ::
  {:ok, token_id()} | {:error, {module(), any()}}
```

Validates a token identifier or short name
and returns the token identifier or an error.

## Arguments

* `id` is any token identifier or short name.

* `options` is a keyword list of options.

## Options

* `:dti_type` specifies the token type to match when looking up
  by short name or long name. One of `:native`, `:auxiliary`,
  `:distributed`, or `:fungible`. When not specified, the lookup
  tries each type in the following priority order: `:native`,
  `:auxiliary`, `:distributed`, `:fungible`. The first match wins.

## Returns

* `{:ok, token_id}` or

* `{:error, {exception, id}}`

## Examples

    iex> DigitalToken.validate_token("BTC")
    {:ok, "4H95J0R2X"}

    iex> DigitalToken.validate_token("Bitcoin")
    {:ok, "4H95J0R2X"}

    iex> DigitalToken.validate_token "4H95J0R2X"
    {:ok, "4H95J0R2X"}

    iex> DigitalToken.validate_token("Nothing")
    {:error, {DigitalToken.UnknownTokenError, "Nothing"}}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
