# `Weavr.Client`
[🔗](https://github.com/iamkanishka/weavr/blob/main/lib/weavr/client.ex#L1)

A stateful session wrapper around `Weavr.Config` + `Weavr.Auth`.

`weavr` supports two ways of managing the per-user `auth_token`:

1. **Stateless** — you call `Weavr.Auth` functions directly with a
   `Weavr.Config` and pass the `auth_token` you got back explicitly
   into every subsequent resource call. This is the right choice in
   a web app backend, where the token belongs to an HTTP session or
   a database row, not to a long-lived Elixir process.

2. **Stateful** (Weavr.Client) — start one `Weavr.Client` GenServer
   per logged-in user (e.g. one per LiveView process, or one per
   long-running worker acting as a single Weavr user). The client
   holds the current Auth/Access Token and automatically attaches it
   to every call made through Weavr.Client.request/2, refreshing
   or re-exchanging it as needed.

Resource modules (`Weavr.Accounts`, `Weavr.Cards`, ...) accept either
a `Weavr.Config` struct *or* a `Weavr.Client` pid/name — when given a
`Weavr.Client`, they fetch the current token from it; when given a
bare `Weavr.Config`, they expect you to also pass the token
explicitly. See each resource module's docs for its exact function
signatures.

## Example — stateful usage

    {:ok, client} =
      Weavr.Client.start_link(
        api_key: System.fetch_env!("WEAVR_API_KEY"),
        environment: :sandbox
      )

    :ok = Weavr.Client.login_with_password(client, email: "a@b.com", password: "secret")

    {:ok, accounts} = Weavr.Accounts.list(client)

## Example — stateless usage

    config = Weavr.Config.new(api_key: "...", environment: :sandbox)
    {:ok, %{auth_token: token}} = Weavr.Auth.login_with_password(config, email: "a@b.com", password: "secret")
    {:ok, accounts} = Weavr.Accounts.list(config, token)

# `t`

```elixir
@type t() :: pid() | GenServer.name()
```

# `child_spec`

Returns a child spec, so a `Weavr.Client` can be placed directly under a supervision tree.

# `config`

```elixir
@spec config(t()) :: Weavr.Config.t()
```

Returns the `Weavr.Config` the client was started with. Resource
modules use this to issue requests against the right base URL.

# `current_token`

```elixir
@spec current_token(t()) :: {:ok, String.t()} | {:error, :not_authenticated}
```

Returns the currently stored token, or `{:error, :not_authenticated}`
if no login has happened yet. Resource modules use this internally;
you generally won't need to call it directly.

# `list_identities`

```elixir
@spec list_identities(t()) :: {:ok, [map()]} | {:error, Weavr.Error.t()}
```

Lists identities available to the client's current Auth Token.

# `login_via_biometrics`

```elixir
@spec login_via_biometrics(t(), map()) :: :ok | {:error, Weavr.Error.t()}
```

Logs in via biometrics. See `Weavr.Auth.login_via_biometrics/2`.

# `login_with_password`

```elixir
@spec login_with_password(t(), keyword() | map()) :: :ok | {:error, Weavr.Error.t()}
```

Logs in with email/password and stores the resulting Auth Token on
the client for use by subsequent requests.

# `logout`

```elixir
@spec logout(t()) :: :ok | {:error, Weavr.Error.t()}
```

Logs out and clears the stored token.

# `select_identity`

```elixir
@spec select_identity(t(), String.t()) :: :ok | {:error, Weavr.Error.t()}
```

Exchanges the client's current Auth Token for an Access Token scoped
to `identity_id`, storing the result. See the multi-identity
discussion in `Weavr.Auth`.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts a `Weavr.Client` process.

Accepts the same options as `Weavr.Config.new/1`, plus any
`GenServer.start_link/3` option (`:name`, etc).

# `with_token`

```elixir
@spec with_token(t(), (Weavr.Config.t(), String.t() -&gt; result)) ::
  result | {:error, :not_authenticated}
when result: var
```

Runs a resource-module function with the client's config and current
token, in one call. This is what `Weavr.Accounts.list/1` and similar
one-arity resource functions use internally when given a
`Weavr.Client` instead of a `{config, token}` pair.

---

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