{"version":3,"sources":["../src/NotificationServicesController/utils/utils.ts"],"sourcesContent":["import log from 'loglevel';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport {\n  USER_STORAGE_VERSION_KEY,\n  USER_STORAGE_VERSION,\n} from '../constants/constants';\nimport type { TRIGGER_TYPES } from '../constants/notification-schema';\nimport { TRIGGERS } from '../constants/notification-schema';\nimport type { UserStorage } from '../types/user-storage/user-storage';\n\nexport type NotificationTrigger = {\n  id: string;\n  chainId: string;\n  kind: string;\n  address: string;\n  enabled: boolean;\n};\n\ntype MapTriggerFn<Result> = (\n  trigger: NotificationTrigger,\n) => Result | undefined;\n\ntype TraverseTriggerOpts<Result> = {\n  address?: string;\n  mapTrigger?: MapTriggerFn<Result>;\n};\n\n/**\n * Extracts and returns the ID from a notification trigger.\n * This utility function is primarily used as a mapping function in `traverseUserStorageTriggers`\n * to convert a full trigger object into its ID string.\n *\n * @param trigger - The notification trigger from which the ID is extracted.\n * @returns The ID of the provided notification trigger.\n */\nconst triggerToId = (trigger: NotificationTrigger): string => trigger.id;\n\n/**\n * A utility function that returns the input trigger without any transformation.\n * This function is used as the default mapping function in `traverseUserStorageTriggers`\n * when no custom mapping function is provided.\n *\n * @param trigger - The notification trigger to be returned as is.\n * @returns The same notification trigger that was passed in.\n */\nconst triggerIdentity = (trigger: NotificationTrigger): NotificationTrigger =>\n  trigger;\n\n/**\n * Create a completely new user storage object with the given accounts and state.\n * This method initializes the user storage with a version key and iterates over each account to populate it with triggers.\n * Each trigger is associated with supported chains, and for each chain, a unique identifier (UUID) is generated.\n * The trigger object contains a kind (`k`) indicating the type of trigger and an enabled state (`e`).\n * The kind and enabled state are stored with abbreviated keys to reduce the JSON size.\n *\n * This is used primarily for creating a new user storage (e.g. when first signing in/enabling notification profile syncing),\n * caution is needed in case you need to remove triggers that you don't want (due to notification setting filters)\n *\n * @param accounts - An array of account objects, each optionally containing an address.\n * @param state - A boolean indicating the initial enabled state for all triggers in the user storage.\n * @returns A `UserStorage` object populated with triggers for each account and chain.\n */\nexport function initializeUserStorage(\n  accounts: { address?: string }[],\n  state: boolean,\n): UserStorage {\n  const userStorage: UserStorage = {\n    [USER_STORAGE_VERSION_KEY]: USER_STORAGE_VERSION,\n  };\n\n  accounts.forEach((account) => {\n    const address = account.address?.toLowerCase();\n    if (!address) {\n      return;\n    }\n    if (!userStorage[address]) {\n      userStorage[address] = {};\n    }\n\n    Object.entries(TRIGGERS).forEach(\n      ([trigger, { supported_chains: supportedChains }]) => {\n        supportedChains.forEach((chain) => {\n          if (!userStorage[address]?.[chain]) {\n            userStorage[address][chain] = {};\n          }\n\n          userStorage[address][chain][uuidv4()] = {\n            k: trigger as TRIGGER_TYPES, // use 'k' instead of 'kind' to reduce the json weight\n            e: state, // use 'e' instead of 'enabled' to reduce the json weight\n          };\n        });\n      },\n    );\n  });\n\n  return userStorage;\n}\n\n/**\n * Iterates over user storage to find and optionally transform notification triggers.\n * This method allows for flexible retrieval and transformation of triggers based on provided options.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @param options - Optional parameters to filter and map triggers:\n * - `address`: If provided, only triggers for this address are considered.\n * - `mapTrigger`: A function to transform each trigger. If not provided, triggers are returned as is.\n * @returns An array of triggers, potentially transformed by the `mapTrigger` function.\n */\nexport function traverseUserStorageTriggers<\n  ResultTriggers = NotificationTrigger,\n>(\n  userStorage: UserStorage,\n  options?: TraverseTriggerOpts<ResultTriggers>,\n): ResultTriggers[] {\n  const triggers: ResultTriggers[] = [];\n  const mapTrigger =\n    options?.mapTrigger ?? (triggerIdentity as MapTriggerFn<ResultTriggers>);\n\n  for (const address in userStorage) {\n    if (address === (USER_STORAGE_VERSION_KEY as unknown as string)) {\n      continue;\n    }\n    if (options?.address && address !== options.address) {\n      continue;\n    }\n\n    for (const chainId in userStorage[address]) {\n      if (chainId in userStorage[address]) {\n        for (const uuid in userStorage[address][chainId]) {\n          if (uuid) {\n            const mappedTrigger = mapTrigger({\n              id: uuid,\n              kind: userStorage[address]?.[chainId]?.[uuid]?.k,\n              chainId,\n              address,\n              enabled: userStorage[address]?.[chainId]?.[uuid]?.e ?? false,\n            });\n            if (mappedTrigger) {\n              triggers.push(mappedTrigger);\n            }\n          }\n        }\n      }\n    }\n  }\n\n  return triggers;\n}\n\n/**\n * Verifies the presence of specified accounts and their chains in the user storage.\n * This method checks if each provided account exists in the user storage and if all its supported chains are present.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @param accounts - An array of account addresses to check for presence.\n * @returns A record where each key is an account address and each value is a boolean indicating whether the account and all its supported chains are present in the user storage.\n */\nexport function checkAccountsPresence(\n  userStorage: UserStorage,\n  accounts: string[],\n): Record<string, boolean> {\n  const presenceRecord: Record<string, boolean> = {};\n\n  // Initialize presence record for all accounts as false\n  accounts.forEach((account) => {\n    presenceRecord[account.toLowerCase()] = isAccountEnabled(\n      account,\n      userStorage,\n    );\n  });\n\n  return presenceRecord;\n}\n\n/**\n * Internal method to check if a given account should be marked as enabled by introspecting user storage\n * Introspection: check if account exists; and also see if has all triggers in schema enabled\n *\n * @param accountAddress - address to check in user storage\n * @param userStorage - user storage object to traverse/introspect\n * @returns boolean if the account is enabled or disabled\n */\nfunction isAccountEnabled(\n  accountAddress: string,\n  userStorage: UserStorage,\n): boolean {\n  const accountObject = userStorage[accountAddress?.toLowerCase()];\n\n  // If the account address is not present in the userStorage, return true\n  if (!accountObject) {\n    return false;\n  }\n\n  // Check if all available chains are present\n  for (const [triggerKind, triggerConfig] of Object.entries(TRIGGERS)) {\n    for (const chain of triggerConfig.supported_chains) {\n      if (!accountObject[chain]) {\n        return false;\n      }\n\n      const triggerExists = Object.values(accountObject[chain]).some(\n        (obj) => obj.k === triggerKind,\n      );\n      if (!triggerExists) {\n        return false;\n      }\n\n      // Check if any trigger is disabled\n      for (const uuid in accountObject[chain]) {\n        if (!accountObject[chain][uuid].e) {\n          return false;\n        }\n      }\n    }\n  }\n\n  return true;\n}\n\n/**\n * Infers and returns an array of enabled notification trigger kinds from the user storage.\n * This method counts the occurrences of each kind of trigger and returns the kinds that are present.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @returns An array of trigger kinds (`TRIGGER_TYPES`) that are enabled in the user storage.\n */\nexport function inferEnabledKinds(userStorage: UserStorage): TRIGGER_TYPES[] {\n  const allSupportedKinds = new Set<TRIGGER_TYPES>();\n\n  traverseUserStorageTriggers(userStorage, {\n    mapTrigger: (t) => {\n      allSupportedKinds.add(t.kind as TRIGGER_TYPES);\n    },\n  });\n\n  return Array.from(allSupportedKinds);\n}\n\n/**\n * Retrieves all UUIDs associated with a specific account address from the user storage.\n * This function utilizes `traverseUserStorageTriggers` with a mapping function to extract\n * just the UUIDs of the notification triggers for the given address.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @param address - The specific account address to retrieve UUIDs for.\n * @returns An array of UUID strings associated with the given account address.\n */\nexport function getUUIDsForAccount(\n  userStorage: UserStorage,\n  address: string,\n): string[] {\n  return traverseUserStorageTriggers(userStorage, {\n    address,\n    mapTrigger: triggerToId,\n  });\n}\n\n/**\n * Retrieves all UUIDs from the user storage, regardless of the account address or chain ID.\n * This method leverages `traverseUserStorageTriggers` with a specific mapping function (`triggerToId`)\n * to extract only the UUIDs from all notification triggers present in the user storage.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @returns An array of UUID strings from all notification triggers in the user storage.\n */\nexport function getAllUUIDs(userStorage: UserStorage): string[] {\n  return traverseUserStorageTriggers(userStorage, {\n    mapTrigger: triggerToId,\n  });\n}\n\n/**\n * Retrieves UUIDs for notification triggers that match any of the specified kinds.\n * This method filters triggers based on their kind and returns an array of UUIDs for those that match the allowed kinds.\n * It utilizes `traverseUserStorageTriggers` with a custom mapping function that checks if a trigger's kind is in the allowed list.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @param allowedKinds - An array of kinds (as strings) to filter the triggers by.\n * @returns An array of UUID strings for triggers that match the allowed kinds.\n */\nexport function getUUIDsForKinds(\n  userStorage: UserStorage,\n  allowedKinds: string[],\n): string[] {\n  const kindsSet = new Set(allowedKinds);\n\n  return traverseUserStorageTriggers(userStorage, {\n    mapTrigger: (t) => (kindsSet.has(t.kind) ? t.id : undefined),\n  });\n}\n\n/**\n * Retrieves notification triggers for a specific account address that match any of the specified kinds.\n * This method filters triggers both by the account address and their kind, returning triggers that match the allowed kinds for the specified address.\n * It leverages `traverseUserStorageTriggers` with a custom mapping function to filter and return only the relevant triggers.\n *\n * @param userStorage - The user storage object containing notification triggers.\n * @param address - The specific account address for which to retrieve triggers.\n * @param allowedKinds - An array of trigger kinds (`TRIGGER_TYPES`) to filter the triggers by.\n * @returns An array of `NotificationTrigger` objects that match the allowed kinds for the specified account address.\n */\nexport function getUUIDsForAccountByKinds(\n  userStorage: UserStorage,\n  address: string,\n  allowedKinds: TRIGGER_TYPES[],\n): NotificationTrigger[] {\n  const allowedKindsSet = new Set(allowedKinds);\n  return traverseUserStorageTriggers(userStorage, {\n    address,\n    mapTrigger: (trigger) => {\n      if (allowedKindsSet.has(trigger.kind as TRIGGER_TYPES)) {\n        return trigger;\n      }\n      return undefined;\n    },\n  });\n}\n\n/**\n * Upserts (updates or inserts) notification triggers for a given account across all supported chains.\n * This method ensures that each supported trigger type exists for each chain associated with the account.\n * If a trigger type does not exist for a chain, it creates a new trigger with a unique UUID.\n *\n * @param _account - The account address for which to upsert triggers. The address is normalized to lowercase.\n * @param userStorage - The user storage object to be updated with new or existing triggers.\n * @returns The updated user storage object with upserted triggers for the specified account.\n */\nexport function upsertAddressTriggers(\n  _account: string,\n  userStorage: UserStorage,\n): UserStorage {\n  // Ensure the account exists in userStorage\n  const account = _account.toLowerCase();\n  userStorage[account] = userStorage[account] || {};\n\n  // Iterate over each trigger and its supported chains\n  for (const [trigger, { supported_chains: supportedChains }] of Object.entries(\n    TRIGGERS,\n  )) {\n    for (const chain of supportedChains) {\n      // Ensure the chain exists for the account\n      userStorage[account][chain] = userStorage[account][chain] || {};\n\n      // Check if the trigger exists for the chain\n      const existingTrigger = Object.values(userStorage[account][chain]).find(\n        (obj) => obj.k === trigger,\n      );\n\n      if (!existingTrigger) {\n        // If the trigger doesn't exist, create a new one with a new UUID\n        const uuid = uuidv4();\n        userStorage[account][chain][uuid] = {\n          k: trigger as TRIGGER_TYPES,\n          e: false,\n        };\n      }\n    }\n  }\n\n  return userStorage;\n}\n\n/**\n * Upserts (updates or inserts) notification triggers of a specific type across all accounts and chains in user storage.\n * This method ensures that a trigger of the specified type exists for each account and chain. If a trigger of the specified type\n * does not exist for an account and chain, it creates a new trigger with a unique UUID.\n *\n * @param triggerType - The type of trigger to upsert across all accounts and chains.\n * @param userStorage - The user storage object to be updated with new or existing triggers of the specified type.\n * @returns The updated user storage object with upserted triggers of the specified type for all accounts and chains.\n */\nexport function upsertTriggerTypeTriggers(\n  triggerType: TRIGGER_TYPES,\n  userStorage: UserStorage,\n): UserStorage {\n  // Iterate over each account in userStorage\n  Object.entries(userStorage).forEach(([account, chains]) => {\n    if (account === (USER_STORAGE_VERSION_KEY as unknown as string)) {\n      return;\n    }\n\n    // Iterate over each chain for the account\n    Object.entries(chains).forEach(([chain, triggers]) => {\n      // Check if the trigger type exists for the chain\n      const existingTrigger = Object.values(triggers).find(\n        (obj) => obj.k === triggerType,\n      );\n\n      if (!existingTrigger) {\n        // If the trigger type doesn't exist, create a new one with a new UUID\n        const uuid = uuidv4();\n        userStorage[account][chain][uuid] = {\n          k: triggerType,\n          e: false,\n        };\n      }\n    });\n  });\n\n  return userStorage;\n}\n\n/**\n * Toggles the enabled status of a user storage trigger.\n *\n * @param userStorage - The user storage object.\n * @param address - The user's address.\n * @param chainId - The chain ID.\n * @param uuid - The unique identifier for the trigger.\n * @param enabled - The new enabled status.\n * @returns The updated user storage object.\n */\nexport function toggleUserStorageTriggerStatus(\n  userStorage: UserStorage,\n  address: string,\n  chainId: string,\n  uuid: string,\n  enabled: boolean,\n): UserStorage {\n  if (userStorage?.[address]?.[chainId]?.[uuid]) {\n    userStorage[address][chainId][uuid].e = enabled;\n  }\n\n  return userStorage;\n}\n\n/**\n * Attempts to fetch a resource from the network, retrying the request up to a specified number of times\n * in case of failure, with a delay between attempts.\n *\n * @param url - The resource URL.\n * @param options - The options for the fetch request.\n * @param retries - Maximum number of retry attempts. Defaults to 3.\n * @param retryDelay - Delay between retry attempts in milliseconds. Defaults to 1000.\n * @returns A Promise resolving to the Response object.\n * @throws Will throw an error if the request fails after the specified number of retries.\n */\nasync function fetchWithRetry(\n  url: string,\n  options: RequestInit,\n  retries = 3,\n  retryDelay = 1000,\n): Promise<Response> {\n  for (let attempt = 1; attempt <= retries; attempt++) {\n    try {\n      const response = await fetch(url, options);\n      if (!response.ok) {\n        throw new Error(`Fetch failed with status: ${response.status}`);\n      }\n      return response;\n    } catch (error) {\n      log.error(`Attempt ${attempt} failed for fetch:`, error);\n      if (attempt < retries) {\n        await new Promise((resolve) => setTimeout(resolve, retryDelay));\n      } else {\n        throw new Error(\n          `Fetching failed after ${retries} retries. Last error: ${\n            error instanceof Error ? error.message : 'Unknown error'\n          }`,\n        );\n      }\n    }\n  }\n\n  throw new Error('Unexpected error in fetchWithRetry');\n}\n\n/**\n * Performs an API call with automatic retries on failure.\n *\n * @param bearerToken - The JSON Web Token for authorization.\n * @param endpoint - The URL of the API endpoint to call.\n * @param method - The HTTP method ('POST' or 'DELETE').\n * @param body - The body of the request. It should be an object that can be serialized to JSON.\n * @param retries - The number of retry attempts in case of failure (default is 3).\n * @param retryDelay - The delay between retries in milliseconds (default is 1000).\n * @returns A Promise that resolves to the response of the fetch request.\n */\nexport async function makeApiCall<Body>(\n  bearerToken: string,\n  endpoint: string,\n  method: 'POST' | 'DELETE',\n  body: Body,\n  retries = 3,\n  retryDelay = 1000,\n): Promise<Response> {\n  const options: RequestInit = {\n    method,\n    headers: {\n      'Content-Type': 'application/json',\n      Authorization: `Bearer ${bearerToken}`,\n    },\n    body: JSON.stringify(body),\n  };\n\n  return fetchWithRetry(endpoint, options, retries, retryDelay);\n}\n"],"mappings":"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","names":[]}