### Install Suilend SDK and Dependencies
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
Installs the Suilend SDK and its required peer dependencies using npm. Ensure you have Node.js 16+ or Bun installed. This command fetches the necessary packages for interacting with the Suilend protocol.
```bash
npm install @suilend/sdk @mysten/bcs@1.6.0 @mysten/sui@1.28.2 @suilend/sui-fe@^0.3.5
```
--------------------------------
### Install Suilend SDK
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Installs the Suilend SDK using npm. This is the first step to integrate the SDK into your project. It requires Node.js and npm to be installed.
```bash
npm install @suilend/sdk
```
--------------------------------
### Initialize Suilend and Sui Clients (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
Initializes the SuilendClient and SuiClient for interacting with the Sui blockchain and the Suilend protocol. This setup requires the lending market details and a Sui client instance. It also demonstrates creating a keypair for user authentication.
```typescript
import {
SuilendClient,
LENDING_MARKET_ID,
LENDING_MARKET_TYPE,
} from "@suilend/sdk";
import { SuiClient } from "@mysten/sui/client";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
// Initialize Sui client
const suiClient = new SuiClient({
url: process.env.SUI_RPC_URL || "https://fullnode.mainnet.sui.io",
});
// Initialize Suilend client
const suilendClient = await SuilendClient.initialize(
LENDING_MARKET_ID,
LENDING_MARKET_TYPE,
suiClient
);
// Set up your keypair (in production, load from secure storage)
const keypair = Ed25519Keypair.fromSecretKey(/* your secret key */);
const userAddress = keypair.toSuiAddress();
```
--------------------------------
### TypeScript: Full Lending Flow Example
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
This TypeScript code demonstrates the complete lending lifecycle on Suilend. It includes initializing clients, creating an obligation, depositing SUI as collateral, borrowing USDC, claiming rewards, repaying the loan, and withdrawing collateral. It requires @suilend/sdk and @mysten/sui dependencies.
```typescript
import {
SuilendClient,
LENDING_MARKET_ID,
LENDING_MARKET_TYPE,
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 fullLendingFlow() {
// Initialize clients
const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
const suilendClient = await SuilendClient.initialize(
LENDING_MARKET_ID,
LENDING_MARKET_TYPE,
suiClient
);
// Set up keypair (replace with your actual key management)
const keypair = Ed25519Keypair.fromSecretKey(/* your secret key */);
const userAddress = keypair.toSuiAddress();
console.log("Starting full lending flow for address:", userAddress);
try {
// 1. Create obligation
console.log("1. Creating obligation...");
const createTx = new Transaction();
const obligationOwnerCap = suilendClient.createObligation(createTx);
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction: createTx,
});
console.log("✓ Obligation created");
// 2. Deposit collateral
console.log("2. Depositing 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,
});
console.log("✓ 5 SUI deposited as collateral");
// 3. Borrow against collateral
console.log("3. Borrowing USDC...");
const borrowTx = new Transaction();
// Get the obligation ID (in real app, you'd store this)
const caps = await SuilendClient.getObligationOwnerCaps(
userAddress,
[LENDING_MARKET_TYPE],
suiClient
);
const obligationId = caps[0].obligationId;
const obligation = await SuilendClient.getObligation(
obligationId,
[LENDING_MARKET_TYPE],
suiClient
);
// Refresh before borrowing
await suilendClient.refreshAll(borrowTx, obligation);
await suilendClient.borrowAndSendToUser(
userAddress,
obligationOwnerCap,
obligationId,
"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN",
"1000000", // 1 USDC
borrowTx
);
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction: borrowTx,
});
console.log("✓ 1 USDC borrowed");
// 4. Wait some time for rewards to accrue (in real app)
console.log("4. Claiming rewards...");
const rewardsTx = new Transaction();
const rewards = [
{
reserveArrayIndex: 0n,
rewardIndex: 0n,
rewardCoinType: "0x2::sui::SUI",
side: Side.DEPOSIT,
},
];
try {
suilendClient.claimRewardsAndSendToUser(
userAddress,
obligationOwnerCap,
rewards,
rewardsTx
);
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction: rewardsTx,
});
console.log("✓ Rewards claimed");
} catch (error) {
console.log("No rewards available to claim");
}
// 5. Repay part of the loan
console.log("5. Repaying loan...");
const repayTx = new Transaction();
await suilendClient.repayIntoObligation(
userAddress,
obligationId,
"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN",
"500000", // 0.5 USDC
repayTx
);
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction: repayTx,
});
console.log("✓ 0.5 USDC repaid");
// 6. Withdraw some collateral
console.log("6. Withdrawing collateral...");
const withdrawTx = new Transaction();
// Refresh obligation before withdrawal
const updatedObligation = await SuilendClient.getObligation(
obligationId,
[LENDING_MARKET_TYPE],
suiClient
);
await suilendClient.refreshAll(withdrawTx, updatedObligation);
await suilendClient.withdrawAndSendToUser(
userAddress,
obligationOwnerCap,
obligationId,
"0x2::sui::SUI",
"1000000000", // 1 SUI
withdrawTx
);
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction: withdrawTx,
});
console.log("✓ 1 SUI withdrawn");
console.log("🎉 Full lending flow completed successfully!");
} catch (error) {
console.error("❌ Error in lending flow:", error.message);
throw error;
}
}
// Run the full flow
fullLendingFlow().catch(console.error);
```
--------------------------------
### Quick Start: Deposit Tokens with Suilend SDK
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Demonstrates how to initialize the Suilend and Sui clients, create a transaction, deposit tokens into the lending market, and execute the transaction. It requires an active Sui network connection and a Keypair for signing.
```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,
});
```
--------------------------------
### Perform First Suilend Deposit (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
Guides through making the first deposit to the Suilend protocol. It includes creating a new obligation if one doesn't exist, depositing SUI tokens as collateral, and executing the transaction. Requires an initialized SuilendClient, SuiClient, and a keypair.
```typescript
async function firstDeposit() {
const transaction = new Transaction();
try {
// Step 1: Create an obligation (if you don't have one)
const existingCaps = await checkExistingObligations();
let obligationOwnerCap;
if (existingCaps.length === 0) {
console.log("Creating new obligation...");
obligationOwnerCap = suilendClient.createObligation(transaction);
} else {
console.log("Using existing obligation...");
obligationOwnerCap = existingCaps[0].id;
}
// Step 2: Deposit 1 SUI into the obligation as collateral
await suilendClient.depositIntoObligation(
userAddress,
"0x2::sui::SUI", // SUI coin type
"1000000000", // 1 SUI in MIST (1 SUI = 10^9 MIST)
transaction,
obligationOwnerCap
);
// Step 3: Execute the transaction
const result = await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction,
options: {
showEffects: true,
showEvents: true,
},
});
console.log("Deposit successful!");
console.log("Transaction digest:", result.digest);
return result;
} catch (error) {
console.error("Deposit failed:", error.message);
throw error;
}
}
// Run the deposit
await firstDeposit();
```
--------------------------------
### Administrative Actions
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Provides examples for administrative tasks such as creating new reserves and adding liquidity mining rewards.
```APIDOC
## Administrative Actions
### Description
This section covers administrative operations for the Suilend protocol, including setting up new reserves and managing reward programs.
### Method
N/A (Illustrative Code Example)
### Endpoint
N/A
### Parameters
N/A
### Request 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,
});
}
```
### Response
N/A (Illustrative Code Example)
```
--------------------------------
### Batch Multiple Operations in One Transaction (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
This example demonstrates how to combine multiple SDK operations into a single transaction for improved gas efficiency. It includes refreshing state, claiming rewards, and depositing rewards, all executed atomically. This approach helps avoid redundant transaction fees and ensures atomicity. Requires initialized 'suilendClient', 'suiClient', 'keypair', 'userAddress', 'obligationOwnerCap', 'rewards', and 'obligation'.
```typescript
const transaction = new Transaction();
// Refresh state
await suilendClient.refreshAll(transaction, obligation);
// Claim rewards
suilendClient.claimRewards(userAddress, obligationOwnerCap, rewards, transaction);
// Deposit claimed rewards
await suilendClient.depositIntoObligation(/* ... */, transaction, obligationOwnerCap);
// Execute all in one transaction
await suiClient.signAndExecuteTransaction({ signer: keypair, transaction });
```
--------------------------------
### Install Peer Dependencies for Suilend SDK
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Installs the required peer dependencies for the Suilend SDK. These packages are necessary for the SDK to function correctly with the Sui blockchain and its related tools.
```bash
npm install @mysten/bcs@1.6.0 @mysten/sui@1.28.2 @suilend/sui-fe@^0.3.5
```
--------------------------------
### Set Gas Budget for Transactions (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
This example shows how to set a gas budget for a transaction using the `Transaction` class. A specific budget (0.01 SUI in this case) is applied before signing and executing the transaction. This is crucial for complex operations to avoid 'gas budget exceeded' errors. Requires initialized 'suiClient' and 'keypair'.
```typescript
const transaction = new Transaction();
// Add your operations...
transaction.setGasBudget(10000000); // 0.01 SUI
await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction,
});
```
--------------------------------
### Complete Pool Setup for Yield-Bearing USDC/SUI Pool in Move
Source: https://docs.suilend.fi/steamm-integration
This function demonstrates the complete setup for a yield-bearing USDC/SUI pool. It initializes coin metadata, creates lending banks with specified utilization rates, and establishes an AMM pool. Dependencies include 'steamm', 'cpmm', and 'suilend' modules. It takes registry, lending market, global admin, and transaction context as input, and returns the created pool and bank IDs.
```move
module my_protocol::complete_example {
use steamm::{registry, bank, cpmm, global_admin};
use steamm::pool::Pool;
use steamm_scripts::pool_script_v2;
use suilend::lending_market::LendingMarket;
// Token types
public struct USDC has drop {}
public struct SUI has drop {}
public struct B_USDC has drop {}
public struct B_SUI has drop {}
public struct LP_USDC_SUI has drop {}
/// Complete setup for a yield-bearing USDC/SUI pool
public fun setup_complete_pool<
P
>(
registry: &mut Registry,
lending_market: &mut LendingMarket
,
global_admin: &GlobalAdmin,
ctx: &mut TxContext,
): (
Pool,
ID, // Bank USDC ID
ID, // Bank SUI ID
) {
// 1. Setup all coin metadata (implementation details omitted)
let (
meta_usdc, meta_sui, mut meta_lp,
mut meta_b_usdc, mut meta_b_sui,
lp_treasury, b_usdc_treasury, b_sui_treasury
) = setup_all_coin_metadata(ctx);
// 2. Create banks using builder pattern (needed for lending setup)
let mut builder_usdc = bank::new(
registry, &meta_usdc, &mut meta_b_usdc,
b_usdc_treasury, lending_market, ctx
);
let mut builder_sui = bank::new
(
registry, &meta_sui, &mut meta_b_sui,
b_sui_treasury, lending_market, ctx
);
// 3. Initialize lending with 80% utilization before sharing
builder_usdc.bank_mut().init_lending(
global_admin, lending_market,
8000, 1000, ctx // 80% ± 10%
);
builder_sui.bank_mut().init_lending(
global_admin, lending_market,
8000, 1000, ctx // 80% ± 10%
);
// 4. Share the banks
let bank_usdc_id = builder_usdc.build();
let bank_sui_id = builder_sui.build();
// 5. Create the AMM pool
let pool = cpmm::new(
registry,
30, // 0.3% swap fee
0, // No offset
&meta_b_usdc,
&meta_b_sui,
&mut meta_lp,
lp_treasury,
ctx,
);
(pool, bank_usdc_id, bank_sui_id)
}
/// Add initial liquidity to the pool
public fun bootstrap_liquidity<
P
>(
pool: &mut Pool,
bank_usdc: &mut Bank,
bank_sui: &mut Bank
,
lending_market: &LendingMarket
,
usdc_amount: u64,
sui_amount: u64,
clock: &Clock,
ctx: &mut TxContext,
): Coin {
// Create coins for initial liquidity
let mut usdc_coin = coin::mint_for_testing(usdc_amount, ctx);
let mut sui_coin = coin::mint_for_testing(sui_amount, ctx);
// Add liquidity through the script helper
let lp_tokens = pool_script_v2::deposit_liquidity(
pool, bank_usdc, bank_sui, lending_market,
&mut usdc_coin, &mut sui_coin,
usdc_amount, sui_amount,
clock, ctx
);
// Clean up remaining coins
if (usdc_coin.value() > 0) {
transfer::public_transfer(usdc_coin, ctx.sender());
} else {
coin::destroy_zero(usdc_coin);
};
if (sui_coin.value() > 0) {
transfer::public_transfer(sui_coin, ctx.sender());
} else {
coin::destroy_zero(sui_coin);
};
lp_tokens
}
}
```
--------------------------------
### Instantiate Constant Product AMM Pool in Move
Source: https://docs.suilend.fi/steamm-developer-integration-guide
Provides an example of instantiating a Constant Product AMM Quoter for a pool. This involves specifying the token types, fee, offset, metadata, and treasury cap.
```move
// Formula: (x + offset) * y = k
use steamm::cpmm::CpQuoter;
let pool = cpmm::new(
registry,
30, // 0.3% fee
0, // No offset
meta_a, meta_b, meta_lp,
lp_treasury,
ctx,
);
```
--------------------------------
### Complete Pool Setup in Move
Source: https://docs.suilend.fi/steamm-developer-integration-guide
Sets up a yield-bearing USDC/SUI pool by creating coin metadata, initializing banks, configuring lending parameters, and establishing an AMM pool. It requires several dependencies including steamm, steamm_scripts, and suilend modules. The function outputs the created pool and banks.
```move
module my_protocol::complete_example {
use steamm::{registry, bank, cpmm, global_admin};
use steamm::pool::Pool;
use steamm_scripts::pool_script_v2;
use suilend::lending_market::LendingMarket;
// Token types
public struct USDC has drop {}
public struct SUI has drop {}
public struct B_USDC has drop {}
public struct B_SUI has drop {}
public struct LP_USDC_SUI has drop {}
/// Complete setup for a yield-bearing USDC/SUI pool
public fun setup_complete_pool(
registry: &mut Registry,
lending_market: &mut LendingMarket
,
global_admin: &GlobalAdmin,
ctx: &mut TxContext,
): (
Pool,
Bank,
Bank
,
) {
// 1. Setup all coin metadata (implementation details omitted)
let (
meta_usdc, meta_sui, mut meta_lp,
mut meta_b_usdc, mut meta_b_sui,
lp_treasury, b_usdc_treasury, b_sui_treasury
) = setup_all_coin_metadata(ctx);
// 2. Create banks
let mut bank_usdc = bank::create_bank
(
registry, &meta_usdc, &mut meta_b_usdc,
b_usdc_treasury, lending_market, ctx
);
let mut bank_sui = bank::create_bank
(
registry, &meta_sui, &mut meta_b_sui,
b_sui_treasury, lending_market, ctx
);
// 3. Initialize lending with 80% utilization
bank_usdc.init_lending(
global_admin, lending_market,
8000, 1000, ctx // 80% ± 10%
);
bank_sui.init_lending(
global_admin, lending_market,
8000, 1000, ctx // 80% ± 10%
);
// 4. Create the AMM pool
let pool = cpmm::new(
registry,
30, // 0.3% swap fee
0, // No offset
&meta_b_usdc,
&meta_b_sui,
&mut meta_lp,
lp_treasury,
ctx,
);
(pool, bank_usdc, bank_sui)
}
/// Add initial liquidity to the pool
public fun bootstrap_liquidity(
pool: &mut Pool,
bank_usdc: &mut Bank,
bank_sui: &mut Bank
,
lending_market: &LendingMarket
,
usdc_amount: u64,
sui_amount: u64,
clock: &Clock,
ctx: &mut TxContext,
): Coin {
// Create coins for initial liquidity
let mut usdc_coin = coin::mint_for_testing(usdc_amount, ctx);
let mut sui_coin = coin::mint_for_testing(sui_amount, ctx);
// Add liquidity through the script helper
let lp_tokens = pool_script_v2::deposit_liquidity(
pool, bank_usdc, bank_sui, lending_market,
&mut usdc_coin, &mut sui_coin,
usdc_amount, sui_amount,
clock, ctx
);
// Clean up remaining coins
if (usdc_coin.value() > 0) {
transfer::public_transfer(usdc_coin, ctx.sender());
} else {
coin::destroy_zero(usdc_coin);
};
if (sui_coin.value() > 0) {
transfer::public_transfer(sui_coin, ctx.sender());
} else {
coin::destroy_zero(sui_coin);
};
lp_tokens
}
}
```
--------------------------------
### Configure Suilend SDK Environment Variables
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
Sets up environment variables for the Suilend SDK. The `.env` file allows configuration of the beta market usage and the Sui RPC endpoint. By default, it uses the mainnet RPC endpoint and does not use the beta market.
```env
# Optional: Use beta market for testing
NEXT_PUBLIC_SUILEND_USE_BETA_MARKET=false
# Your Sui RPC endpoint (optional, defaults to mainnet)
SUI_RPC_URL=https://fullnode.mainnet.sui.io
```
--------------------------------
### Pool Creation with Existing Bank in Move
Source: https://docs.suilend.fi/steamm-integration
Demonstrates how to create a new liquidity pool when one of the underlying tokens already has an existing bank. This example shows creating a USDC/SUI pool, where the SUI bank is pre-existing.
```move
module my_protocol::usdc_sui_pool {
use steamm::cpmm;
use steamm::pool::Pool;
use steamm::registry::Registry;
public struct MyLpToken has drop {}
public struct MyBTokenUSDC has drop {}
public fun create_usdc_sui_pool(
registry: &mut Registry,
lending_market: &LendingMarket,
ctx: &mut TxContext,
): (Pool, ID) {
// Setup coin metadata (implementation details omitted)
let (meta_usdc, meta_sui, mut meta_lp, mut meta_b_usdc, meta_b_sui,
lp_treasury, b_usdc_treasury) = setup_coin_metadata(ctx);
// Create bank only for USDC since SUI bank already exists
let bank_usdc_id = bank::create_bank_and_share(
registry,
&meta_usdc,
&mut meta_b_usdc,
b_usdc_treasury,
lending_market,
ctx,
);
// Create pool using bToken types
let pool = cpmm::new(
registry,
30, // 0.3% swap fee
0, // No offset
&meta_b_usdc, // bToken USDC metadata
&meta_b_sui, // Existing bToken SUI metadata
&mut meta_lp,
lp_treasury,
ctx,
);
(pool, bank_usdc_id)
}
}
```
--------------------------------
### Suilend Client and Transaction Example (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/suilend-sdk-types-reference
Demonstrates the usage of the `SuilendClient` and associated types for interacting with the Suilend protocol. This example shows how to initialize the client, define reward structures using `ClaimRewardsReward`, and construct a transaction for claiming rewards, highlighting type safety and SDK integration.
```typescript
import {
SuilendClient,
Side,
ClaimRewardsReward,
CreateReserveConfigArgs,
LENDING_MARKET_ID,
} from "@suilend/sdk";
import { SuiClient } from "@mysten/sui/client";
import { Transaction } from "@mysten/sui/transactions";
async function exampleWithTypes() {
const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
const suilendClient = await SuilendClient.initialize(
LENDING_MARKET_ID,
suiClient
);
// Using ClaimRewardsReward type
const rewards: ClaimRewardsReward[] = [
{
reserveArrayIndex: 0n,
rewardIndex: 0n,
rewardCoinType: "0x2::sui::SUI",
side: Side.DEPOSIT,
},
];
// Using Transaction type
const transaction = new Transaction();
// Call with properly typed parameters
suilendClient.claimRewards(
userAddress, // string
obligationCapId, // string
rewards, // ClaimRewardsReward[]
transaction // Transaction
);
}
```
--------------------------------
### Test Setup Utility (Move)
Source: https://docs.suilend.fi/steamm-developer-integration-guide
A test utility function for setting up a Constant Product Market Maker (CPMM) pool scenario. It initializes the necessary components like pool, banks, lending market, and clock for testing purposes. This function is part of the `steamm::test_utils` module and is intended for use within `#[test_only]` blocks.
```move
#[test_only]
use steamm::test_utils;
#[test]
fun test_my_pool() {
let mut scenario = test_scenario::begin(@0x0);
// Use test utilities for quick setup
let (pool, bank_a, bank_b, lending_market, lend_cap, prices, bag, clock) =
test_utils::test_setup_cpmm(30, 0, &mut scenario);
// Your test logic here
// Clean up
destroy(pool);
destroy(bank_a);
// ... destroy other objects
test_scenario::end(scenario);
}
```
--------------------------------
### TypeScript Example for Claiming Rewards
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/suilend-sdk-types-reference
Provides an example of how to use the ClaimRewardsReward interface to define an array of rewards to be claimed. It demonstrates the structure for specifying SUI and USDC rewards for both deposit and borrow sides.
```typescript
const rewards: ClaimRewardsReward[] = [
{
reserveArrayIndex: 0n, // SUI reserve
rewardIndex: 0n, // First reward program
rewardCoinType: "0x2::sui::SUI",
side: Side.DEPOSIT,
},
{
reserveArrayIndex: 1n, // USDC reserve
rewardIndex: 0n,
rewardCoinType: "0x2::sui::SUI",
side: Side.BORROW,
},
];
```
--------------------------------
### Borrow USDC Against SUI Collateral (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
Demonstrates how to borrow USDC against SUI collateral using the Suilend SDK. It involves retrieving obligation details, refreshing state, executing the borrow transaction, and sending the borrowed assets to the user's address. Ensure you have deposited collateral and have a valid `userAddress`, `suiClient`, and `keypair`.
```typescript
async function borrowExample() {
const transaction = new Transaction();
try {
// Step 1: Get your obligation
const obligationOwnerCaps = await SuilendClient.getObligationOwnerCaps(
userAddress,
[LENDING_MARKET_TYPE],
suiClient
);
if (obligationOwnerCaps.length === 0) {
throw new Error("No obligations found. Please deposit first.");
}
const obligationOwnerCap = obligationOwnerCaps[0];
const obligation = await SuilendClient.getObligation(
obligationOwnerCap.obligationId,
[LENDING_MARKET_TYPE],
suiClient
);
// Step 2: Refresh the obligation state
await suilendClient.refreshAll(transaction, obligation);
// Step 3: Borrow 0.5 USDC (assuming USDC has 6 decimals)
const borrowResult = await suilendClient.borrow(
obligationOwnerCap.id,
obligationOwnerCap.obligationId,
"0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN", // USDC coin type
"500000", // 0.5 USDC in smallest denomination
transaction
);
// Step 4: Send borrowed tokens to yourself
transaction.transferObjects([borrowResult], userAddress);
// Step 5: Execute the transaction
const result = await suiClient.signAndExecuteTransaction({
signer: keypair,
transaction,
options: {
showEffects: true,
showEvents: true,
},
});
console.log("Borrow successful!");
console.log("Transaction digest:", result.digest);
return result;
} catch (error) {
console.error("Borrow failed:", error.message);
throw error;
}
}
// Run the borrow
await borrowExample();
```
--------------------------------
### Swap Integration
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Integrates with Decentralized Exchanges (DEXs) for token swapping.
```APIDOC
## POST /getQuote
### Description
Gets a swap quote for a token exchange.
### Method
POST
### Endpoint
/getQuote
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **fromToken** (string) - Required - The token to swap from.
- **toToken** (string) - Required - The token to swap to.
- **amount** (string) - Required - The amount of the `fromToken` to swap.
- **slippage** (number) - Required - The maximum acceptable slippage.
### Request Example
```json
{
"fromToken": "string",
"toToken": "string",
"amount": "string",
"slippage": 0.01
}
```
### Response
#### Success Response (200)
- **swapQuote** (SwapQuote) - The quote for the swap transaction.
#### Response Example
```json
{
"swapQuote": {}
}
```
## POST /executeSwap
### Description
Executes a swap transaction based on a provided quote.
### Method
POST
### Endpoint
/executeSwap
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **quote** (SwapQuote) - Required - The swap quote obtained from `/getQuote`.
- **transaction** (Transaction) - Required - The transaction object.
### Request Example
```json
{
"quote": {},
"transaction": {}
}
```
### Response
#### Success Response (200)
No specific return value, indicates successful completion.
#### Response Example
(void)
```
--------------------------------
### Handle SDK Call Errors with Try-Catch (TypeScript)
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide/getting-started-with-suilend-sdk
This snippet demonstrates how to wrap SDK calls in try-catch blocks to gracefully handle potential errors. It specifically checks for 'insufficient funds' and 'gas budget' errors, providing tailored console messages, and includes a fallback for unexpected errors. Ensure the 'suilendClient' is properly initialized.
```typescript
try {
await suilendClient.depositIntoObligation(/* ... */);
} catch (error) {
if (error.message.includes("insufficient funds")) {
console.error("Not enough tokens in wallet");
} else if (error.message.includes("gas budget")) {
console.error("Increase gas budget");
} else {
console.error("Unexpected error:", error);
}
}
```
--------------------------------
### Administrative Operations
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Provides functionalities for creating and updating reserve configurations.
```APIDOC
## POST /createReserve
### Description
Creates a new reserve in the lending market.
### Method
POST
### Endpoint
/createReserve
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **lendingMarketOwnerCapId** (string) - Required - The ID of the lending market owner capability.
- **transaction** (Transaction) - Required - The transaction object.
- **pythPriceId** (string) - Required - The Pyth price feed ID for the reserve.
- **coinType** (string) - Required - The type of coin for the reserve.
- **createReserveConfigArgs** (CreateReserveConfigArgs) - Required - Configuration arguments for the new reserve.
### Request Example
```json
{
"lendingMarketOwnerCapId": "string",
"transaction": {},
"pythPriceId": "string",
"coinType": "string",
"createReserveConfigArgs": {}
}
```
### Response
#### Success Response (200)
No specific return value, indicates successful completion.
#### Response Example
(void)
## POST /updateReserveConfig
### Description
Updates the configuration of an existing reserve.
### Method
POST
### Endpoint
/updateReserveConfig
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
- **lendingMarketOwnerCapId** (string) - Required - The ID of the lending market owner capability.
- **transaction** (Transaction) - Required - The transaction object.
- **coinType** (string) - Required - The type of coin for the reserve whose configuration is being updated.
- **createReserveConfigArgs** (CreateReserveConfigArgs) - Required - The updated configuration arguments for the reserve.
### Request Example
```json
{
"lendingMarketOwnerCapId": "string",
"transaction": {},
"coinType": "string",
"createReserveConfigArgs": {}
}
```
### Response
#### Success Response (200)
No specific return value, indicates successful completion.
#### Response Example
(void)
```
--------------------------------
### Complete Lending Flow with Suilend SDK
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Demonstrates a full lending cycle using the Suilend SDK, including creating an obligation, depositing collateral, borrowing assets, and claiming rewards. It requires initializing Suilend and Sui clients and uses keypairs for transaction signing. The flow involves multiple transaction steps, each signed and executed.
```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,
});
}
```
--------------------------------
### Complete Lending Flow
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Demonstrates the complete lending process: creating an obligation, depositing collateral, borrowing assets, and claiming rewards.
```APIDOC
## Complete Lending Flow
### Description
This section outlines the steps involved in a complete lending and borrowing cycle using the Suilend SDK.
### Method
N/A (Illustrative Code Example)
### Endpoint
N/A
### Parameters
N/A
### Request Example
```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,
});
}
```
### Response
N/A (Illustrative Code Example)
```
--------------------------------
### Initialize SuilendClient
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Shows the static method to initialize the SuilendClient. This requires the lending market ID, its type, and an initialized SuiClient. Optional logging of the package ID is also available.
```typescript
class SuilendClient {
static async initialize(
lendingMarketId: string,
lendingMarketType: string,
client: SuiClient,
logPackageId?: boolean
): Promise;
}
```
--------------------------------
### Swap Integration Functions - TypeScript
Source: https://docs.suilend.fi/ecosystem/suilend-sdk-guide
Functions for interacting with DEX aggregators to get swap quotes and execute swap transactions.
```typescript
async function getQuote(
fromToken: string,
toToken: string,
amount: string,
slippage: number
): Promise;
async function executeSwap(
quote: SwapQuote,
transaction: Transaction
): Promise
```
--------------------------------
### Configuring Lending Utilization Parameters in Suilend
Source: https://docs.suilend.fi/steamm-developer-integration-guide
Shows how to initialize Suilend lending for a bank, setting the target utilization rate and buffer. This controls how much liquidity is deployed to Suilend for yield generation.
```move
// Configure how much liquidity gets deployed to Suilend
bank.init_lending(
global_admin,
lending_market,
8000, // target_utilization_bps: 80% deployed to Suilend
1000, // utilization_buffer_bps: 10% buffer (70-90% range)
ctx,
);
```