# `TruelayerClient.Auth.TokenStore`
[🔗](https://github.com/iamkanishka/truelayer_client/blob/v1.0.0/lib/truelayer_client/auth/token_store.ex#L1)

Behaviour for pluggable OAuth2 token storage backends.

The default implementation (`TruelayerClient.Auth.MemoryStore`) stores tokens
in a GenServer-managed ETS table — suitable for single-node deployments.

For distributed systems implement this behaviour with a Redis or DynamoDB backend:

    defmodule MyApp.RedisTokenStore do
      @behaviour TruelayerClient.Auth.TokenStore

      @impl true
      def get(store_id, token_type) do
        case Redix.command(:redix, ["GET", key(store_id, token_type)]) do
          {:ok, nil}    -> {:ok, nil}
          {:ok, binary} -> {:ok, :erlang.binary_to_term(binary)}
          {:error, _}   -> {:ok, nil}
        end
      end

      @impl true
      def put(store_id, token_type, token) do
        ttl = max(DateTime.diff(token.expires_at, DateTime.utc_now()), 1)
        Redix.command!(:redix, ["SETEX", key(store_id, token_type), ttl,
                                 :erlang.term_to_binary(token)])
        :ok
      end

      @impl true
      def delete(store_id, token_type) do
        Redix.command(:redix, ["DEL", key(store_id, token_type)])
        :ok
      end

      defp key(store_id, type), do: "truelayer:token:#{store_id}:#{type}"
    end

Pass the module to `TruelayerClient.new/1`:

    {:ok, client} = TruelayerClient.new(
      client_id: "...",
      client_secret: "...",
      token_store: MyApp.RedisTokenStore
    )

# `store_id`

```elixir
@type store_id() :: reference() | atom()
```

# `token_type`

```elixir
@type token_type() :: TruelayerClient.Auth.Token.token_type()
```

# `delete`

```elixir
@callback delete(store_id(), token_type()) :: :ok
```

Remove a stored token. Always returns `:ok`.

# `get`

```elixir
@callback get(store_id(), token_type()) ::
  {:ok, TruelayerClient.Auth.Token.t() | nil} | {:error, term()}
```

Fetch a token by store_id and type.
Returns `{:ok, %Token{}}`, `{:ok, nil}` if not found, or `{:error, reason}`.

# `put`

```elixir
@callback put(store_id(), token_type(), TruelayerClient.Auth.Token.t()) ::
  :ok | {:error, term()}
```

Persist a token. Returns `:ok` or `{:error, reason}`.

---

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