# Integration Guide

### Introduction

Solend has 3 types of accounts: lending market, reserve, and obligation.

There's only one instance of a lending market for now. There's a one-to-one mapping from listed asset to reserve. There's a one-to-one mapping from user to obligations (which tracks user's collateral/borrows).

Rust definitions are [here](https://github.com/solendprotocol/solana-program-library/tree/9513a15f818ef141188e4727b22ec5b6195a0904/token-lending/program/src/state).

### Calculating TVL from on-chain data example

<https://github.com/solendprotocol/tvl-calculator-example>

### Deriving obligation address

```
const seed = LENDING_MARKET_ADDRESS.slice(0, 32);
const obligationAddress = await PublicKey.createWithSeed(
  new PublicKey(address),
  seed,
  new PublicKey(SOLEND_PROGRAM_ID),
);
```

### Calculating APY

The following typescript snippet is extracted from our codebase:

```
export const calculateSupplyAPY = (reserve: Reserve) => {
  const currentUtilization = calculateUtilizationRatio(reserve);
  const borrowAPY = calculateBorrowAPY(reserve);
  return currentUtilization * borrowAPY;
};

export const calculateUtilizationRatio = (reserve: Reserve) => {
  const borrowedAmount = reserve.liquidity.borrowedAmountWads
    .div(new BN(`1${''.padEnd(18, '0')}`))
    .toNumber();
  const availableAmount = reserve.liquidity.availableAmount.toNumber();
  const currentUtilization =
    borrowedAmount / (availableAmount + borrowedAmount);
  return currentUtilization;
};

export const calculateBorrowAPY = (reserve: Reserve) => {
  const currentUtilization = calculateUtilizationRatio(reserve);
  const optimalUtilization = reserve.config.optimalUtilizationRate / 100;
  let borrowAPY;
  if (optimalUtilization === 1.0 || currentUtilization < optimalUtilization) {
    const normalizedFactor = currentUtilization / optimalUtilization;
    const optimalBorrowRate = reserve.config.optimalBorrowRate / 100;
    const minBorrowRate = reserve.config.minBorrowRate / 100;
    borrowAPY =
      normalizedFactor * (optimalBorrowRate - minBorrowRate) + minBorrowRate;
  } else {
    const normalizedFactor =
      (currentUtilization - optimalUtilization) / (1 - optimalUtilization);
    const optimalBorrowRate = reserve.config.optimalBorrowRate / 100;
    const maxBorrowRate = reserve.config.maxBorrowRate / 100;
    borrowAPY =
      normalizedFactor * (maxBorrowRate - optimalBorrowRate) +
      optimalBorrowRate;
  }

  return borrowAPY;
};
```

Additionally, we have a few other resources for developers:

* [SDK](https:/sdk.solend.fi)
* [API](https://api.solend.fi)s
*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.save.finance/developers/integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
