/** * Shared channel action helpers. * * Filters token-backed accounts and composes account-level action gates. */ type OptionalDefaultGate = (key: TKey, defaultValue?: boolean) => boolean; type TokenSourcedAccount = { tokenSource?: string | null; }; /** * Filters out accounts explicitly marked as tokenless. */ export function listTokenSourcedAccounts( accounts: readonly TAccount[], ): TAccount[] { return accounts.filter((account) => account.tokenSource !== "none"); } /** * Creates an action gate that is enabled when any account-level gate enables the action. */ export function createUnionActionGate( accounts: readonly TAccount[], createGate: (account: TAccount) => OptionalDefaultGate, ): OptionalDefaultGate { const gates = accounts.map((account) => createGate(account)); return (key, defaultValue = true) => gates.some((gate) => gate(key, defaultValue)); }