Amarula.Protocol.Signal.LidMappingFileStore (amarula v0.1.0)

View Source

File-backed LID ↔ PN mapping store, ported from Baileys LIDMappingStore.storeLIDPNMappings / getLIDForPN / getPNForLID.

Persistence mirrors Amarula.Protocol.Signal.SessionStore: one entry per mapping in the :lid_mapping namespace. We key by the user part of the JID (the device/server are reconstructed by the caller), matching Baileys which stores pnUser → lidUser plus a <lidUser>_reverse entry.

lidmap-<pnUser>.term            holds the lidUser
lidmap-<lidUser>_reverse.term   holds the pnUser

This is intentionally process-free (no GenServer) and crash-safe. Persistence goes through the pluggable Amarula.Storage seam (:lid_mapping namespace), scoped to the connection conn (Amarula.Conn).

Summary

Functions

Look up the LID user for a PN JID (or PN user string). nil if unmapped.

Plain signal address for a JID (no LID resolution): <user>.<device>, with a _<domainType> suffix for non-WA domains (jidToSignalProtocolAddress).

Look up the PN user for a LID JID (or LID user string). nil if unmapped.

LID-priority signal address for a device JID, port of Baileys resolveLIDSignalAddress. If jid is a PN user with a stored LID mapping, return the signal address under the LID identity (<lidUser>_1.<device>); otherwise return the plain signal address of jid.

Store a batch of {lid, pn} JID pairs. Each side may be given as either the LID or the PN (Baileys accepts both orders); pairs that aren't a valid PN/LID combination are skipped.

LID-priority wire jid: a PN device jid mapped to its LID equivalent (preserving the device), else the jid unchanged. Mirrors Baileys assertSessions wireJids — the server serves prekey bundles keyed by the LID for lid-mapped users; a PN fetch for such a user goes unanswered.

Functions

lid_for_pn(conn, pn)

@spec lid_for_pn(Amarula.Conn.t(), String.t()) :: String.t() | nil

Look up the LID user for a PN JID (or PN user string). nil if unmapped.

plain_signal_address(jid)

@spec plain_signal_address(String.t()) :: String.t()

Plain signal address for a JID (no LID resolution): <user>.<device>, with a _<domainType> suffix for non-WA domains (jidToSignalProtocolAddress).

pn_for_lid(conn, lid)

@spec pn_for_lid(Amarula.Conn.t(), String.t()) :: String.t() | nil

Look up the PN user for a LID JID (or LID user string). nil if unmapped.

signal_address(conn, jid)

@spec signal_address(Amarula.Conn.t(), String.t()) :: String.t()

LID-priority signal address for a device JID, port of Baileys resolveLIDSignalAddress. If jid is a PN user with a stored LID mapping, return the signal address under the LID identity (<lidUser>_1.<device>); otherwise return the plain signal address of jid.

Used so a session keyed by a recipient's LID is found even when we address them by phone number on the wire.

store_mappings(conn, pairs)

@spec store_mappings(Amarula.Conn.t(), [{String.t(), String.t()}]) ::
  {non_neg_integer(), [{String.t(), String.t()}]}

Store a batch of {lid, pn} JID pairs. Each side may be given as either the LID or the PN (Baileys accepts both orders); pairs that aren't a valid PN/LID combination are skipped.

Returns {stored_count, newly_stored} where stored_count counts every valid pair persisted (including ones that already matched) and newly_stored lists the input {lid, pn} pairs that were not already present — the ones a caller may want to force-refresh sessions for.

wire_jid(conn, jid)

@spec wire_jid(Amarula.Conn.t(), String.t()) :: String.t()

LID-priority wire jid: a PN device jid mapped to its LID equivalent (preserving the device), else the jid unchanged. Mirrors Baileys assertSessions wireJids — the server serves prekey bundles keyed by the LID for lid-mapped users; a PN fetch for such a user goes unanswered.