{"version":3,"file":"group-defi-positions.cjs","sourceRoot":"","sources":["../../src/DeFiPositionsController/group-defi-positions.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n  DefiPositionResponse,\n  PositionType,\n  ProtocolToken,\n  Underlying,\n  Balance,\n} from './fetch-positions';\n\nexport type GroupedDeFiPositions = {\n  aggregatedMarketValue: number;\n  protocols: {\n    [protocolId: string]: {\n      protocolDetails: {\n        name: string;\n        iconUrl: string;\n      };\n      aggregatedMarketValue: number;\n      positionTypes: {\n        [key in PositionType]?: {\n          aggregatedMarketValue: number;\n          positions: ProtocolTokenWithMarketValue[][];\n        };\n      };\n    };\n  };\n};\n\nexport type ProtocolTokenWithMarketValue = Omit<ProtocolToken, 'tokens'> & {\n  marketValue?: number;\n  tokens: UnderlyingWithMarketValue[];\n};\n\nexport type UnderlyingWithMarketValue = Omit<Underlying, 'tokens'> & {\n  marketValue?: number;\n};\n\n/**\n *\n * @param defiPositionsResponse - The response from the defi positions API\n * @returns The grouped positions that get assigned to the state\n */\nexport function groupDeFiPositions(\n  defiPositionsResponse: DefiPositionResponse[],\n): {\n  [key: Hex]: GroupedDeFiPositions;\n} {\n  const groupedDeFiPositions: { [key: Hex]: GroupedDeFiPositions } = {};\n\n  for (const position of defiPositionsResponse) {\n    if (!position.success) {\n      continue;\n    }\n\n    const { chainId, protocolId, iconUrl, positionType, protocolDisplayName } =\n      position;\n\n    const chain = toHex(chainId);\n\n    if (!groupedDeFiPositions[chain]) {\n      groupedDeFiPositions[chain] = {\n        aggregatedMarketValue: 0,\n        protocols: {},\n      };\n    }\n\n    const chainData = groupedDeFiPositions[chain];\n\n    if (!chainData.protocols[protocolId]) {\n      chainData.protocols[protocolId] = {\n        protocolDetails: {\n          name: protocolDisplayName,\n          iconUrl,\n        },\n        aggregatedMarketValue: 0,\n        positionTypes: {},\n      };\n    }\n\n    const protocolData = chainData.protocols[protocolId];\n\n    let positionTypeData = protocolData.positionTypes[positionType];\n    if (!positionTypeData) {\n      positionTypeData = {\n        aggregatedMarketValue: 0,\n        positions: [],\n      };\n      protocolData.positionTypes[positionType] = positionTypeData;\n    }\n\n    for (const protocolToken of position.tokens) {\n      const token = processToken(protocolToken) as ProtocolTokenWithMarketValue;\n\n      // If groupPositions is true, we group all positions of the same type\n      if (position.metadata?.groupPositions) {\n        if (positionTypeData.positions.length === 0) {\n          positionTypeData.positions.push([token]);\n        } else {\n          positionTypeData.positions[0].push(token);\n        }\n      } else {\n        positionTypeData.positions.push([token]);\n      }\n\n      if (token.marketValue) {\n        const multiplier = position.positionType === 'borrow' ? -1 : 1;\n\n        positionTypeData.aggregatedMarketValue += token.marketValue;\n        protocolData.aggregatedMarketValue += token.marketValue * multiplier;\n        chainData.aggregatedMarketValue += token.marketValue * multiplier;\n      }\n    }\n  }\n\n  return groupedDeFiPositions;\n}\n\n/**\n *\n * @param tokenBalance - The token balance that is going to be processed\n * @returns The processed token balance\n */\nfunction processToken<T extends Balance>(\n  tokenBalance: T,\n): T & {\n  marketValue?: number;\n  tokens?: UnderlyingWithMarketValue[];\n} {\n  if (!tokenBalance.tokens) {\n    return {\n      ...tokenBalance,\n      marketValue: tokenBalance.price\n        ? tokenBalance.balance * tokenBalance.price\n        : undefined,\n    };\n  }\n\n  const processedTokens = tokenBalance.tokens.map((t) => {\n    const { tokens, ...tokenWithoutUnderlyings } = processToken(t);\n\n    return tokenWithoutUnderlyings;\n  });\n\n  const marketValue = processedTokens.reduce<number | undefined>(\n    (acc, t) =>\n      acc === undefined || t.marketValue === undefined\n        ? undefined\n        : acc + t.marketValue,\n    0,\n  );\n\n  return {\n    ...tokenBalance,\n    marketValue,\n    tokens: processedTokens,\n  };\n}\n"]}