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