agent.lending supplies, borrows, withdraws and repays on Aave and Spark pools, Euler vaults, Morpho markets and Kamino lending markets through one set of calls. Every call is one operation; a prerequisite Circuit derives, such as a token approval or an Aave or Spark category switch, runs first as its own operation and the call continues after it.
agent.lending.markets.list({ network, protocol? }) returns { markets, unavailable }. markets has one row per asset a venue lists on that network: protocol, market (the Aave or Spark pool, the Aave V4 <spoke>/<reserveId>, the Euler vault, the Morpho market id or the Kamino lending market), name, asset, symbol, decimals, whether you can supply or borrow it, supplyApy and borrowApy as fractions, the asset’s own loanToValue and liquidationLoanToValue, collateral (for a borrow row, what it accepts: the market to supply the collateral to, its asset and LTV pair) and categories (the Aave or Spark e-mode categories or Kamino elevation groups the asset belongs to, each with its integer id, securesLoans when the asset counts as collateral inside it and canBorrow when it can be borrowed inside it; a Kamino group lends exactly one asset). A venue or market Circuit cannot read is left out of markets without blocking the rest and named in unavailable (protocol, market, null when the whole venue failed, and error), so a missing venue reads as unreadable rather than as offering nothing. Supply and borrow check only their own target market on chain, so an unreadable listing never blocks them.
agent.lending.positions.supply({ network, protocol, market, asset, amount, category? }) supplies asset to a market from a row, opening the wallet’s default account there (on Kamino, its default obligation). agent.lending.positions.supply({ network, position, asset, amount, category? }) adds to the lending account a held position sits in, named by its holding.asset; on Kamino this reaches multiply and leverage obligations too. agent.lending.positions.borrow(...) takes the same two forms. amount is whole tokens, "max" (supply only: the whole token holding) or { balancePercent }; a borrow also takes { loanToValue }, the account’s loan-to-value after the borrow on the scale of the holding’s loanToValue. category is a row’s categories[].id; 0 is none. Aave and Spark switch it first as its own operation; Kamino requests the elevation group inside the supply or borrow’s own transaction.
agent.lending.positions.withdraw({ network, position, amount }) and agent.lending.positions.repay({ network, position, amount, payWith? }) reduce a held position. amount is whole tokens, { balancePercent } of the session’s holding, { loanToValue } or "max". For an agent, "max" is the session’s own holding; when the session holds the whole position, Circuit uses the venue’s own full close, which also covers interest accrued since. A rebasing holding (Aave, Spark, an Euler loan) is compared in the venue’s own shares at the live rate, so accrued interest never makes a whole position look partial; a manual position on the same wallet is never closed by an agent. payWith: "supply" repays from the account’s supply of the same asset where the venue allows it (Aave, Spark, Euler). Kamino refuses a "max" withdraw while a loan is open, because its program withdraws only down to the limit: name an amount or repay first.
agent.lending.positions.update({ network, position, securesLoans }) turns a supply’s collateral use on or off (Aave V3 and V4, Spark, Euler). agent.lending.account.update({ network, protocol, market, category }) or ({ network, position, category }) switches the account’s category (Aave and Spark e-mode, Kamino elevation group); the venue refuses a switch its held positions do not allow, and Kamino sets a category only on an obligation that holds a deposit. A Kamino supply or borrow with category sets the elevation group in the same transaction as the action, so a first supply can name its group.
Circuit derives each venue’s setup itself: token approvals (a full repay approves the debt plus 0.1%, so interest that accrues before the repay lands stays covered), Euler’s collateral and controller switches inside the same EVC batch as the deposit or borrow (a first deposit into a vault secures loans unless the account already uses ten vaults as collateral, the EVC’s limit), Kamino’s user metadata, obligation and farm accounts and a requested elevation group inside the same transaction as the action, and a first Aave V4 supply turning the reserve on as collateral in the same spoke multicall. Lending operations need a live wallet: paper sessions and backtests refuse them.
Holdings report supplies and loans as supplied and borrowed rows; pass a row’s asset as position. Its market is the market a markets.list row names.