> For the complete documentation index, see [llms.txt](https://docs.save.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.save.finance/developers/integration-guide.md).

# 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
*
