# `ExWapp.PrivacyToken`
[🔗](https://github.com/elchemista/ex_wapp/blob/v0.1.5/lib/ex_wapp/privacy_token.ex#L1)

Validates trusted-contact privacy tokens used by direct-message sends.

WhatsApp rotates these tokens in seven-day buckets and accepts the current
bucket plus the previous three. Tokens outside that window must not be
attached to outbound stanzas.

# `tctoken_record`

```elixir
@type tctoken_record() :: %{
  :token =&gt; binary(),
  :timestamp =&gt; non_neg_integer() | String.t(),
  optional(:sender_timestamp) =&gt; non_neg_integer() | String.t() | nil
}
```

# `cutoff_timestamp`

```elixir
@spec cutoff_timestamp(integer()) :: integer()
```

# `newer_or_equal?`

```elixir
@spec newer_or_equal?(term(), term()) :: boolean()
```

# `normalize_timestamp`

```elixir
@spec normalize_timestamp(term()) :: {:ok, non_neg_integer()} | :error
```

# `put_newer`

```elixir
@spec put_newer(map(), [binary()], map()) :: map()
```

Stores `record` under every JID in `jids`, keeping whichever token is newer.

One contact reaches the store under several JID aliases (phone number and LID),
and the same token arrives through more than one path — a notification and a
history sync chunk. Overwriting blindly would let a stale copy win.

# `valid?`

```elixir
@spec valid?(term(), integer()) :: boolean()
```

---

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