Current section
Files
Jump to
Current section
Files
lib/xmtp/installations.ex
defmodule Xmtp.Installations do
@moduledoc """
Product-safe installation status and repair helpers.
"""
alias XmtpElixirSdk.Client
alias XmtpElixirSdk.Installations, as: LowLevelInstallations
alias XmtpElixirSdk.Preferences
alias XmtpElixirSdk.Types
@default_device_limit 5
@type status :: %{
required(:status) => :ok | :too_many_devices,
required(:installation_count) => non_neg_integer(),
required(:device_limit) => pos_integer(),
required(:installation_ids) => [String.t()],
required(:user_copy) => String.t()
}
@spec status(Client.t() | Types.InboxState.t(), keyword()) :: {:ok, status()} | {:error, term()}
def status(client_or_state, opts \\ [])
def status(%Client{} = client, opts) do
with {:ok, inbox_state} <- Preferences.fetch_inbox_state(client) do
status(inbox_state, opts)
end
end
def status(%Types.InboxState{} = inbox_state, opts) do
device_limit = Keyword.get(opts, :device_limit, @default_device_limit)
installation_ids = LowLevelInstallations.ids(inbox_state)
installation_count = length(installation_ids)
status =
if installation_count > device_limit do
:too_many_devices
else
:ok
end
{:ok,
%{
status: status,
installation_count: installation_count,
device_limit: device_limit,
installation_ids: installation_ids,
user_copy: user_copy(status)
}}
end
@spec recommend_cleanup(Client.t() | Types.InboxState.t(), keyword()) ::
{:ok,
%{required(:installation_ids) => [String.t()], required(:user_copy) => String.t()}}
| {:error, term()}
def recommend_cleanup(client_or_state, opts \\ []) do
current_installation_id = Keyword.get(opts, :current_installation_id)
with {:ok, status} <- status(client_or_state, opts) do
cleanup_ids =
status.installation_ids
|> Enum.reject(&(&1 == current_installation_id))
|> Enum.take(max(status.installation_count - status.device_limit, 0))
{:ok,
%{
installation_ids: cleanup_ids,
user_copy: "Remove an old chat session or use a different wallet."
}}
end
end
@spec revoke_old_installation(Client.t(), String.t(), map()) :: :ok | {:error, term()}
def revoke_old_installation(%Client{} = client, installation_id, signer)
when is_binary(installation_id) and is_map(signer) do
LowLevelInstallations.revoke(client, [installation_id], signer)
end
defp user_copy(:ok), do: "This wallet can use chat."
defp user_copy(:too_many_devices),
do: "This wallet has too many chat devices connected."
end