mcpField
L
lulo

lulo

github.com/sendaifun其他130136 次安装13 周前更新
代码仓库

关于 lulo

lulo 是面向 Solana 应用开发者的 DeFi 储蓄平台集成指南,提供 API 和示例以构建存取款及账户查询功能。它支持自动收益分配、风险保护和自定义协议配置。

主要功能

  1. 01跨协议自动分配存款以获取收益
  2. 02Protected、Boosted 和自定义存款
  3. 03生成存款与取款交易
  4. 04查询账户余额、收益和 APY
  5. 05查看资金池利率与流动性

适用场景

  1. 01在 Solana 应用中集成存款与取款
  2. 02查看用户持仓及利息数据
  3. 03比较资金池 APY 与容量

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sendaifun/skills --skill lulo

安装后在 Claude Code 中输入/lulo确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

docs/
troubleshooting.md
examples/balance/
balance.ts
examples/deposit/
deposit.ts
examples/integration/
full-integration.ts
examples/withdraw/
withdraw.ts
resources/
api-reference.md
token-addresses.md
templates/
lulo-client.ts

详细介绍

Lulo 开发指南

关于如何将 Lulo(Solana 上唯一的借贷聚合器)集成到应用中的全面指南。Lulo 会自动将存款路由到收益率最高的 DeFi 协议,并提供可选的智能合约保护。

什么是 Lulo?

Lulo(前身为 FlexLend)是 Solana 上面向稳定币的 DeFi 储蓄平台。它会自动将存款分配到集成的协议中,以最大化收益,同时维持所需的风险敞口。

主要功能
功能描述
收益聚合自动将存款路由到收益率最高的协议
Lulo Protect内置智能合约风险保护(受保护 / 增益存款)
自定义存款全面控制协议分配和风险参数
即时提现无锁定期(增益存款除外,其设有 48 小时冷却期)
多协议集成 Kamino、Drift、MarginFi、Jupiter
无托管资金直接流向集成的协议,而非由 Lulo 持有
为什么使用 Lulo?
  • 自动再平衡:每小时检查利率,并自动将资金转移到收益更高的地方
  • 风险管理:可选择受保护(有保险)、增益(更高收益)或自定义存款
  • 零管理费:仅收取一次性初始化费用 0.005 SOL
  • 多重奖励累积:单笔存款即可赚取多个协议的奖励
  • 终身存款人数超过 9,400 人,定向流动性超过 3,400 万美元

概述

Lulo 提供三种存款类型:

  • 受保护存款:收益稳定,并自动获得针对协议故障的保障
  • 增益存款:为受保护存款提供保险,从而获得更高收益
  • 自定义存款:直接控制哪些协议会收到你的资金
集成的协议
协议描述
Kamino Finance借贷和流动性金库
Drift Protocol永续合约和借贷
MarginFi借贷
Jupiter借贷 / 赚取收益功能
支持的代币
  • 稳定币:USDC、USDT、USDS、PYUSD
  • 原生代币:SOL
  • LST:bSOL、JitoSOL、mSOL
  • 其他:BONK、JUP、ORCA、COPE、CASH

最低存款额:稳定币为 100 美元,原生代币为 1 SOL


快速开始

API 身份验证

所有 API 请求都需要有效的 API 密钥。请从 Lulo Developer Dashboard 获取密钥。

const headers = {
  'Content-Type': 'application/json',
  'x-api-key': process.env.LULO_API_KEY,
};
基础 URL
环境URL
生产环境https://api.lulo.fi
Blinkshttps://blink.lulo.fi
开发者门户https://dev.lulo.fi

API 参考

生成存款交易

创建用于将代币存入 Lulo 的序列化交易。

端点:POST /v1/generate.transactions.deposit

查询参数:

参数类型描述
priorityFeenumber以 microlamports 为单位的优先费用(例如,500000)

请求正文:

{
  "owner": "YourWalletPublicKey",
  "mintAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "depositType": "protected",
  "amount": 100000000
}

响应:

{
  "transaction": "base64EncodedSerializedTransaction",
  "lastValidBlockHeight": 123456789
}
生成提现交易

创建用于从 Lulo 提取代币的序列化交易。

端点:POST /v1/generate.transactions.withdraw

查询参数:

参数类型描述
priorityFeenumber以 microlamports 为单位的优先费用

请求正文:

{
  "owner": "YourWalletPublicKey",
  "mintAddress": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "withdrawType": "protected",
  "amount": 50000000
}
获取账户数据

获取用户余额、已赚取的利息和 APY 指标。

端点:GET /v1/account/{walletAddress}

响应:

{
  "totalDeposited": 1000000000,
  "totalInterestEarned": 5000000,
  "currentApy": 8.5,
  "positions": [
    {
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "depositType": "protected",
      "balance": 500000000,
      "interestEarned": 2500000,
      "apy": 7.2
    }
  ]
}
获取资金池数据

返回当前 APY、流动性金额和容量指标。

端点:GET /v1/pools

响应:

{
  "pools": [
    {
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "symbol": "USDC",
      "protectedApy": 6.5,
      "boostedApy": 9.2,
      "totalDeposited": 34000000000000,
      "availableCapacity": 10000000000000
    }
  ]
}
获取待处理的提现

列出包含冷却期的有效提现请求。

端点:GET /v1/account/{walletAddress}/pending-withdrawals

初始化推荐人

设置推荐人账户以赚取推荐费用。

端点:POST /v1/referrer/initialize

领取推荐奖励

处理推荐费领取。

端点:POST /v1/referrer/claim


存款类型说明

受保护存款

专为寻求稳定收益并希望获得自动保障的风险厌恶型用户设计。

运作方式:

  1. 存款通过集成协议中的借贷赚取利息
  2. 部分利息分配给增强型存款用户(保障费用)
  3. 如果某个协议发生故障,增强型存款会自动弥补受保护存款的损失

优势:

  • 风险较低,享有优先保障
  • 收益稳定且可预测
  • 无需提交索赔,保障会自动生效
  • 可即时提款

保障范围:智能合约漏洞利用、预言机故障、坏账事件

不在保障范围内:Solana 网络故障、USDC 脱锚、Lulo 合约故障

增强型存款

为受保护存款用户提供保险保障,以换取更高收益。

运作方式:

  1. 通过集成协议赚取借贷收益
  2. 通过受保护存款的利息分成获得额外收益
  3. 在协议发生故障时充当第一损失层

优势:

  • APY 更高(通常比受保护存款高 1-2%)
  • 双重收入来源(借贷收益 + 保障费用)

风险:

  • 协议发生故障时处于第一损失位置
  • 提款有 48 小时冷却期
自定义存款

全面掌控协议分配和风险参数。

功能:

  • 选择特定协议(Kamino、Drift、MarginFi、Jupiter)
  • 为每个协议设置最大敞口上限
  • 收益变化时自动重新分配
  • 不提供保障(直接承担协议敞口)

示例:如果将最大敞口设为 50%,并选择 3 个协议,则任何单个协议中都不会存入超过一半的资金。


集成示例

TypeScript:存入 Lulo
import { Connection, Transaction, VersionedTransaction, Keypair } from '@solana/web3.js';

const LULO_API_URL = 'https://api.lulo.fi';

interface DepositParams {
  owner: string;
  mintAddress: string;
  amount: number;
  depositType: 'protected' | 'boosted' | 'regular';
  priorityFee?: number;
}

async function generateDepositTransaction(params: DepositParams): Promise<string> {
  const { owner, mintAddress, amount, depositType, priorityFee = 500000 } = params;

  const response = await fetch(
    `${LULO_API_URL}/v1/generate.transactions.deposit?priorityFee=${priorityFee}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.LULO_API_KEY!,
      },
      body: JSON.stringify({
        owner,
        mintAddress,
        depositType,
        amount,
      }),
    }
  );

  if (!response.ok) {
    throw new Error(`Deposit failed: ${response.statusText}`);
  }

  const data = await response.json();
  return data.transaction;
}

async function deposit(
  connection: Connection,
  wallet: Keypair,
  mintAddress: string,
  amount: number,
  depositType: 'protected' | 'boosted' | 'regular' = 'protected'
): Promise<string> {
  // Generate deposit transaction
  const serializedTx = await generateDepositTransaction({
    owner: wallet.publicKey.toBase58(),
    mintAddress,
    amount,
    depositType,
  });

  // Deserialize and sign
  const txBuffer = Buffer.from(serializedTx, 'base64');
  const transaction = VersionedTransaction.deserialize(txBuffer);
  transaction.sign([wallet]);

  // Send and confirm
  const signature = await connection.sendTransaction(transaction);
  await connection.confirmTransaction(signature, 'confirmed');

  console.log('Deposit successful:', signature);
  return signature;
}

// Usage
const connection = new Connection('https://api.mainnet-beta.solana.com');
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';

await deposit(
  connection,
  wallet,
  USDC_MINT,
  100_000_000, // 100 USDC (6 decimals)
  'protected'
);
TypeScript:从 Lulo 提款
interface WithdrawParams {
  owner: string;
  mintAddress: string;
  amount: number;
  withdrawType: 'protected' | 'boosted' | 'regular';
  priorityFee?: number;
}

async function generateWithdrawTransaction(params: WithdrawParams): Promise<string> {
  const { owner, mintAddress, amount, withdrawType, priorityFee = 500000 } = params;

  const response = await fetch(
    `${LULO_API_URL}/v1/generate.transactions.withdraw?priorityFee=${priorityFee}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.LULO_API_KEY!,
      },
      body: JSON.stringify({
        owner,
        mintAddress,
        withdrawType,
        amount,
      }),
    }
  );

  if (!response.ok) {
    throw new Error(`Withdrawal failed: ${response.statusText}`);
  }

  const data = await response.json();
  return data.transaction;
}

async function withdraw(
  connection: Connection,
  wallet: Keypair,
  mintAddress: string,
  amount: number,
  withdrawType: 'protected' | 'boosted' | 'regular' = 'protected'
): Promise<string> {
  const serializedTx = await generateWithdrawTransaction({
    owner: wallet.publicKey.toBase58(),
    mintAddress,
    amount,
    withdrawType,
  });

  const txBuffer = Buffer.from(serializedTx, 'base64');
  const transaction = VersionedTransaction.deserialize(txBuffer);
  transaction.sign([wallet]);

  const signature = await connection.sendTransaction(transaction);
  await connection.confirmTransaction(signature, 'confirmed');

  console.log('Withdrawal successful:', signature);
  return signature;
}
TypeScript:获取账户余额
interface LuloPosition {
  mint: string;
  depositType: string;
  balance: number;
  interestEarned: number;
  apy: number;
}

interface LuloAccount {
  totalDeposited: number;
  totalInterestEarned: number;
  currentApy: number;
  positions: LuloPosition[];
}

async function getAccountData(walletAddress: string): Promise<LuloAccount> {
  const response = await fetch(
    `${LULO_API_URL}/v1/account/${walletAddress}`,
    {
      headers: {
        'x-api-key': process.env.LULO_API_KEY!,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to fetch account: ${response.statusText}`);
  }

  return response.json();
}

// Usage
const account = await getAccountData(wallet.publicKey.toBase58());
console.log('Total Deposited:', account.totalDeposited);
console.log('Interest Earned:', account.totalInterestEarned);
console.log('Current APY:', account.currentApy);
使用 Solana Agent Kit
import { SolanaAgentKit } from 'solana-agent-kit';

const agent = new SolanaAgentKit(
  privateKey,
  rpcUrl,
  openAiApiKey
);

// Lend USDC using Lulo (gets best APR)
const signature = await agent.methods.lendAssets(
  agent,
  100 // amount of USDC to lend
);

console.log('Lending transaction:', signature);
Python:集成 Lulo
import aiohttp
import os
from solders.keypair import Keypair
from solders.transaction import VersionedTransaction
from solana.rpc.async_api import AsyncClient
from solana.rpc.commitment import Confirmed
from solana.rpc.types import TxOpts
import base64

LULO_API_URL = "https://api.lulo.fi"
LULO_API_KEY = os.environ.get("LULO_API_KEY")

async def lulo_deposit(
    client: AsyncClient,
    wallet: Keypair,
    mint_address: str,
    amount: int,
    deposit_type: str = "protected"
) -> str:
    """Deposit tokens to Lulo for yield optimization."""

    async with aiohttp.ClientSession() as session:
        # Generate deposit transaction
        async with session.post(
            f"{LULO_API_URL}/v1/generate.transactions.deposit?priorityFee=500000",
            headers={
                "Content-Type": "application/json",
                "x-api-key": LULO_API_KEY,
            },
            json={
                "owner": str(wallet.pubkey()),
                "mintAddress": mint_address,
                "depositType": deposit_type,
                "amount": amount,
            }
        ) as response:
            if response.status != 200:
                raise Exception(f"Deposit failed: {await response.text()}")

            data = await response.json()
            tx_data = base64.b64decode(data["transaction"])

    # Deserialize, sign, and send
    transaction = VersionedTransaction.from_bytes(tx_data)
    transaction.sign([wallet])

    signature = await client.send_transaction(
        transaction,
        opts=TxOpts(preflight_commitment=Confirmed)
    )

    await client.confirm_transaction(signature.value, commitment="confirmed")

    return str(signature.value)

async def lulo_withdraw(
    client: AsyncClient,
    wallet: Keypair,
    mint_address: str,
    amount: int,
    withdraw_type: str = "protected"
) -> str:
    """Withdraw tokens from Lulo."""

    async with aiohttp.ClientSession() as session:
        async with session.post(
            f"{LULO_API_URL}/v1/generate.transactions.withdraw?priorityFee=500000",
            headers={
                "Content-Type": "application/json",
                "x-api-key": LULO_API_KEY,
            },
            json={
                "owner": str(wallet.pubkey()),
                "mintAddress": mint_address,
                "withdrawType": withdraw_type,
                "amount": amount,
            }
        ) as response:
            if response.status != 200:
                raise Exception(f"Withdrawal failed: {await response.text()}")

            data = await response.json()
            tx_data = base64.b64decode(data["transaction"])

    transaction = VersionedTransaction.from_bytes(tx_data)
    transaction.sign([wallet])

    signature = await client.send_transaction(
        transaction,
        opts=TxOpts(preflight_commitment=Confirmed)
    )

    await client.confirm_transaction(signature.value, commitment="confirmed")

    return str(signature.value)

# Usage
async def main():
    client = AsyncClient("https://api.mainnet-beta.solana.com")
    wallet = Keypair.from_base58_string("your-private-key")

    USDC_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"

    # Deposit 100 USDC
    signature = await lulo_deposit(
        client,
        wallet,
        USDC_MINT,
        100_000_000,  # 100 USDC
        "protected"
    )
    print(f"Deposit: {signature}")
使用 Lulo Blinks

Lulo 还支持 Solana Actions/Blinks,简化交互操作:

// Blink endpoint for lending
const blinkUrl = `https://blink.lulo.fi/actions?amount=${amount}&symbol=USDC`;

// Fetch blink metadata
const response = await fetch(blinkUrl);
const blinkData = await response.json();

// Execute the action
const postResponse = await fetch(blinkUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ account: walletAddress }),
});

const { transaction } = await postResponse.json();
// Sign and send transaction...

常见代币地址

代币铸造地址
USDCEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
USDTEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
USDSUSDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA
PYUSD2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo
SOL(包装型)So11111111111111111111111111111111111111112
mSOLmSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So
JitoSOLJ1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn
bSOLbSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1

最佳实践

安全性
  1. 切勿公开 API 密钥 - 使用环境变量
  2. 验证交易 - 签名前先模拟交易
  3. 设置合适的滑点 - 考虑汇率变化
  4. 监控持仓 - 定期检查余额和 APY
性能
  1. 使用优先费 - 使用 500,000+ 微 lamport 以加快确认速度
  2. 批量操作 - 尽可能合并多个操作
  3. 缓存池数据 - 利率每小时更新,请适当缓存
错误处理
try {
  const signature = await deposit(connection, wallet, USDC_MINT, amount, 'protected');
} catch (error) {
  if (error.message.includes('BAD_REQUEST')) {
    console.error('Invalid parameters');
  } else if (error.message.includes('UNAUTHORIZED')) {
    console.error('Invalid API key');
  } else if (error.message.includes('NOT_FOUND')) {
    console.error('Account or pool not found');
  } else {
    throw error;
  }
}
监控 APY
async function monitorRates(interval: number = 3600000) { // 1 hour
  setInterval(async () => {
    const pools = await fetch(`${LULO_API_URL}/v1/pools`, {
      headers: { 'x-api-key': process.env.LULO_API_KEY! },
    }).then(r => r.json());

    pools.pools.forEach(pool => {
      console.log(`${pool.symbol}: Protected ${pool.protectedApy}% | Boosted ${pool.boostedApy}%`);
    });
  }, interval);
}

费用结构

费用类型金额适用时间
初始化0.005 SOL仅首次存款
管理无-
提款无-
交易可变每笔交易(Solana 费用)

资源


技能结构

lulo/
├── SKILL.md                      # This file
├── resources/
│   ├── api-reference.md          # Complete API documentation
│   └── token-addresses.md        # Supported token addresses
├── examples/
│   ├── deposit/
│   │   └── deposit.ts            # Deposit examples
│   ├── withdraw/
│   │   └── withdraw.ts           # Withdrawal examples
│   ├── balance/
│   │   └── balance.ts            # Balance query examples
│   └── integration/
│       └── full-integration.ts   # Complete integration example
├── templates/
│   └── lulo-client.ts            # Ready-to-use client template
└── docs/
    └── troubleshooting.md        # Common issues and solutions

评论

支持 Markdown