       when generating the encryption and signing keys. Defaults to `:sha256`
     * `:signed_at` - set the timestamp of the token in seconds.
       Defaults to `System.system_time(:second)`
-    * `:max_age` - the default maximum age of the token. Defaults to
-      86400 seconds (1 day) and it may be overridden on verify/4.
-
-  """
+
+  """
+  @spec sign(context, binary, term, [shared_opt | signed_at_opt]) :: binary
   def sign(context, salt, data, opts \\ []) when is_binary(salt) do
     context
     |> get_key_base()


  ## Options

    * `:max_age` - verifies the token only if it has been generated
      "max age" ago in seconds. Defaults to the max age signed in the
      token (86400)
    * `:key_iterations` - option passed to `Plug.Crypto.KeyGenerator`
      when generating the encryption and signing keys. Defaults to 1000
    * `:key_length` - option passed to `Plug.Crypto.KeyGenerator`
      when generating the encryption and signing keys. Defaults to 32
    * `:key_digest` - option passed to `Plug.Crypto.KeyGenerator`
      when generating the encryption and signing keys. Defaults to `:sha256`

  """
  def decrypt(context, secret, token, opts \\ []) when is_binary(secret) do
    context
    |> get_key_base()


  require Logger

  @type context :: Plug.Conn.t() | Phoenix.Socket.t() | atom | binary

  @type shared_opt ::
          {:key_iterations, pos_integer}
          | {:key_length, pos_integer}
          | {:key_digest, :sha256 | :sha384 | :sha512}

  @type max_age_opt :: {:max_age, pos_integer}
  @type signed_at_opt :: {:signed_at, pos_integer}

  @doc """
  Encodes and signs data into a token you can send to clients.

  ## Options

