SDK 桥接
测试覆盖率
| 发言 | 分支 | 职能 | 行数 |
|---|---|---|---|
这个软件包为CoW协议SDK提供了连接功能,可以进行跨链令牌传输和交互. 它与各种桥梁供应商进行整合,以利无缝地通过所支持的区块链网络进行资产流动.
安装
npm install @cowprotocol/sdk-bridging
or
pnpm add @cowprotocol/sdk-bridging
or
yarn add @cowprotocol/sdk-bridging
使用量
import {
SupportedChainId,
BridgingSdk,
QuoteBridgeRequest,
OrderKind,
assertIsBridgeQuoteAndPost,
} from '@cowprotocol/sdk-bridging'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
import { JsonRpcProvider, Wallet } from 'ethers'
// Configure the adapter
const provider = new JsonRpcProvider('YOUR_RPC_URL')
const wallet = new Wallet('YOUR_PRIVATE_KEY', provider)
const adapter = new EthersV6Adapter({ provider, signer: wallet })
// Initialize bridging SDK
const bridging = new BridgingSdk(adapter, options)
const parameters: QuoteBridgeRequest = {
// Cross-chain orders are always SELL orders (BUY not supported yet)
kind: OrderKind.SELL,
// Sell token (and source chain)
sellTokenChainId: SupportedChainId.ARBITRUM_ONE,
sellTokenAddress: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
sellTokenDecimals: 18,
// Buy token (and target chain)
buyTokenChainId: SupportedChainId.BASE,
buyTokenAddress: '0x4200000000000000000000000000000000000006',
buyTokenDecimals: 18,
// Amount to sell
amount: '120000000000000000',
signer: adapter.signer,
// Optional parameters
appCode: 'YOUR_APP_CODE',
}
// Get a quote (and the post callback) for a cross-chain swap
const quoteResult = await sdk.getQuote(parameters)
// Assert that the quote result is of type BridgeQuoteAndPost
// (type for cross-chain quotes, as opposed to QuoteAndPost for single-chain quotes).
// The assertion makes typescript happy.
assertIsBridgeQuoteAndPost(quoteResult)
const { swap, bridge, postSwapOrderFromQuote } = quoteResult
// Display all data related to the swap (costs, amounts, appData including the bridging hook, etc.) 🐮
console.log('Swap info', swap)
// Display all data related to the bridge (costs, amounts, provider info, hook, and the bridging quote) ✉️
console.log('Bridge info', bridge)
// Get the buy amount after slippage in the target chain
const { buyAmount } = bridge.amountsAndCosts.afterSlippage
if (confirm(`You will get at least: ${buyAmount}, ok?`)) {
const orderId = await postSwapOrderFromQuote()
console.log('Order created, id: ', orderId)
}
多版本引用比较
这个 getMultiQuotes() 方法允许您同时从多个桥接提供者获得报价,同时支持每个提供者响应的渐进结果.
基本的多引号使用
import { MultiQuoteRequest } from '@cowprotocol/sdk-bridging'
const multiQuoteRequest: MultiQuoteRequest = {
quoteBridgeRequest: parameters, // Same parameters as above
providerDappIds: ['provider1', 'provider2'], // Optional: specify which providers to query
advancedSettings: {
slippageBps: 100, // 1% slippage tolerance
},
options: {
totalTimeout: 15000, // 15 seconds total timeout
providerTimeout: 8000, // 8 seconds per provider timeout
}
}
// Get quotes from all providers
const results = await bridgingSdk.getMultiQuotes(multiQuoteRequest)
results.forEach((result) => {
if (result.quote) {
console.log(`Quote from ${result.providerDappId}:`, result.quote)
} else {
console.log(`Error from ${result.providerDappId}:`, result.error?.message)
}
})
渐进式引用结果
为了获得更好的用户体验,您可以随着每个提供者的响应而逐步获得报价:
const progressiveResults: MultiQuoteResult[] = []
const multiQuoteRequest: MultiQuoteRequest = {
quoteBridgeRequest: parameters,
options: {
// Receive quotes as they arrive
onQuoteResult: (result) => {
progressiveResults.push(result)
if (result.quote) {
console.log(`✅ Quote received from ${result.providerDappId}`)
// Update UI immediately with the new quote
displayQuoteInUI(result)
} else {
console.log(`❌ Error from ${result.providerDappId}: ${result.error?.message}`)
}
},
totalTimeout: 20000, // 20 seconds total timeout
providerTimeout: 5000 // 5 seconds per provider timeout
}
}
// This will return all results once completed (or timed out)
const finalResults = await bridgingSdk.getMultiQuotes(multiQuoteRequest)
console.log(`Received ${finalResults.filter(r => r.quote).length} successful quotes out of ${finalResults.length} providers`)
高级多引文示例
// Example with React state management
const [quotes, setQuotes] = useState<MultiQuoteResult[]>([])
const [isLoading, setIsLoading] = useState(false)
const fetchQuotes = async () => {
setIsLoading(true)
setQuotes([])
try {
const results = await bridgingSdk.getMultiQuotes({
quoteBridgeRequest: parameters,
options: {
onQuoteResult: (result) => {
// Add quote to state as it arrives
setQuotes(prev => [...prev, result])
if (result.quote) {
// Optional: Auto-select best quote
if (isBestQuote(result)) {
selectQuote(result)
}
} else {
// Handle errors
console.error(`Provider ${result.providerDappId} failed:`, result.error?.message)
// Update UI to show provider is unavailable
setProviderStatus(prev => ({
...prev,
[result.providerDappId]: 'error'
}))
}
},
totalTimeout: 30000, // 30 seconds total timeout
providerTimeout: 10000 // 10 seconds per provider timeout
}
})
console.log('All quotes completed:', results)
} catch (error) {
console.error('Multi-quote failed:', error)
} finally {
setIsLoading(false)
}
}
// Helper function to determine best quote
const isBestQuote = (result: MultiQuoteResult): boolean => {
if (!result.quote) return false
const currentBest = quotes.find(q => q.quote)
if (!currentBest?.quote) return true
// Compare buy amounts after slippage
return result.quote.bridge.amountsAndCosts.afterSlippage.buyAmount >
currentBest.quote.bridge.amountsAndCosts.afterSlippage.buyAmount
}
超时配置
这个 getMultiQuotes() 方法支持对精细控制进行两种超时:
const results = await bridgingSdk.getMultiQuotes({
quoteBridgeRequest: parameters,
options: {
// Global timeout: Maximum time to wait for all providers to complete
totalTimeout: 30000, // 30 seconds (default)
// Individual provider timeout: Maximum time each provider has to respond
providerTimeout: 15000, // 15 seconds (default)
onQuoteResult: (result) => {
// Handle progressive results
console.log(`Received result from ${result.providerDappId}`);
}
}
});
超时工作方式 :
providerTimeout:每个提供者有这样多的时间来完成他们的引用请求. 如果超过, 提供者返回超时出错 .totalTimeout: 等待所有提供者的总时间。 在此之后,任何剩余的供应商都会被标记为超时.- 在全球超时后完成的供应商仍将包括在最后结果中.
最佳引用选择
这个 getBestQuote() 方法提供了一个优化的方法,只能从多个提供者那里得到最好的引文,随着找到更好的引文,可以逐步更新. 这对于只需要单一最佳结果的应用来说是完美的.
基本最佳引文使用法
import { MultiQuoteRequest } from '@cowprotocol/sdk-bridging'
// Get the best quote from all available providers
const bestQuote = await bridgingSdk.getBestQuote({
quoteBridgeRequest: parameters, // Same parameters as above
providerDappIds: ['provider1', 'provider2'], // Optional: specify which providers to query
advancedSettings: {
slippageBps: 100, // 1% slippage tolerance
},
options: {
totalTimeout: 15000, // 15 seconds total timeout
providerTimeout: 8000, // 8 seconds per provider timeout
}
})
if (bestQuote?.quote) {
console.log(`Best quote from ${bestQuote.providerDappId}:`, bestQuote.quote)
const { buyAmount } = bestQuote.quote.bridge.amountsAndCosts.afterSlippage
console.log(`You will receive: ${buyAmount} tokens`)
} else if (bestQuote?.error) {
console.log('All providers failed, first error:', bestQuote.error.message)
} else {
console.log('No quotes available')
}
进步最佳引文更新
对于实时更新,每次找到更好的引文时都可以收到通知:
let currentBest: MultiQuoteResult | null = null
const bestQuote = await bridgingSdk.getBestQuote({
quoteBridgeRequest: parameters,
options: {
// Called whenever a better quote is found
onQuoteResult: (result) => {
currentBest = result
console.log(`🚀 New best quote from ${result.providerDappId}!`)
if (result.quote) {
const buyAmount = result.quote.bridge.amountsAndCosts.afterSlippage.buyAmount
console.log(`Better quote found: ${buyAmount} tokens`)
// Update UI immediately with the new best quote
updateBestQuoteInUI(result)
}
},
totalTimeout: 20000, // 20 seconds total timeout
providerTimeout: 5000 // 5 seconds per provider timeout
}
})
console.log('Final best quote:', bestQuote)
使用最佳引用处理错误
当所有供应商失败时, getBestQuote() 返回第一个提供者的错误 :
const bestQuote = await bridgingSdk.getBestQuote({
quoteBridgeRequest: parameters,
options: {
onQuoteResult: (result) => {
// Only called for successful quotes that are better than current best
console.log(`✅ Better quote from ${result.providerDappId}`)
}
}
})
if (bestQuote?.quote) {
// Success: we have the best available quote
console.log('Best quote found:', bestQuote.quote)
} else if (bestQuote?.error) {
// All providers failed, this is the first error encountered
console.error('All providers failed:', bestQuote.error.message)
console.log('Failed provider:', bestQuote.providerDappId)
} else {
// This should never happen, but good to handle
console.log('No quote or error returned')
}
比较: 获得最佳引文 vs 获得多引文
| 特性 | getBestQuote() | getMultiQuotes() |
|---|---|---|
| 回返 | 单一最佳结果 | 所有结果的矩阵 |
| 递进回调 | 只为更好的引用 | 对所有结果( 成功和错误) |
| 处理错误 | 如果全部失败, 则返回第一个错误 | 返回数组中的所有错误 |
| 业绩 | 仅优化最佳结果 | 返回完整的数据集 |
| 使用大小写 | 当你只需要最好的引用 | 当你需要比较所有选项时 |
选择 getBestQuote() 当:
- 你只需要一个最好的报价
- 您需要实时更新, 因为找到更好的报价
- 您想要最小化回调间接费用( 只要求改进)
选择 getMultiQuotes() 当:
- 您需要向用户显示所有可用的选项
- 您想要分析所有提供者的响应
- 您需要显示特定提供者的错误或状态
供应商管理
BridgeingSdk提供了管理哪些桥提供商被积极用于引用和操作的方法.
获取可用的提供者
使用 getAvailableProviders() 以获取当前活动提供者列表:
// Get all active providers
const providers = bridgingSdk.getAvailableProviders()
providers.forEach((provider) => {
console.log(`Provider: ${provider.info.name}`)
console.log(`Dapp ID: ${provider.info.dappId}`)
console.log(`Networks: ${provider.info.supportedChains.join(', ')}`)
})
过滤活动供应商
使用 setAvailableProviders() 以动态过滤哪些提供者应用于桥梁操作:
// Initially, all configured providers are available
const allProviders = bridgingSdk.getAvailableProviders()
console.log(`Total providers: ${allProviders.length}`)
// Filter to use only specific providers
bridgingSdk.setAvailableProviders(['across', 'hop-protocol'])
// Now only the specified providers will be used
const filteredProviders = bridgingSdk.getAvailableProviders()
console.log(`Active providers: ${filteredProviders.length}`)
// Reset to use all providers again
bridgingSdk.setAvailableProviders([])
const resetProviders = bridgingSdk.getAvailableProviders()
console.log(`Reset to all providers: ${resetProviders.length}`)
动态提供者选择示例
// Example: Let users select their preferred bridge providers
const [selectedProviders, setSelectedProviders] = useState<string[]>([])
// Function to update active providers based on user selection
const updateActiveProviders = (providerIds: string[]) => {
bridgingSdk.setAvailableProviders(providerIds)
setSelectedProviders(providerIds)
console.log(`Updated to use ${providerIds.length} provider(s)`)
}
// Get quotes only from selected providers
const getQuotesFromSelectedProviders = async () => {
// The SDK will automatically use only the providers set via setAvailableProviders
const quote = await bridgingSdk.getQuote(parameters)
// Or for multi-provider quotes
const multiQuotes = await bridgingSdk.getMultiQuotes({
quoteBridgeRequest: parameters
// No need to specify providerDappIds, setAvailableProviders already filtered them
})
return quote
}
支持的桥梁提供者
- 正在整合其他桥梁供应商
- 随着发展的进展,将提供更多细节