import type { IDebankTokenExposure } from '../../types'; import type { IDebankNormalizedResponse } from '../debank/utils'; import type { IUntangledVaultExposure } from './types'; /** Display metadata for an Untangled protocol slug. */ export interface IUntangledProtocolMetadata { /** Name rendered in the exposure breakdown. */ name: string; /** Chain the protocol position lives on — not always the vault's own chain. */ chain: string; } /** * Display metadata for the protocol slugs Untangled reports today. * * Untangled does not return protocol names or chains, so they are mapped here. * Unknown slugs fall back to a capitalized slug on the vault's chain rather than * being dropped, so a newly integrated protocol still shows up (unlabelled) * instead of silently vanishing from the breakdown. */ export declare const UNTANGLED_PROTOCOL_REGISTRY: Record; /** * The vault's asset composition, as vault-level token exposure. * * This is the one asset breakdown Untangled actually publishes, and it is * authoritative: `byAsset` decomposes the same `tvlUsd` that `byProtocol` does. * It is returned separately from {@link transformUntangledToDebank} because it * cannot be folded into that structure — attributing an asset to a position * would require a join the API does not provide, and adding these on top of the * synthesized position tokens would double-count the vault. * * Negative rows are kept. A vault that has moved capital into another Upshift * vault is reported holding the receipt token and owing the asset it spent — * earnXLM carries `earnUSDC +$1,170,913` against `USDC -$1,170,271` — and those * only sum back to `tvlUsd` together. Dropping the liability would overstate the * vault's assets by the full size of the position. * * @param exposure - A resolved Untangled report, or `null`/`undefined` when the * fetch failed. * @returns One row per asset clearing `filterOutBySize` in absolute terms, * largest first, with `amount` denominated in USD. Empty when `exposure` is * absent. `id` carries the asset symbol rather than an address — Untangled * reports assets by ticker and publishes no contract address for them — so it * is safe as a display key and must not be read as an on-chain address. */ export declare function untangledAssetExposure(exposure: IUntangledVaultExposure | null | undefined): IDebankTokenExposure[]; /** * Transform an Untangled vault exposure report into the DeBank-normalized shape * that `parseVaultLevelDebank` and `parseLoanLevelDebank` consume. * * This is the Stellar equivalent of `transformOctavfiToDebank`: a foreign * portfolio shape is mapped onto the one normalized structure the vault * allocation parser understands, so Stellar vaults populate the same * `exposurePerCategory` / `protocolExposure` / `tokenExposure` outputs as EVM * vaults with no parser changes. * * Mapping: * - Each `byProtocol` entry becomes one position with a single supplying token, * valued in USD (`price: 1`), on the chain from * {@link UNTANGLED_PROTOCOL_REGISTRY}. The token is labelled with the vault's * asset only when one asset covers essentially all of it (see * {@link vaultAssetSymbol}); otherwise it carries the value with no symbol, * and {@link untangledAssetExposure} supplies the composition separately. * - `stellar-wallet` becomes a wallet token, because custody cash is undeployed * capital rather than protocol exposure. * - `upshift` is split: the vault's own idle buffer (the `idle` location) joins * that wallet token, and whatever is left is a real position in another * Upshift vault, named after its receipt token. Untangled reports one * `upshift` slice however many vaults that is, so a vault holding receipts in * two others emits one merged position under the generic name — the value is * still right, only the label is coarser. * - Dust is left in place: `filterOutBySize` in the parser applies the same * threshold Stellar and EVM vaults share. * * Only the `idle` entries of `locations` are consumed, to size the buffer inside * `upshift`. `asOf`, `stale` and `tvlUsd` are not — TVL already comes from * `getVaultTvl`, and freshness is not yet surfaced on `IVaultAllocations`. * * @param exposure - A resolved Untangled report, or `null`/`undefined` when the * fetch failed. * @returns A DeBank-normalized response. Empty positions and tokens when * `exposure` is absent, so callers can pass a failed fetch straight through. * * @example * ```typescript * const exposure = await fetchUntangledVaultExposure(vault); * const normalized = transformUntangledToDebank(exposure); * parseVaultLevelDebank( * normalized, protocolExposure, tokenExposure, vault, exposurePerCategory, netValue, * ); * ``` */ export declare function transformUntangledToDebank(exposure: IUntangledVaultExposure | null | undefined): IDebankNormalizedResponse;