> ## Documentation Index
> Fetch the complete documentation index at: https://docs.circuit.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Lending agent SDK

> Circuit SDK reference for lending agents: supply, borrow, withdraw and repay on Aave V3 and V4, Spark, Euler, Morpho and Kamino, collateral and category changes, and the markets each venue lists.

`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](https://docs.circuit.org/agent-developers/sdk-reference/holdings.md) 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.