/**
 * Normalization layer: Aave V4 Hub & Spoke → multi-market lender response.
 *
 * ## Architecture
 *
 * Aave V4 Spokes are **isolated risk silos**: each Spoke has its own
 * collateral configs, its own user health factor, its own risk premium, and
 * shares no solvency with other Spokes (the Hub is the shared liquidity
 * layer, not a shared risk surface). The architectural analogues:
 *
 *   Aave v3 (legacy)   →  one giant shared pool      (one lender key)
 *   Compound v3        →  one Comet per base asset   (one lender key per Comet)
 *   Morpho Blue        →  one market per pair        (one lender key per marketId)
 *   Aave v4            →  one Spoke per risk silo    (one lender key per spoke)  ← THIS
 *
 * To match this reality and treat V4 like any other isolated-market protocol,
 * the V4 normalizer is a **multi-market lender** (`isMultiMarket()` returns
 * true). Each Spoke gets its own synthesized lender key:
 *
 *   `${baseHubLender}_${spokeAddr.slice(2).toUpperCase()}`
 *
 * e.g. `AAVE_V4_CORE_94E7A5DCBE816E498B89AB752661904E2F56C485`. The base Hub
 * lender (`AAVE_V4_CORE`, `AAVE_V4_PLUS`, `AAVE_V4_PRIME`) is used only as
 * the **input/discovery** identifier passed to the fetcher. The output is
 * keyed exclusively by per-spoke synthesized keys.
 *
 * The dispatcher in `fetchLender.ts` `Object.assign`s the multi-market map
 * into the top-level lender data, so callers see V4 spokes the same way
 * they see Morpho markets — flat, top-level, one entry per isolated market.
 */
import type { ParsedSpokeData } from './types';
/**
 * Per-config entry shape. Mirrors `ConfigEntry` in `types/apiReturnType.ts`
 * — `category` is a `number` to match Aave V3 (e-mode index). For V4 the
 * value is the on-chain `dynamicConfigKey` (also an integer).
 */
export interface LenderConfigData {
    category: number;
    label: string;
    borrowCollateralFactor: number;
    collateralFactor: number;
    borrowFactor: number;
    liquidationPenalty?: number;
    closeFactor?: number;
    targetHealthFactor?: number;
    collateralDisabled?: boolean;
    debtDisabled?: boolean;
}
/**
 * Per-marketUid identity inside an Aave V4 spoke. The (hub, assetId,
 * reserveId) triple locates the asset in the on-chain Hub & Spoke binding
 * for action routing — they're not derivable from the marketUid alone
 * (which only encodes the underlying address).
 */
export interface AaveV4MarketMetadata {
    /** Hub-internal asset ID for this underlying (scoped to `hub`) */
    assetId: number;
    /** Spoke-internal reserve ID for this underlying in this spoke */
    reserveId: number;
    /**
     * Per-reserve hub address (lowercase). A single spoke can mix reserves
     * across hubs; this is the hub THIS reserve binds to.
     */
    hub: string;
}
/**
 * Lender-key-wide params for a single Aave V4 spoke. Constant across every
 * marketUid in the same per-spoke entry — analogous to Morpho's market-level
 * params (loan token, collateral token, oracle, irm). Lives at the top level
 * of the multi-market response wrapper, not on individual marketUid entries.
 *
 * Note: there is **no** spoke-level `hub` here. Hub identity is per-reserve;
 * see `AaveV4MarketMetadata.hub`.
 */
export interface AaveV4SpokeParams {
    /** This entry's spoke address (lowercase) */
    spoke: string;
    /** Spoke's oracle address (lowercase) */
    oracle: string;
    /** Spoke label from data-sdk metadata (e.g. "Core / Default") */
    label: string;
    /**
     * UI/grouping hint only — `AAVE_V4_CORE` / `AAVE_V4_PLUS` / `AAVE_V4_PRIME`.
     * NOT used for routing or lender keying.
     */
    baseHubAttribution?: string;
}
export interface AaveV4TokenEntry {
    marketUid: string;
    name: string;
    poolId: string;
    underlying: string;
    asset: any;
    /**
     * Spoke-local supply (from Spoke.getReserveSuppliedAssets) as decimal
     * string. Aggregatable: `sum(totalDeposits)` across spokes gives real TVL
     * without double-counting the shared hub pool.
     */
    totalDeposits: string;
    totalDebtStable: string;
    /**
     * Spoke-local total debt (drawn + premium) as decimal string.
     * Aggregatable across spokes for TVL: `TVL = Σ deposits − Σ debts`.
     */
    totalDebt: string;
    /**
     * Pool liquidity: hub-level `asset.liquidity` — the raw amount available
     * in the hub for this asset. This is the withdraw-side liquidity ceiling
     * (not gated by spoke caps). Matches the semantics of `totalLiquidity`
     * across all other protocols (`deposits − debt`).
     */
    totalLiquidity: number;
    totalDepositsUSD: number;
    totalDebtStableUSD: number;
    totalDebtUSD: number;
    totalLiquidityUSD: number;
    /**
     * Hub-level total supply across all spokes as decimal string.
     * This is the IRM-relevant denominator (`hubTotalOwed / hubDeposits`).
     */
    hubDeposits: string;
    /** Hub-level total owed across all spokes as decimal string. */
    hubBorrows: string;
    hubDepositsUSD: number;
    hubBorrowsUSD: number;
    depositRate: number;
    variableBorrowRate: number;
    stableBorrowRate: number;
    /**
     * Hub-level borrow utilization (0..1) — the exact IRM input
     * `drawn / (liquidity + drawn + swept)` (premium debt excluded, deficit
     * ignored — mirrors the hub's AssetInterestRateStrategy). The V4 IRM
     * lives on the hub and aggregates drawn liquidity across all spokes
     * sharing this asset, so this is the IRM-relevant utilization, NOT the
     * per-spoke ratio. Per-spoke `(suppliedAssets/totalDebt)` would be
     * misleading here (e.g. always negative for borrow-only spokes).
     */
    utilization: number;
    /**
     * Totals in the hub IRM's utilization basis (token units):
     * `irmTotalDeposits = liquidity + drawn + swept`, `irmTotalDebt = drawn`.
     * Rate-impact simulations must shift these, not the spoke-local totals.
     */
    irmTotalDeposits: number;
    irmTotalDebt: number;
    intrinsicYield: number;
    rewards: any[];
    decimals: number;
    config: {
        [key: string]: LenderConfigData;
    };
    collateralActive: boolean;
    borrowingEnabled: boolean;
    /**
     * Whether this asset can currently be supplied to this spoke. Pendant to
     * `borrowingEnabled`. Sourced from `ReserveConfig.receiveSharesEnabled`
     * and gated by the spoke's `paused` flag — borrow-only spokes (e.g.
     * `TreasurySpoke`) will report `false` here while still reporting
     * `borrowingEnabled: true`.
     *
     * Also gated by the Hub-side spoke binding `active` flag: if the binding
     * is inactive, Hub.add() will revert regardless of spoke-level flags.
     */
    depositsEnabled: boolean;
    hasStable: boolean;
    isActive: boolean;
    isFrozen: boolean;
    borrowCap: number;
    supplyCap: number;
    debtCeiling: number;
    /**
     * Static liquidation close factor. Aave uses a 50% default that rises to
     * 100% only below the close-factor HF threshold; we surface the static 0.5.
     * V4's spoke liquidation model parameterizes the bonus rather than a fixed
     * close factor, so this is a cross-lender-shape default, noted as such.
     */
    closeFactor: number;
    /**
     * Spoke-level liquidation target health factor (e.g. 1.05). V4 liquidators
     * repay only enough debt to restore the position to this HF — the real
     * liquidation knob here, surfaced alongside the shape-default closeFactor.
     */
    targetHealthFactor?: number;
    /**
     * Remaining deposit capacity for this spoke in token units.
     * Mirrors `TokenizationSpoke.maxDeposit()`:
     *   `max(0, addCap * 10^decimals - totalDeposits)`.
     * `null` means uncapped (`addCap == MAX_ALLOWED_SPOKE_CAP`).
     * `0` means no deposits are currently allowed (binding blocked, or cap
     * reached, or `addCap == 0`).
     */
    depositable: number | null;
    /**
     * Hub-side borrow liquidity available for this spoke in token units.
     * Mirrors the borrow-liquidity computation from `normalize.ts`
     * (`min(hubLiquidity, drawCap headroom)`).
     * `null` means uncapped.
     */
    borrowLiquidity: number | null;
    borrowLiquidityUSD: number;
    /**
     * Hub-side spoke binding state. `true` when the spoke can interact with
     * the Hub for this asset. `false` blocks ALL Hub operations (draw, add,
     * remove, restore). Undefined when binding was not fetched.
     */
    spokeActive?: boolean;
    /**
     * Hub-side spoke binding halt flag. When `true`, the spoke cannot perform
     * operations that instantly update liquidity (draw, add, remove, restore),
     * but can still report deficit. Undefined when binding was not fetched.
     */
    spokeHalted?: boolean;
    /**
     * Per-marketUid identity. The lender-key-wide spoke/hub/oracle live on
     * the response wrapper's `params`, not here.
     */
    params: {
        metadata: AaveV4MarketMetadata;
    };
    /**
     * Risk premium fields stamped directly on the entry (the entry IS one
     * spoke's view of one asset, so these are per-(spoke, asset) by
     * construction — no need for a wrapper).
     */
    collateralRiskBps: number;
    riskPremiumThresholdBps: number;
}
/**
 * One V4 spoke's normalized response. The shape mirrors what other
 * normalizers return (`{ data, chainId }`) plus a top-level `params` that
 * carries the lender-key-wide spoke/hub/oracle addresses.
 */
export interface AaveV4SpokeResponse {
    data: {
        [marketUid: string]: AaveV4TokenEntry;
    };
    chainId: string;
    params: AaveV4SpokeParams;
}
/**
 * V4 is single-market per call now: each per-spoke synthesized lender key
 * (`AAVE_V4_<HEX>`) corresponds to exactly one fetcher call that returns
 * one `AaveV4SpokeResponse`. The dispatcher in `fetchLender.ts` stores it
 * under `lenderData[lender]` directly — same code path as Aave V3.
 */
export type NormalizedAaveV4Response = AaveV4SpokeResponse | undefined;
export declare function normalizeAaveV4(spokeDataList: ParsedSpokeData[], chainId: string, 
/**
 * Per-spoke lender key (`AAVE_V4_<HEX>`). Pass-through; the lender-key
 * generator was already invoked by the caller — we use the value as the
 * top-level key under which to emit this spoke's response.
 */
spokeLenderKeyArg: string, prices: {
    [asset: string]: number;
}, additionalYields: any, tokenList: any, lenderShortNameFn: (l: string) => string, createMarketUidFn: (chainId: string, lender: string, refAddress: string) => string, toOracleKeyFn: (a: string | null) => string, toGenericPriceKeyFn: (asset: string, chainId: string) => string): NormalizedAaveV4Response;
//# sourceMappingURL=normalize.d.ts.map