交换工具箱
目录
概览
交换Kit为建立可树摇动的互换操作提供了基础:
- 🔒 类型安全: 完整类型脚本支持, 严格类型检查
- ✅ 运行时间验证: 参数验证的综合Zod计划
- 📝 丰富的文档: 完成 JSDoc 并附有可运行实例
- 🎯 开发者经验: IntelliSense 支持和清除错误消息
- 🔧 弹性配置:定制收费政策和互换战略
开发者文档
安装
npm install @circle-fin/swap-kit
# or
yarn add @circle-fin/swap-kit
快速启动
交换 Kit 提供了两种使用模式—— 选择最适合您的项目:
- 链条选择受到互换支持的网络的限制. 支持的链条包括:
使用 CCTP v2 和至少一个支持的代号(USDC、USDT、EURC、EURC)的主网网络,
或登记在册的标志)。 目前的例子:Ethereum、Base、Polygon、Arbitrum、,
乐观主义,雪崩,莫纳德,索拉纳等. 使用
getSupportedChains()获取 完整的最新名单.
基于类的使用
import { SwapKit } from '@circle-fin/swap-kit'
import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
// Create a SwapKit instance
const kit = new SwapKit()
// Create an adapter
const adapter = createViemAdapterFromPrivateKey({
privateKey: process.env.PRIVATE_KEY,
})
// Define swap parameters
const params = {
from: { adapter, chain: 'Ethereum' },
tokenIn: 'USDC',
tokenOut: 'USDT',
amountIn: '100.50',
config: {
apiKey: process.env.CIRCLE_API_KEY,
slippageBps: 300, // 3% slippage tolerance
allowanceStrategy: 'permit',
},
}
// Get an estimate
const estimate = await kit.estimate(params)
console.log(
`Estimated output: ${estimate.estimatedOutput?.amount} ${estimate.estimatedOutput?.token}`,
)
// Execute the swap
const result = await kit.swap(params)
功能用法( Tree- Shakeable)
import { createSwapKitContext, estimate, swap } from '@circle-fin/swap-kit'
import { createViemAdapterFromPrivateKey } from '@circle-fin/adapter-viem-v2'
// Create a swap context
const context = createSwapKitContext()
// Create an adapter
const adapter = createViemAdapterFromPrivateKey({
privateKey: process.env.PRIVATE_KEY,
})
// Define swap parameters
const params = {
from: { adapter, chain: 'Ethereum' },
tokenIn: 'USDC',
tokenOut: 'USDT',
amountIn: '100.50',
config: {
apiKey: process.env.CIRCLE_API_KEY,
slippageBps: 300,
allowanceStrategy: 'permit',
},
}
// Get an estimate
const quoteResult = await estimate(context, params)
console.log(
`Estimated output: ${quoteResult.estimatedOutput?.amount} ${quoteResult.estimatedOutput?.token}`,
)
// Execute the swap
const result = await swap(context, params)
这两种模式都提供了相同的功能——基于类的方法提供了一个熟悉的基于类的界面,而功能方法则允许更好的树摇和更小的捆绑大小.
配置
自定义收费
交换Kit支持两种收取自定义开发商费的方法.
1. 按百分比计算的费用
直接按百分比计算的收费:
await kit.swap({
from: { adapter, chain: Ethereum },
tokenIn: 'USDC',
tokenOut: 'DAI',
amountIn: '100',
config: {
apiKey: process.env.CIRCLE_API_KEY,
customFee: {
percentageBps: 1000, // 10% fee (100 = 1%)
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
},
},
})
2. 基于回调收费
对于复杂的收费逻辑:
班级:
const kit = new SwapKit({
customFeePolicy: {
computeFee: async (ctx) => {
// Full context with adapter, chain, tokens, amounts
if (ctx.type === 'output') {
// Output fee scenario
// Access to minAmount and estimatedAmount
const user = await getUser(ctx.from.address)
if (user.isVIP) {
return (parseFloat(ctx.minAmount) * 0.05).toString()
}
return (parseFloat(ctx.estimatedAmount) * 0.1).toString()
}
// Input fee scenario
return (parseFloat(ctx.amountIn) * 0.05).toString()
},
resolveFeeRecipientAddress: (chain, ctx) => {
return chain.type === 'solana'
? 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'
: '0x1234567890123456789012345678901234567890'
},
},
})
// Or set/update it later
kit.setCustomFeePolicy({
computeFee: (ctx) => {
if (ctx.from.chain.name === 'Ethereum') {
return (parseFloat(ctx.amountIn) * 0.01).toString()
}
return (parseFloat(ctx.amountIn) * 0.005).toString()
},
resolveFeeRecipientAddress: (chain) => '0x...',
})
// Remove the fee policy when needed
kit.removeCustomFeePolicy()
职能:
import {
createSwapKitContext,
setCustomFeePolicy,
removeCustomFeePolicy,
} from '@circle-fin/swap-kit'
const context = createSwapKitContext({
customFeePolicy: {
computeFee: async (ctx) => {
if (ctx.type === 'output') {
return (parseFloat(ctx.estimatedAmount) * 0.1).toString()
}
return (parseFloat(ctx.amountIn) * 0.05).toString()
},
resolveFeeRecipientAddress: (chain, ctx) => {
return chain.type === 'solana' ? 'Sol...' : '0x...'
},
},
})
// Or set/update later
setCustomFeePolicy(context, {
computeFee: () => '0.05',
resolveFeeRecipientAddress: (chain) => '0x...',
})
// Remove when needed
removeCustomFeePolicy(context)
自定义提供者(类型)
import { createSwapKitContext } from '@circle-fin/swap-kit'
class ExperimentalSwapProvider {
readonly name = 'ExperimentalSwapProvider'
// implements SwappingProvider methods (supportsRoute, estimate, swap)
}
const extraProviders = [new ExperimentalSwapProvider()] as const
const context = createSwapKitContext({ providers: extraProviders })
// TypeScript knows the exact provider types:
type RegisteredProviders = typeof context.providers
// ^? readonly [...DefaultProviders, ExperimentalSwapProvider]
上下文将默认提供者与您提供的任何自定义提供者合并,同时保留其文字
类型。 一直这样 context.providers 严格打字,做好未来供应商整合的准备.
认证
通过圆形 API 键为 config.apiKey 认证服务支持
操作。 允许它使用无权限( 无键) 路径 .
config: {
apiKey: process.env.CIRCLE_API_KEY, // <ENV>_API_KEY:<keyId>:<keySecret>
}
API密钥是服务器唯一的秘密——由浏览器投掷提供. 别动 在您的服务器上, 并将准备的交易转发给客户端 .
从
kitKey数字 :config.kitKey以有利于config.apiKey它继续工作 和遗产KIT_KEY:<keyId>:<keySecret>值仍然被接受,所以您可以按照自己的速度移动。 当两者 字段已经设置,apiKey赢了.
交换配置选项
const params = {
from: { adapter, chain: Ethereum },
tokenIn: 'USDC',
tokenOut: 'USDT',
amountIn: '100',
config: {
// API key for authentication (optional — omit for permissionless mode)
apiKey: process.env.CIRCLE_API_KEY,
// Allowance strategy (default: 'permit')
allowanceStrategy: 'permit', // or 'approve'
// Maximum slippage in basis points (default: 300 = 3%)
slippageBps: 300,
// Minimum output amount (stop-limit)
stopLimit: '95000000', // 95 USDT in smallest units
// Custom fee for this specific swap (percentage approach)
customFee: {
percentageBps: 100, // 1% fee
recipientAddress: '0x742d35Cc6634C0532925a3b844Bc454e4438f44e',
},
// Batch approve + swap into one atomic call when the wallet supports it
// (default). Set false to send approval and swap as two transactions.
batchTransactions: true,
},
}
说明: 使用交易级别
percentageBps简单收费,或包级setCustomFeePolicy()用于复杂的逻辑。 它们是相互排斥的.
支持的托肯斯语Name
交换Kit支持收费募集的16个令牌. 此列表必须至少包含一个符号( 输入 OR 输出) .
稳定币 (6 小数):
USDC- 硬币EURC- 欧币USDT- 绳子美元PYUSD- 支付费用
稳定币 (18 小数):
DAI- 制造马来币USDE- 爱思娜美元
已包装的托肯斯 :
WBTC- 包装了比特币(8个小数)WETH- 包装了伊特鲁姆(18个小数)WSOL- 包装索拉纳(9个小数)WAVAX- 包裹了雪崩(18个小数)WPOL- 环形多边形(18个小数)
本地托肯语 :
NATIVE- 决定连锁原生煤气代币(Etheum上的ETH、索拉纳上的SOL等)
重要内容: 支持的列表必须至少包含一个符号( 输入 OR 输出) 。 非支持 → 非支持互换是不允许的.
实例:
// Swap between 6-decimal stablecoins
await kit.swap({
from: { adapter, chain: 'Ethereum' },
tokenIn: 'EURC',
tokenOut: 'USDC',
amountIn: '100.50',
config: { apiKey: process.env.CIRCLE_API_KEY },
})
// Swap DAI (18 decimals) to USDC
await kit.swap({
from: { adapter, chain: 'Ethereum' },
tokenIn: 'DAI',
tokenOut: 'USDC',
amountIn: '500.0', // Automatically handles 18-decimal precision
config: { apiKey: process.env.CIRCLE_API_KEY },
})
// Swap native gas token to stablecoin (generic)
await kit.swap({
from: { adapter, chain: 'Ethereum' },
tokenIn: 'NATIVE', // ETH on Ethereum, POL on Polygon, SOL on Solana, etc.
tokenOut: 'USDC',
amountIn: '1.5',
config: { apiKey: process.env.CIRCLE_API_KEY },
})
// Swap wrapped ETH to stablecoin on Polygon
await kit.swap({
from: { adapter, chain: 'Polygon' },
tokenIn: 'WETH', // Wrapped ETH on Polygon
tokenOut: 'USDC',
amountIn: '0.5',
config: { apiKey: process.env.CIRCLE_API_KEY },
})
说明: 使用 NATIVE 连锁店的内燃气代号 链式特定符号 ETH, (中文(简体) ), POL 不支持为互换令牌的别名——使用 NATIVE 或合同地址.
类型定义
交换
interface SwapParams {
from: AdapterContext // Source adapter and chain
tokenIn: SupportedToken // Input token
tokenOut: SupportedToken // Output token
amountIn: string // Decimal string (e.g., '10.5')
config?: SwapConfig // Optional configuration
}
// SupportedToken can be:
// - Stablecoin aliases (6 decimals): 'USDC' | 'EURC' | 'USDT' | 'PYUSD'
// - Stablecoin aliases (18 decimals): 'DAI' | 'USDE'
// - Wrapped tokens: 'WBTC' (8 dec) | 'WETH' | 'WSOL' (9 dec) | 'WAVAX' | 'WPOL' (18 dec)
// - Native token: 'NATIVE' (chain's native gas token)
type SupportedToken =
| 'USDC'
| 'EURC'
| 'USDT'
| 'USDE'
| 'DAI'
| 'PYUSD'
| 'WBTC'
| 'WETH'
| 'WSOL'
| 'WAVAX'
| 'WPOL'
| 'NATIVE'
交换
估计结果包括将估计数与投入联系起来的投入上下文字段:
interface SwapEstimate {
// Input context (populated from your params)
tokenIn: SupportedToken // e.g., 'NATIVE'
tokenOut: SupportedToken // e.g., 'USDC'
amountIn: string // e.g., '0.00001'
chain: string // e.g., 'Ethereum'
fromAddress: string // e.g., '0x2971...5EE9f'
toAddress: string // e.g., '0x2971...5EE9f'
// Estimate details
transaction: object // Raw transaction to sign and submit
stopLimit: string // Minimum output in base units
estimatedOutput?: string // Human-readable expected output
fees?: ServiceSwapFee[] // Fee breakdown
}
交换结果
互换结果使用简化链字段:
interface SwapResult {
tokenIn: SupportedToken
tokenOut: SupportedToken
chain: string // e.g., 'Ethereum'
amountIn: string // Human-readable amount
fromAddress: string
toAddress: string
txHash: string
explorerUrl?: string
fees?: ServiceSwapFee[]
config?: SwapResultConfig
}
将链名解为链定义
两者 SwapEstimate 财务报告和审定财务报表 SwapResult 返回简化 chain 字符串( 例如, ), 'Ethereum'(中文(简体) )
如果需要全链定义,请使用 getChainByEnum 工具栏 :
import { getChainByEnum } from '@circle-fin/swap-kit'
// After getting a swap result or estimate
const result = await kit.swap(params)
// Resolve the chain name back to full ChainDefinition
const chainDef = getChainByEnum(result.chain)
console.log(chainDef.chainId) // 1 (for Ethereum)
console.log(chainDef.rpcEndpoints) // ['https://...']
自定义文件政策
interface CustomFeePolicy {
computeFee: (params: SwapParams) => Promise<string> | string
resolveFeeRecipientAddress: (
chain: ChainDefinition,
params: SwapParams,
) => Promise<string> | string
}
验证
交换 Kit 提供了全面的运行时间验证 :
import { assertSwapParams, swapParamsSchema } from '@circle-fin/swap-kit'
try {
assertSwapParams(params, swapParamsSchema)
// Parameters are valid
} catch (error) {
console.error('Validation failed:', error.message)
}
用法模式:类与功能
交换Kit支持基于类和功能的编程风格. 根据您的偏好选择 :
使用基于类( SwapKit) 时 :
- 你喜欢传统的班级模式
- 您的代码库已经使用基于类的库
- 您想要一个类似于其他 SDK 的熟悉的 API
- {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你不需要强势的震动树的优化
使用功能( 创建SwapKitContext + 操作) 当 :
- 您更喜欢功能编程模式
- ~ 你需要最大的树摇晃 对于更小的捆绑
- 您只想要导入特定操作
- 你正在打造一个 性能关键应用程序
两种办法:
- 提供相同的功能
- 使用相同的基本操作
- QQ 提供全部类型脚本支持
- * 包括全面验证
示例:选择一种办法
// Class-based: Great for general use
import { SwapKit } from '@circle-fin/swap-kit'
const kit = new SwapKit()
await kit.swap(params)
// Functional: Great for tree-shaking
import { createSwapKitContext, swap } from '@circle-fin/swap-kit'
const context = createSwapKitContext()
await swap(context, params)
许可证
阿帕奇 - 2.0
支助
关于问题,请访问 GitHub 仓库。 。 。 .