# Suilend SDK Guide

A TypeScript SDK for interacting with the Suilend lending protocol on the Sui blockchain. This SDK provides a complete interface for lending, borrowing, liquidity mining, and administrative operations.

[![npm version](https://img.shields.io/npm/v/@suilend/sdk)](https://www.npmjs.com/package/@suilend/sdk) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)

## Table of Contents

* \[Installation]
* \[Quick Start]
* \[Architecture Overview]
* \[Core Concepts]
* \[API Reference]
* \[Examples]
* \[Generated Code]
* \[Types and Enums]
* \[Contributing]
* \[Support]

## Installation

```bash
npm install @suilend/sdk
```

### Peer Dependencies

The SDK requires the following peer dependencies:

```bash
npm install @mysten/bcs@1.6.0 @mysten/sui@1.28.2 @suilend/sui-fe@^0.3.5
```

## Quick Start

```typescript
import { SuilendClient, LENDING_MARKET_ID } from "@suilend/sdk";
import { SuiClient } from "@mysten/sui/client";
import { Transaction } from "@mysten/sui/transactions";

// Initialize Sui client
const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });

// Initialize Suilend client
const suilendClient = await SuilendClient.initialize(
  LENDING_MARKET_ID,
  suiClient
);

// Create a transaction
const transaction = new Transaction();

// Deposit tokens into the lending market
await suilendClient.depositIntoObligation(
  userAddress,
  "0x2::sui::SUI", // SUI token type
  "1000000000", // 1 SUI (in MIST)
  transaction,
  obligationOwnerCapId
);

// Execute the transaction
const result = await suiClient.signAndExecuteTransaction({
  signer: keypair,
  transaction,
});
```

## Architecture Overview

The Suilend SDK is organized into several core modules:

### Core Modules

* **Client** (`SuilendClient`): Main interface for all lending operations
* **API**: Event fetching and blockchain data retrieval
* **Parsers**: Data structure parsing and validation utilities
* **Swap**: DEX integration for token swapping operations
* **Utils**: General utilities and helper functions
* **Generated**: Auto-generated code from on-chain smart contracts

### Key Components

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│ SuilendClient   │────│ Lending Market  │────│     Reserves    │
└─────────────────┘    └─────────────────┘    └─────────────────┘
        │                      │                        │
        │              ┌─────────────────┐              │
        └──────────────│ Obligations     │──────────────┘
                       └─────────────────┘
```

## Core Concepts

### Lending Markets

Lending markets are the primary containers for reserves and obligations. Each market has:

* A unique market ID
* A specific coin type (collateral type)
* Multiple reserves for different assets
* Associated obligations for users

### Reserves

Reserves represent individual asset pools within a lending market:

* Store deposited liquidity
* Track borrowing activity
* Manage interest rates and rewards
* Issue cTokens (claim tokens) to depositors

### Obligations

Obligations represent user positions within a lending market:

* Track deposited collateral (cTokens)
* Track borrowed amounts
* Calculate health ratios
* Manage liquidation risk

### cTokens (Claim Tokens)

cTokens represent ownership of deposited assets:

* Earned when depositing into reserves
* Accrue value over time through interest
* Can be redeemed for underlying assets
* Used as collateral for borrowing

## API Reference

### SuilendClient

The main client class for interacting with Suilend protocol.

#### Initialization

```typescript
class SuilendClient {
  static async initialize(
    lendingMarketId: string,
    lendingMarketType: string,
    client: SuiClient,
    logPackageId?: boolean
  ): Promise<SuilendClient>;
}
```

#### Core Operations

**Deposit Operations**

```typescript
// Deposit tokens and receive cTokens
async depositLiquidityAndGetCTokens(
  ownerId: string,
  coinType: string,
  value: string,
  transaction: Transaction
): Promise<TransactionResult>

// Deposit into an obligation as collateral
async depositIntoObligation(
  ownerId: string,
  coinType: string,
  value: string,
  transaction: Transaction,
  obligationOwnerCapId: string | TransactionResult
): Promise<void>
```

**Withdrawal Operations**

```typescript
// Withdraw collateral from obligation
async withdraw(
  obligationOwnerCapId: string,
  obligationId: string,
  coinType: string,
  value: string,
  transaction: Transaction
): Promise<TransactionResult>

// Redeem cTokens for underlying assets
redeem(
  ctokens: TransactionObjectInput,
  coinType: string,
  exemption: TransactionObjectInput,
  transaction: Transaction
): TransactionResult
```

**Borrowing Operations**

```typescript
// Borrow against collateral
async borrow(
  obligationOwnerCapId: string,
  obligationId: string,
  coinType: string,
  value: string,
  transaction: Transaction
): Promise<TransactionResult>

// Repay borrowed amount
async repayIntoObligation(
  ownerId: string,
  obligationId: string,
  coinType: string,
  value: string,
  transaction: Transaction
): Promise<void>
```

**Liquidation Operations**

```typescript
// Liquidate unhealthy obligation
async liquidate(
  transaction: Transaction,
  obligation: Obligation<string>,
  repayCoinType: string,
  withdrawCoinType: string,
  repayCoinId: TransactionObjectInput
): Promise<TransactionResult>
```

**Reward Operations**

```typescript
// Claim rewards from liquidity mining
claimRewards(
  ownerId: string,
  obligationOwnerCapId: string,
  rewards: ClaimRewardsReward[],
  transaction: Transaction
): {
  transaction: Transaction;
  mergedCoinsMap: Record<string, TransactionObjectArgument>;
}

// Add reward to a reserve
async addReward(
  ownerId: string,
  lendingMarketOwnerCapId: string,
  reserveArrayIndex: bigint,
  isDepositReward: boolean,
  rewardCoinType: string,
  rewardValue: string,
  startTimeMs: bigint,
  endTimeMs: bigint,
  transaction: Transaction,
  mergeCoins?: boolean
): Promise<void>
```

#### Administrative Operations

```typescript
// Create new reserve
async createReserve(
  lendingMarketOwnerCapId: string,
  transaction: Transaction,
  pythPriceId: string,
  coinType: string,
  createReserveConfigArgs: CreateReserveConfigArgs
): Promise<void>

// Update reserve configuration
updateReserveConfig(
  lendingMarketOwnerCapId: string,
  transaction: Transaction,
  coinType: string,
  createReserveConfigArgs: CreateReserveConfigArgs
): void
```

#### Data Retrieval

```typescript
// Get obligation data
static async getObligation(
  obligationId: string,
  lendingMarketTypeArgs: string[],
  client: SuiClient
): Promise<Obligation<string>>

// Get obligation owner capabilities
static async getObligationOwnerCaps(
  ownerId: string,
  lendingMarketTypeArgs: string[],
  client: SuiClient
): Promise<ObligationOwnerCap<string>[]>
```

### Events API

The SDK provides comprehensive event parsing for tracking protocol activity:

```typescript
// Event types available
type ApiReserveAssetDataEvent = {
  id: number;
  lendingMarketId: string;
  coinType: string;
  reserveId: string;
  availableAmount: string;
  supplyAmount: string;
  borrowedAmount: string;
  // ... additional fields
};

type ApiDepositEvent = {
  id: number;
  lendingMarketId: string;
  coinType: string;
  obligationId: string;
  ctokenAmount: string;
  // ... additional fields
};

// Similar events for withdraw, borrow, repay, liquidate, etc.
```

### Swap Integration

The SDK includes DEX aggregation capabilities:

```typescript
// Get swap quote
async function getQuote(
  fromToken: string,
  toToken: string,
  amount: string,
  slippage: number
): Promise<SwapQuote>;

// Execute swap transaction
async function executeSwap(
  quote: SwapQuote,
  transaction: Transaction
): Promise<void>;
```

## Examples

### Complete Lending Flow

```typescript
import { SuilendClient, LENDING_MARKET_ID, Side } from "@suilend/sdk";
import { SuiClient } from "@mysten/sui/client";
import { Transaction } from "@mysten/sui/transactions";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";

async function lendingExample() {
  // Initialize clients
  const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
  const suilendClient = await SuilendClient.initialize(
    LENDING_MARKET_ID,
    suiClient
  );

  const keypair = Ed25519Keypair.generate();
  const userAddress = keypair.toSuiAddress();

  // 1. Create obligation
  const createObligationTx = new Transaction();
  const obligationOwnerCap = suilendClient.createObligation(createObligationTx);

  await suiClient.signAndExecuteTransaction({
    signer: keypair,
    transaction: createObligationTx,
  });

  // 2. Deposit SUI as collateral
  const depositTx = new Transaction();
  await suilendClient.depositIntoObligation(
    userAddress,
    "0x2::sui::SUI",
    "5000000000", // 5 SUI
    depositTx,
    obligationOwnerCap
  );

  await suiClient.signAndExecuteTransaction({
    signer: keypair,
    transaction: depositTx,
  });

  // 3. Borrow USDC
  const borrowTx = new Transaction();
  const obligationId = "your-obligation-id";

  await suilendClient.borrow(
    obligationOwnerCap,
    obligationId,
    "0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN", // USDC
    "1000000", // 1 USDC
    borrowTx
  );

  await suiClient.signAndExecuteTransaction({
    signer: keypair,
    transaction: borrowTx,
  });

  // 4. Claim rewards
  const rewardsTx = new Transaction();
  const rewards = [
    {
      reserveArrayIndex: 0n,
      rewardIndex: 0n,
      rewardCoinType: "0x2::sui::SUI",
      side: Side.DEPOSIT,
    },
  ];

  suilendClient.claimRewards(
    userAddress,
    obligationOwnerCap,
    rewards,
    rewardsTx
  );

  await suiClient.signAndExecuteTransaction({
    signer: keypair,
    transaction: rewardsTx,
  });
}
```

### Administrative Example

```typescript
async function adminExample() {
  const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
  const suilendClient = await SuilendClient.initialize(
    LENDING_MARKET_ID,
    suiClient
  );

  const adminKeypair = Ed25519Keypair.fromSecretKey(/* admin secret key */);
  const lendingMarketOwnerCapId = "owner-cap-id";

  // Create new reserve
  const createReserveTx = new Transaction();

  await suilendClient.createReserve(
    lendingMarketOwnerCapId,
    createReserveTx,
    "pyth-price-feed-id",
    "0x2::sui::SUI",
    {
      // Reserve configuration parameters
      openLtvPct: 70,
      closeLtvPct: 75,
      maxCloseLtvPct: 80,
      borrowWeightBps: 11000,
      depositLimitUsd: 10000000,
      borrowLimitUsd: 5000000,
      // ... additional config
    }
  );

  await suiClient.signAndExecuteTransaction({
    signer: adminKeypair,
    transaction: createReserveTx,
  });

  // Add liquidity mining rewards
  const addRewardTx = new Transaction();

  await suilendClient.addReward(
    adminKeypair.toSuiAddress(),
    lendingMarketOwnerCapId,
    0n, // reserve array index
    true, // is deposit reward
    "0x2::sui::SUI",
    "1000000000000", // 1000 SUI in rewards
    BigInt(Date.now()), // start time
    BigInt(Date.now() + 30 * 24 * 60 * 60 * 1000), // end time (30 days)
    addRewardTx
  );

  await suiClient.signAndExecuteTransaction({
    signer: adminKeypair,
    transaction: addRewardTx,
  });
}
```

## Generated Code

The SDK includes auto-generated TypeScript bindings for all on-chain smart contract functions and data structures. These are located in the `_generated` directory and provide:

* **Function bindings**: Direct access to all smart contract functions
* **Struct definitions**: TypeScript interfaces for all on-chain data structures
* **Type safety**: Full type checking for all blockchain interactions

The generated code is organized by package and module:

* `suilend/`: Core Suilend protocol functions and structs
* `_dependencies/`: External dependencies (Sui framework, Pyth, etc.)
* `_framework/`: Framework utilities and loaders

## Types and Enums

### Core Enums

```typescript
enum Side {
  DEPOSIT = "deposit",
  BORROW = "borrow",
}

enum Action {
  DEPOSIT = "deposit",
  WITHDRAW = "withdraw",
  BORROW = "borrow",
  REPAY = "repay",
}
```

### Key Interfaces

```typescript
interface ClaimRewardsReward {
  reserveArrayIndex: bigint;
  rewardIndex: bigint;
  rewardCoinType: string;
  side: Side;
}

interface CreateReserveConfigArgs {
  openLtvPct: number;
  closeLtvPct: number;
  maxCloseLtvPct: number;
  borrowWeightBps: number;
  depositLimitUsd: number;
  borrowLimitUsd: number;
  // ... additional configuration fields
}
```

## Configuration

### Environment Variables

The SDK behavior can be configured using environment variables:

* `NEXT_PUBLIC_SUILEND_USE_BETA_MARKET`: Set to "true" to use beta market endpoints

### Constants

```typescript
// Available lending markets
export const LENDING_MARKETS: UiLendingMarket[];
export const LENDING_MARKET_ID: string; // Main market ID
export const LENDING_MARKET_TYPE: string; // Main market type

// Precision constants
export const WAD = new BigNumber(10).pow(18);
```

## Error Handling

The SDK uses standard JavaScript Error objects and blockchain-specific errors from the Sui SDK. Always wrap SDK calls in try-catch blocks:

```typescript
try {
  await suilendClient.depositIntoObligation(/* ... */);
} catch (error) {
  console.error("Deposit failed:", error.message);
  // Handle error appropriately
}
```

## Performance Considerations

* **Batch operations**: Use transactions to batch multiple operations
* **Refresh cycles**: Call `refreshAll()` to update obligation state before operations
* **Gas optimization**: Merge coins when possible to reduce transaction complexity

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## Support

* **Documentation**: This README and inline code documentation
* **Discord**: Join our [#dev-support](https://discord.com/channels/1202984617087598622/1238023733403193385) channel
* **Issues**: Report bugs on [GitHub Issues](https://github.com/suilend/suilend-fe-public/issues)

## License

MIT License - see LICENSE file for details.


---

# 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.suilend.fi/ecosystem/suilend-sdk-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.
