Suilend SDK

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.

Table of Contents

Installation


npm install @suilend/sdk

Peer Dependencies

The SDK requires the following peer dependencies:


npm install @mysten/[email protected] @mysten/[email protected] @suilend/sui-fe@^0.3.5

Quick Start


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


class SuilendClient {

static async initialize(

lendingMarketId: string,

lendingMarketType: string,

client: SuiClient,

logPackageId?: boolean

): Promise<SuilendClient>;

}

Core Operations

Deposit Operations


// 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


// 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


// 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


// Liquidate unhealthy obligation

async liquidate(

transaction: Transaction,

obligation: Obligation<string>,

repayCoinType: string,

withdrawCoinType: string,

repayCoinId: TransactionObjectInput

): Promise<TransactionResult>

Reward Operations


// 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


// 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


// 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:


// 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:


// 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


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


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


enum Side {

DEPOSIT = "deposit",

BORROW = "borrow",

}

  

enum Action {

DEPOSIT = "deposit",

WITHDRAW = "withdraw",

BORROW = "borrow",

REPAY = "repay",

}

Key Interfaces


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


// 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:


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 channel

  • Issues: Report bugs on GitHub Issues

License

MIT License - see LICENSE file for details.