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 operationsAPI: 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 operationsGas optimization: Merge coins when possible to reduce transaction complexity
Contributing
Fork the repository
Create a feature branch
Make your changes
Add tests if applicable
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.