SDK 参考
@stablechain/sdk 的完整功能。这包括来自 createStable 的签名客户端,来自 createStableReader 的只读客户端,以及共享的枚举、常量和错误类。有关演练,请参阅 SDK 快速入门。有关以任务为中心的收益指南,请参阅 使用 SDK 赚取收益。
安装
npm install @stablechain/sdk viemadded 2 packages, audited 3 packages in 2sviem >= 2.0.0 是一个对等依赖项。该包发布为 @stablechain/sdk。
createStable(config)
构造一个 StableClient。返回一个包含 StableClient 下列出的方法的对象。
import { createStable, Network } from "@stablechain/sdk";
const stable = createStable({ network: Network.Mainnet, account });StableClient { transfer, quoteBridge, bridge, quoteSwap, swap, earn }StableConfig
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
network | Network | Network.Mainnet | 目标网络。 |
rpc | string | network 的公共 RPC | RPC 覆盖。 |
account | viem.Account | 服务器端签名器(例如 privateKeyToAccount)。 | |
transport | viem.Transport | 浏览器钱包传输(例如 custom(window.ethereum))。 | |
walletClient | viem.WalletClient | 预构建的钱包客户端。优先于 account 和 transport。 | |
earn | { vault: string } | Morpho V2 保险库配置。调用 stable.earn 存款、取款、赎回和准备 calldata 方法时需要。 | |
merklApiBase | string | https://api.merkl.xyz | Merkl 奖励 API 基础 URL。覆盖以通过您自己的服务器代理并避免浏览器 CORS 限制。 |
提供 account、transport 或 walletClient 中的一个。earn 字段是可选的:转账、桥接和兑换在没有它的情况下也能工作。保险库存款和取款需要它,如果您在没有配置保险库的情况下调用它们,SDK 会抛出 StableValidationError。
StableClient
transfer(params)
在 Stable 上发送原生 USDT0 或任何 ERC-20。将钱包切换到 Stable 链,在缺失时链上获取代币小数位数,并等待收据。
const { txHash } = await stable.transfer({
from: "0xYourAddress",
to: "0xRecipient",
amount: 10,
});{ txHash: "0x8f3a...2d41" }| 参数 | 类型 | 描述 |
|---|---|---|
from | string | 发送方地址。 |
to | string | 接收方地址。 |
amount | number | 人类可读金额。 |
token | string? | ERC-20 合约地址。原生 USDT0 忽略。 |
tokenDecimals | number? | 小数位数。省略时在链上获取。 |
返回 OperationResult ({ txHash, toAmount? })。
quoteBridge(params)
预览桥接。只读。无签名,无 gas。
const quote = await stable.quoteBridge({
fromChain: Chain.Ethereum,
toChain: Chain.Stable,
fromToken: "0xdAC17F958D2ee523a2206206994597C13D831ec7", // USDT on Ethereum
toToken: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736", // USDT0 on Stable
amount: 100,
});{ toAmount: 99.73 }返回 BridgeQuote。
bridge(params)
通过 LI.FI 桥接跨链代币,LI.FI 选择桥接路径。SDK 处理 ERC-20 批准并在发送前将钱包切换到源链。传递预获取的 quote 以跳过内部报价调用。
const { txHash } = await stable.bridge({ ...bridgeParams, quote });{ txHash: "0xabcd...7890" }| 参数 | 类型 | 描述 |
|---|---|---|
fromChain | Chain | 源链。 |
toChain | Chain | 目标链。 |
fromToken | string | 源代币合约地址。 |
toToken | string | 目标代币合约地址。 |
amount | number | 人类可读金额。 |
fromDecimals | number? | 源代币小数位数。默认为 6。 |
recipient | string? | 目标地址。默认为签名者。 |
quote | BridgeQuote? | 预获取的报价。跳过内部报价调用。 |
quoteSwap(params)
在 Stable 上获取 LI.FI 兑换报价。返回一个预构建的交易请求和批准地址。
const quote = await stable.quoteSwap({
fromToken: "0x8a2B28364102Bea189D99A475C494330Ef2bDD0B",
toToken: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
amount: 100,
fromDecimals: 6,
});{ toAmount: 99.81, fromAmount: 100000000n, fromToken: "0x8a2B...", approvalAddress: "0x...", transactionRequest: { ... } }swap(params)
通过 LI.FI 在 Stable 上兑换代币。自动处理 ERC-20 批准并在需要时切换钱包的链。
const { txHash, toAmount } = await stable.swap({ ...swapParams, quote });{ txHash: "0xabcd...", toAmount: 99.81 }| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
fromToken | string | 源代币地址。 | |
toToken | string | 目标代币地址。 | |
amount | number | 人类可读金额。 | |
fromDecimals | number? | 6 | 源代币小数位数。 |
toAddress | string? | signer | 接收方地址。 |
quote | SwapQuote? | 预获取的报价。跳过 LI.FI 调用。 |
stable.earn
将 USDT0 存入 Morpho V2 保险库以获取收益,并领取 Merkl 激励奖励。所有方法都位于 earn 命名空间下,并且需要签名器。存款、取款、赎回和 prepare-calldata 方法还需要在 StableConfig 中设置 earn: { vault }。
const stable = createStable({
network: Network.Mainnet,
account,
earn: { vault: "0xb7Df8db22A5DBBFA9ebeb94b3910aec6a4f05c08" },
});stable.earn { deposit, bulkDeposit, withdraw, bulkWithdraw, redeem, forceWithdraw, forceRedeem, prepareDepositCalldata, prepareWithdrawCalldata, prepareRedeemCalldata, incentiveRewards }金额和份额数量是人类可读的数字。如果您省略资产和份额的小数位数,它们会在链上获取。存款、取款、赎回和强制方法返回 EarnResult ({ txHash, idempotencyKey? }) 并在解析之前等待收据。批量方法返回 BulkEarnResult,incentiveRewards.claim() 返回 MerklClaimResult,这些都在下面的各自部分中描述。
deposit(params)
向保险库提供资产。通过一次调用处理 ERC-20 批准(或钱包支持时的许可签名),然后是存款。
const { txHash } = await stable.earn.deposit({ amount: 100 });{ txHash: "0x8f3a...2d41" }| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
amount | number | 要存入的基础资产,人类可读。 | |
vault | string? | config vault | 保险库地址覆盖。在 bulkDeposit 中跨多个保险库按项目要求。 |
tokenDecimals | number? | on-chain | 基础资产小数位数。 |
slippageTolerance | number? | 0.0003 | 滑点以小数表示(例如 0.003 = 0.3%)。默认为 Morpho 的 0.03%。 |
depositBuffer | number? | 此存款可能消耗的保险库闲置流动性的最大比例(例如 0.8 = 80%)。必须 > 0 且 ≤ 1。如果超出,则在发送前抛出。 | |
idempotencyKey | string? | 去重键。第二次调用一个正在进行的键会返回相同的 Promise。 |
withdraw(params)
提取给定数量的基础资产。当保险库闲置流动性不足时,SDK 会自动从保险库的适配器中解除分配以弥补差额。
const { txHash } = await stable.earn.withdraw({ amount: 50 });{ txHash: "0xabcd...7890" }| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
amount | number | 要提取的基础资产,人类可读。 | |
tokenDecimals | number? | on-chain | 基础资产小数位数。 |
idempotencyKey | string? | 去重键。 |
redeem(params)
将数量的保险库份额赎回为基础资产。与 withdraw 类似,当闲置流动性不足时,它会自动从适配器中解除分配。
const { txHash } = await stable.earn.redeem({ shares: 25 });{ txHash: "0xabcd...7890" }| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
shares | number | 要赎回的 Vault Shares,人类可读。 | |
shareDecimals | number? | on-chain | Vault Share 小数位数。 |
idempotencyKey | string? | 去重键。 |
bulkDeposit(items, options?) / bulkWithdraw(items, options?)
按顺序运行多个存款或取款。默认情况下,批处理会尝试每个项目并返回部分结果。设置 stopOnError: true 以在第一次失败时停止并抛出 StableBulkError。
const result = await stable.earn.bulkDeposit([
{ amount: 100 },
{ amount: 250, vault: "0xAnotherVault" },
]);{ results: [ { status: "fulfilled", txHash: "0x..." }, ... ], succeeded: 2, failed: 0 }items 是 EarnDepositParams(或 EarnWithdrawParams)的数组。options 接受:
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
idempotencyKey | string? | 批处理级别的去重键。 | |
stopOnError | boolean? | false | 在第一次失败时停止并抛出 StableBulkError,而不是返回部分结果。 |
返回 BulkEarnResult ({ results, succeeded, failed, idempotencyKey? })。results 中的每个条目都是 { status: "fulfilled", txHash, vault?, idempotencyKey? } 或 { status: "rejected", error, vault?, idempotencyKey? }。
forceWithdraw(params) / forceRedeem(params)
通过对首先解除分配哪些适配器头寸的明确控制来提取或赎回。当您需要自行选择来源市场而不是 withdraw / redeem 中的自动选择时,请使用这些方法。
const { txHash } = await stable.earn.forceWithdraw({
amount: 1000,
deallocations: [{ adapter: "0xAdapter", amount: 1000 }],
});{ txHash: "0xabcd...7890" }两者都接受 deallocations: ForceDeallocation[] 数组和一个可选的 tokenDecimals(基础资产小数位数,用于解除分配金额;省略时在链上获取)。forceWithdraw 接受 amount;forceRedeem 接受 shares 和可选的 shareDecimals。每个 ForceDeallocation 都是:
| 字段 | 类型 | 描述 |
|---|---|---|
adapter | string | 要解除分配的适配器合约。 |
amount | number | 要解除分配的金额,以基础资产单位表示。 |
marketParams | object? | 仅适用于 Morpho Blue 市场适配器:{ loanToken, collateralToken, oracle, irm, lltv }(lltv 乘以 1e18 后)。保险库适配器省略。 |
prepareDepositCalldata(params) / prepareWithdrawCalldata(params) / prepareRedeemCalldata(params)
构建交易 calldata,不进行签名或发送。使用这些方法通过中继器、免 Gas 流程或多重签名来路由交易。
const { steps, chainId } = await stable.earn.prepareDepositCalldata({ amount: 100 });{ steps: [ { to: "0x...", data: "0x...", value: 0n } ], chainId: 988 }prepareDepositCalldata 返回 EarnDepositCalldata ({ steps, chainId }),其中 steps 是 { to, data, value } 事务的有序列表:一个可选的代币批准,然后是存款。prepareWithdrawCalldata 和 prepareRedeemCalldata 返回 EarnWithdrawCalldata ({ to, data, value, chainId }),一个单一事务。它们接受与其签名对应物相同的参数。
incentiveRewards
获取并申领签名者的 Merkl 奖励代币。这些方法需要签名者,但不需要 earn 保险库配置。
const { rewards } = await stable.earn.incentiveRewards.fetch();
const { txHash, tokenCount } = await stable.earn.incentiveRewards.claim();{ txHash: "0xabcd...7890", tokenCount: 1 }fetch() 返回 MerklRewardsResult ({ chainId, rewards: MerklReward[] }),其中包含每个代币可申领的净金额。claim() 申领提交到当前 Merkl 默克尔树的所有奖励,并返回 MerklClaimResult ({ txHash, tokenCount })。
createStableReader(config)
构造一个只读的 StableReader 用于保险库收益和头寸数据。不需要签名者,只需要您想要读取的地址。
import { createStableReader, Network } from "@stablechain/sdk";
const reader = createStableReader({
network: Network.Mainnet,
address: "0xUserAddress",
earn: { vault: "0xb7Df8db22A5DBBFA9ebeb94b3910aec6a4f05c08" },
});StableReader { earn: { getYield, position, preview, withdrawability, incentiveRewards } }StableReaderConfig
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
address | string | 要读取其头寸和奖励的用户地址。必填。 | |
earn | { vault: string } | 要读取的保险库。必填:如果缺少,createStableReader 将抛出 StableValidationError。 | |
network | Network? | Network.Mainnet | 目标网络。 |
rpc | string? | 公共 RPC | RPC 覆盖。 |
merklApiBase | string? | https://api.merkl.xyz | Merkl 奖励 API 基础 URL。 |
StableReader
getYield()
返回保险库当前的净年化收益率和费用明细。
const vaultYield = await reader.earn.getYield();{ apy: 0.058, native: 0.041, rewards: [ { symbol: "MORPHO", address: "0x...", apr: 0.017 } ], performanceFee: 0.1, managementFee: 0 }返回 VaultYield。apy 是扣除奖励提升后的总净 APY;native 是不包括奖励的基础市场收益。所有值都是小数(0.05 = 5%)。
position()
返回配置地址的当前保险库头寸。
const position = await reader.earn.position();{ shares: 100000000n, sharesFormatted: 100, shareDecimals: 6, assets: 101.2, tokenDecimals: 6, assetAddress: "0x..." }返回 VaultPosition,其中包含原始 shares 余额,其 sharesFormatted 人类可读值,以及这些份额以基础单位表示的 assets 值。
preview(params)
使用保险库的实时净 APY,预测在给定时间内某个金额的收益。
const preview = await reader.earn.preview({ amount: 1000, horizonDays: 30 });{ projectedYield: 4.64, apy: 0.058, horizonDays: 30 }| 参数 | 类型 | 描述 |
|---|---|---|
amount | number | 要预测的本金,人类可读。 |
horizonDays | number | 预测周期,以天为单位。 |
返回 YieldPreview ({ projectedYield, apy, horizonDays })。
withdrawability(params)
检查某个金额是否可以从保险库的闲置流动性中即时提取。
const status = await reader.earn.withdrawability({ amount: 5000 });{ isInstant: true, availableLiquidity: 12500.5, tokenDecimals: 6 }| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
amount | number | 测试金额,人类可读。 | |
tokenDecimals | number? | on-chain | 基础资产小数位数。 |
返回 WithdrawStatus ({ isInstant, availableLiquidity, tokenDecimals })。当 isInstant 为 false 时,提现需要适配器解除分配,stable.earn.withdraw 会自动处理。
incentiveRewards.fetch()
读取配置地址的待处理 Merkl 奖励。与 stable.earn.incentiveRewards.fetch 对应的只读方法。
const { rewards } = await reader.earn.incentiveRewards.fetch();{ chainId: 988, rewards: [ { token: { symbol: "MORPHO", ... }, amount: 1.25, rawAmount: "1250000...", proofs: [...] } ] }返回 MerklRewardsResult。
枚举
Network
| 值 | 链 ID |
|---|---|
Network.Mainnet | 988 |
Network.Testnet | 2201 |
Chain
由 quoteBridge 和 bridge 使用。每个条目都有一个对应的 CHAIN_CONFIGS 条目。两个测试网条目是为了完整性而定义的,但 LI.FI 拒绝它们:桥接仅在主网链之间工作。
| 枚举 | 网络 | 链 ID |
|---|---|---|
Chain.Sepolia | 以太坊 Sepolia | 11155111 |
Chain.StableTestnet | Stable 测试网 | 2201 |
Chain.Stable | Stable 主网 | 988 |
Chain.Ethereum | 以太坊 | 1 |
Chain.Arbitrum | Arbitrum One | 42161 |
Chain.Ink | Ink | 57073 |
Chain.Bera | Berachain | 80094 |
Chain.MegaETH | MegaETH | 4326 |
Chain.Base | Base | 8453 |
Chain.BSC | BNB 智能链 | 56 |
Chain.HyperEVM | HyperEVM | 999 |
CHAIN_CONFIGS
Partial<Record<Chain, ChainConfig>> 以 Chain 枚举为键。每个条目都公开 id、rpc、usdt 和 decimals。当您需要支持链上的规范 USDT 地址而无需硬编码时使用它。
import { CHAIN_CONFIGS, Chain } from "@stablechain/sdk";
console.log(CHAIN_CONFIGS[Chain.Stable]);{ id: 988, rpc: "https://rpc.stable.xyz", usdt: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736", decimals: 6 }常量
规范主网地址,已导出,因此您无需硬编码它们。
import { STABLE_USDT_ADDRESS, STABLE_VAULT_ADDRESS } from "@stablechain/sdk";STABLE_USDT_ADDRESS 0x779ded0c9e1022225f8e0630b35a9b54be713736
STABLE_VAULT_ADDRESS 0xb7Df8db22A5DBBFA9ebeb94b3910aec6a4f05c08| 常量 | 描述 |
|---|---|
STABLE_USDT_ADDRESS | Stable 主网上的 USDT 代币地址。 |
STABLE_VAULT_ADDRESS | Stable 主网上的默认 Morpho V2 收益保险库。传递给 earn: { vault }。 |
错误
所有 SDK 错误都扩展了 StableError,而 StableError 又扩展了 viem 的 BaseError。错误带有结构化元数据,因此您可以根据 error.name 或 instanceof 进行分支。
| 类 | 抛出条件 | 有用字段 |
|---|---|---|
StableValidationError | 参数验证失败(地址错误、金额非有限、不支持的链)。 | field、value |
StableQuoteError | 向 LI.FI 发送报价请求失败。 | provider、httpStatus、providerCode、body |
StableTransactionError | 链上步骤失败:链切换、批准、发送或回滚。 | phase、txHash、chainId、revertReason |
StableNetworkError | 底层 HTTP/RPC 调用失败(例如 Morpho 或 Merkl API)。 | url |
StableBulkError | 运行 bulkDeposit 或 bulkWithdraw 时,如果 stopOnError: true,则在第一次失败时触发。 | results、succeeded、failed |
import { StableTransactionError } from "@stablechain/sdk";
try {
await stable.transfer({ from, to, amount: 1 });
} catch (err) {
if (err instanceof StableTransactionError && err.phase === "switch_chain") {
// user rejected the chain switch
}
throw err;
}StableTransactionError: transfer: wallet rejected or failed to switch to chain 988
Phase: switch_chain
Chain ID: 988下一步建议
- SDK 快速入门:安装 SDK 并在测试网上运行您的第一个转账。
- 与 viem 一起使用:在私钥、浏览器钱包和预构建签名器之间切换。
- 与 wagmi 一起使用:使用 hooks 将 SDK 连接到 React 应用程序。

