贸易SDK
测试覆盖率
| 发言 | 分支 | 职能 | 行数 |
|---|---|---|---|
CoW协议是基于意向,分散的交易协议,允许用户交易ERC-20令牌. 这种SDK通过处理订单参数,计算金额,以及签署订单,使得与COW协议的交互更加容易.
基本贸易流量
- 获得一个交易报价(价格)
- 签署命令
- 将命令张贴到命令簿
《合作议定书》提供了非常灵活和强大的贸易能力。 然而,这种灵活性带来代价:议定书的复杂性。 这个SDK可以简化与CoW协议的互动. 它会把所有必要的参数都放在您的顺序, 计算适当的数量, 并签名的顺序.
为什么要用这个SDK?
- App-数据 - 命令元数据处理
- 签署命令 - EIP-712签名管理
- 网络费用 - 自动收费和延迟计算
- 顺序参数 - 有效性、部分填充等.
- 引用 API 设置 - 价格质量、签字计划等.
- 顺序类型 - 市场、限制、链上贸易等.
见 实例 用于使用.
安装
npm install @cowprotocol/sdk-trading
or
pnpm add @cowprotocol/sdk-trading
or
yarn add @cowprotocol/sdk-trading
TradingSdk 函数
主要职能:
postSwapOrder- 获取一个引文并创建一个互换订单.postLimitOrder- 创建一个限制顺序.getQuote- 拿个报价来换订单.getQuoteOnly- 找到一个只有所有者地址的引文,不需要签名者.getOrderToSubmit- 建立以外部签名提交的命令.postSignedOrder- 提交外部签署的命令(见 无符号流动) (中文(简体) ).
命令管理:
getOrder- 从UID获取订单细节.offChainCancelOrder- 取消下链订单(软取消、免费和快速).onChainCancelOrder- 取消链上订单(硬取消,需要气体).
目 录 :
getCowProtocolAllowance- 检查《煤矿议定书》的现有代号.approveCowProtocol- 批准CoW协议,以支付代币.
特殊情况:
setTraderParams- 以防你用不同的链子工作 需要在运行时在链子之间切换.postSellNativeCurrencyOrder- 出售块链原生标志物(例如Ethereum上的ETH).getPreSignCallData- 为外部钱包、多西格或保管堆栈建立未签名的预标记调用数据.getPreSignTransaction- 建立以签字人为基础的气体估计数的预签交易.
设置
你需要的就是: 爱丽丝
chainId- 支持链式ID(参见列表) (中文(简体) ).appCode- 跟踪命令的专用应用程序标识符.signer- 私人钥匙、醚签字器或Eip1193提供者( 可选的 - 如果不提供, 将使用全局适配器的签名) .
使用量
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/sdk-trading'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
// There are EthersV5Adapter and EthersV6Adapter as well
// @cowprotocol/sdk-ethers-v5-adapter, @cowprotocol/sdk-ethers-v6-adapter
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
// You also can set `walletClient` instead of `signer` using `useWalletClient` from wagmi
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Initialize the SDK
const sdk = new TradingSdk(
{
appCode: 'YOUR_APP_CODE',
},
{
chainId: SupportedChainId.SEPOLIA,
},
adapter, // Pass the adapter
)
// Define trade parameters
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
// Post the order
const orderId = await sdk.postSwapOrder(parameters)
console.log('Order created, id: ', orderId)
选项
关于交易步骤的详情, 您可以启用 SDK 记录 :
import { SupportedChainId, TradingSdk, TradingSdkOptions } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
// You also can set `walletClient` instead of `signer` using `useWalletClient` from wagmi
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
const traderParams = {
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
signer: '<privateKeyOrEthersSigner>', // signer is optional - will use global adapter's signer if not provided
}
const sdkOptions: TradingSdkOptions = {
enableLogging: true, // enables detailed logging of trading steps
disableUtm: false, // set to true to disable UTM tracking completely
}
const sdk = new TradingSdk(traderParams, sdkOptions, adapter)
获取引用
如果你想要引出一个引号,然后创建一个命令,你可以使用 getQuote 函数.
所需参数与 postSwapOrder 函数.
函数返回 quoteResults 具有下列属性的对象:
tradeParameters- 交易类型、资产、金额和其他可选参数amountsAndCosts- 订单销售/购买金额,包括网络费用、收费和延误orderToSign- 要签名的顺序参数( 见 命令签名(中文(简体) )quoteResponse- DTO从 引用 APIappDataInfo- 说吧 命令的元数据orderTypedData- EIP-712型签字数据
此函数返回的另一个参数是 postSwapOrderFromQuote。 。 。 .
它可用于从收到的引文中创建命令.
示例
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
// You also can set `walletClient` instead of `signer` using `useWalletClient` from wagmi
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote(parameters)
const buyAmount = quoteResults.amountsAndCosts.afterSlippage.buyAmount
if (confirm(`You will get at least: ${buyAmount}, ok?`)) {
const orderId = await postSwapOrderFromQuote()
console.log('Order created, id: ', orderId)
}
移动命令后
此函数获取一个互换顺序的引号, 只需创建顺序 .
所需参数为:
kind- 订单种类(销售/购买)sellToken- 销售代号地址sellTokenDecimals- 销售代号小数buyToken- 买证地址buyTokenDecimals- 购买代号小数amount- 在原子中出售/购买的数量
当销售令牌是块链原生令牌(ETH for Ethereum)时,订单就会被设定为链上交易. 见
postSellNativeCurrencyOrder详细情况如下.
示例
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
// You also can set `walletClient` instead of `signer` using `useWalletClient` from wagmi
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const { orderId } = await sdk.postSwapOrder(parameters)
console.log('Order created, id: ', orderId)
后命令
此功能与 postSwapOrder 您需要在此指定销售和购买金额 .
您需要提供以下参数:
kind- 订单种类(销售/购买)sellToken- 销售代号地址sellTokenDecimals- 销售代号小数buyToken- 买证地址buyTokenDecimals- 购买代号小数sellAmount- 用原子出售的数量buyAmount- 用原子购买的金额
还有可选参数:
quoteId- 从引用的 API 中引用的 id (参见获取引用函数)validTo- 命令到期时间(秒)
import { SupportedChainId, OrderKind, LimitTradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
// You also can set `walletClient` instead of `signer` using `useWalletClient` from wagmi
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const limitOrderParameters: LimitTradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
sellAmount: '120000000000000000',
buyAmount: '66600000000000000000',
}
const { orderId } = await sdk.postLimitOrder(limitOrderParameters)
console.log('Order created, id: ', orderId)
售后紧急命令
COW协议支持链上贸易来销售块链原生代币(ETH for Ethereum).
在这种情况下,订单是作为链上交易创建的.
你用的时候不用考虑这个案子 postSwapOrder 函数,将自动处理.
但是,如果你需要更灵活的方式 创建一个订单 出售本地的代币,你可以使用 postSellNativeCurrencyOrder 函数.
我们认为,如果售出物牌的地址是"0xeeeeeeee",则该订单是本地代币销售订单.
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const { orderId } = await sdk.postSellNativeCurrencyOrder(parameters)
console.log('Order created, id: ', orderId)
为智能合同钱包取出报价
想要使用智能合同钱包签署订单,请指定 signingScheme 参数,以便从气体效率的角度获得更准确的引用.
通过使用不同的签名方案支持智能合同钱包 - SigningScheme.PRESIGN。 。 。 .
示例
import {
SupportedChainId,
OrderKind,
TradeParameters,
SwapAdvancedSettings,
SigningScheme,
TradingSdk,
} from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const advancedParameters: SwapAdvancedSettings = {
quoteRequest: {
// Specify the signing scheme
signingScheme: SigningScheme.PRESIGN,
},
}
const { quoteResults } = await sdk.getQuote(parameters)
console.log('Quote:', quoteResults)
用智能合同钱包创建订单
如果您想要使用智能合同钱包创建订单, 请指定 PRESIGN 发布命令时签名方案 。 命令创建后使用 getPreSignCallData 通过您的钱包堆栈提交预签交易,或 getPreSignTransaction 当您有 SDK 标志并需要包含一个气体估计.
交换顺序示例
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const smartContractWalletAddress = '0x<smartContractWalletAddress>'
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
owner: smartContractWalletAddress,
}
const advancedParameters: SwapAdvancedSettings = {
quoteRequest: {
// Specify the signing scheme
signingScheme: SigningScheme.PRESIGN,
},
}
const { orderId } = await sdk.postSwapOrder(parameters, advancedParameters)
const preSignTransaction = await sdk.getPreSignTransaction({ orderUid: orderId })
console.log('Order created with "pre-sign" state, id: ', orderId)
console.log('Execute the transaction to sign the order', preSignTransaction)
限制顺序示例
import {
SupportedChainId,
OrderKind,
LimitTradeParameters,
LimitOrderAdvancedSettings,
SigningScheme,
TradingSdk,
} from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const smartContractWalletAddress = '0x<smartContractWalletAddress>'
const limitOrderParameters: LimitTradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
sellAmount: '120000000000000000',
buyAmount: '66600000000000000000',
owner: smartContractWalletAddress, // See note bellow why you need to specify the parameter
}
const advancedParameters: LimitOrderAdvancedSettings = {
additionalParams: {
signingScheme: SigningScheme.PRESIGN,
},
}
const { orderId } = await sdk.postLimitOrder(limitOrderParameters, advancedParameters)
const preSignTransaction = await sdk.getPreSignTransaction({ orderUid: orderId })
console.log('Order created with "pre-sign" state, id: ', orderId)
console.log('Execute the transaction to sign the order', preSignTransaction)
说明: 一定要说明
owner参数,如果您使用智能合同钱包创建订单,并且与签名符(例如Safe)不同. 将使用 CoW 协议owner为了检查订单所有人余额、津贴和其他物品.
构建没有签名的预签名调用数据
如果交易将被 Safe, multisig, 或守护堆栈提议或提交, 请从已经配置的 SDK 请求原始交易数据 :
const preSignCallData = sdk.getPreSignCallData({ orderUid: orderId })
// Returns { to, data, value }; pass it to your own transaction stack.
await yourMultisigOrCustodyStack.submitTransaction(preSignCallData)
getPreSignCallData 仍需要配置适配器,因为ABI编码是适配器特有的. 适配器可以是无签名器;基于提供者的适配器,例如 ViemAdapter 初始化时仍然需要一个提供者或RPC URL,但是这个帮助者不会访问签名器,呼叫提供者,或者估计气体. 外部堆栈应在自己的执行上下文中估算出气体. 最终交易必须由UID中编码的订单所有人执行——对于安全拥有的订单,安全拥有者本身必须称为和解合同.
外部签名命令( 无签名流)
如果签名密钥不能交给SDK——冷钱包(Tangem),MPC/保管服务(Fireblocks),或者任何在单独环境下签名的设置,那么您可以仅与该用户完成互换 owner 地址和外部制作的签名:
getQuoteOnly({ owner, ... })- 给所有者账户取个报价,不需要签名getOrderToSubmit({ quoteResults })——建设订单正文,除签名外,其他一切- 签名
quoteResults.orderTypedData在自己的环境中(eth_signTypedData_v4(中文(简体) ) postSignedOrder({ orderToSubmit, signature })——上传应用数据并提交订单
示例
import { setGlobalAdapter, SupportedChainId, OrderKind, TradingSdk } from '@cowprotocol/cow-sdk'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
import { JsonRpcProvider } from 'ethers'
// The adapter carries NO signer — it is only used for hashing utilities when
// building app-data. The private key never enters the SDK.
setGlobalAdapter(new EthersV6Adapter({ provider: new JsonRpcProvider('YOUR_RPC_URL') }))
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
})
const quoteResults = await sdk.getQuoteOnly({
owner: '0x<ownerAddress>', // the account that will sign the order
kind: OrderKind.SELL,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
})
// Everything sendOrder needs, except the signature
const orderToSubmit = sdk.getOrderToSubmit({ quoteResults })
// Produce the signature in your own environment, e.g. with a raw JSON-RPC call:
// eth_signTypedData_v4(owner, JSON.stringify(quoteResults.orderTypedData))
// or with a signing library (see the note about EIP712Domain below):
// const { EIP712Domain: _, ...types } = quoteResults.orderTypedData.types
// const signature = await coldWallet.signTypedData(quoteResults.orderTypedData.domain, types, quoteResults.orderTypedData.message)
const signature = await signInYourEnvironment(quoteResults.orderTypedData)
const { orderId } = await sdk.postSignedOrder({ orderToSubmit, signature })
console.log('Order created, id: ', orderId)
可运行版本( 带有本地钱包播放冷钱包) 已进入 examples/nodejs/ethers6/src/signerless.ts 财务报告和审定财务报表 examples/nodejs/viem/src/signerless.ts。 。 。 .
说明: 签名必须来自
owner账号——订单书收回了签名人,并拒绝不符合的订单.owner还需要售出平衡 和Vault Relayer的批准.
一些与这种流动具体相关的事情:
- 签名
orderToSign逐字记录:网络成本和故障已经叠入feeAmount实值0,所以键入的数据数与标题引号不符。 任何改变都不能不重新引用. - 这里不支持原产地的销售——它们需要连锁交易(见
postSellNativeCurrencyOrder) (中文(简体) ). orderTypedData.types包含EIP712Domain所以它的工作是原始的eth_signTypedData_v4. 乙醚如果存在会抛出——从types首先(见示例);viem接受两种形式.getOrderToSubmit默认为EIP712签名计划( 签名)orderTypedData通过eth_signTypedData_v4) (中文(简体) ). 与eth_sign编号 :personal_sign相反,计算该命令的EIP-712摘要personal_sign那个,然后通过sdk.getOrderToSubmit({ quoteResults, signingScheme: SigningScheme.ETHSIGN })- 计划必须与你签字的方式相符.PRESIGN(链上流)不是这种流的一部分,和EIP1271计划为以后的里程碑提供支助.
可选参数
两者 postSwapOrder 财务报告和审定财务报表 postLimitOrder 函数有可选参数.
见 TradeOptionalParameters 键入更多细节.
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
env | Env | prod | 拟使用的环境prod 或者说 staging) (中文(简体) ). |
partiallyFillable | boolean | false | 说明该命令是填入还是可部分填入. |
slippageBps | number | 第50条 | 对获得限价的命令适用了滑行容能. 以基准点表示。 一个基点相当于0.01%(1%/100%). |
receiver | string | 命令创建者 | 接收订单的地址. |
validFor | number | 30分钟 | 订单到期时间数秒. |
partnerFee | PartnerFee | - 说吧 | 协议的合作伙伴可以指定其订单收费,包括基点(BPS)中的收费和收费接收地址. 更多信息 |
示例
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
// Optional parameters
slippageBps: 200, // 2%
validFor: 1200, // 20 mins
receiver: '0xdef1ca1fb7f1232777520aa7f396b4e015f497ab', // Just a random address, don't use it!
}
const { orderId } = await sdk.postSwapOrder(parameters)
console.log('Order created, id: ', orderId)
高级互换订单创建
默认情况下,SDK只需要基本参数就可以创建命令. 然而,可以提供附加参数来自定义命令创建.
交换
-
quoteRequest- 引文请求对象。 用于从引文API中取出引文(更多信息(中文(简体) )priceQuality默认为verified:后端会模拟引出并更喜欢被验证的取出,而不是被验证较高的取出. 过optimal在不模拟的情况下获得最高报价(较快,但订单风险较高,无法填充). -
appData- 命令的元数据(更多信息(中文(简体) )
示例
import {
SupportedChainId,
OrderKind,
TradeParameters,
TradingSdk,
SwapAdvancedSettings,
PriceQuality,
} from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
// Proper adapter initialization (see setup example above)
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const advancedSettings: SwapAdvancedSettings = {
quoteRequest: {
priceQuality: PriceQuality.FAST,
validFor: 120,
},
appData: {
hooks: {
version: 1,
pre: [
{
target: '0xdef1ca1fb7fbcdc777520aa7f396b4e015f497ab',
callData: '0x70a08231000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045',
gasLimit: 21000,
},
],
},
},
}
const { orderId } = await sdk.postSwapOrder(parameters, advancedSettings)
console.log('Order created, id: ', orderId)
限制顺序
与互换订单相同,但没有 quoteRequest 参数.
订单管理
SDK提供了管理现有订单的方法,包括检索订单细节和取消订单等.
获取命令
获取其 UID 命令的细节 .
参数:
orderUid- 命令的独特标识chainId- (可选)链式ID,如果不提供则使用交易员参数
回返情况: Promise<EnrichedOrder> - 完整订购细节,包括状况、数额和元数据
示例
import { TradingSdk } from '@cowprotocol/sdk-trading'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const orderUid = '0xd64389693b6cf89ad6c140a113b10df08073e5ef3063d05a02f3f42e1a42f0ad...'
const order = await sdk.getOrder({ orderUid })
console.log('Order status:', order.status)
console.log('Sell amount:', order.sellAmount)
console.log('Buy amount:', order.buyAmount)
关闭ChanCancel命令
通过向订单簿 API 发送签名的取消请求来取消一个脱链订单. 这是一种"软取消",速度快而不需要汽油,但需要订购书支持.
您总是可以使用 交换, (中文(简体) ), 详情请参见教程。 。 。 .
参数:
orderUid- 取消命令的唯一标识符chainId- (可选)链式ID,如果不提供则使用交易员参数signer- (可选的)自定义签名器,如果不提供则使用交易人参数签名器
回返情况: Promise<boolean> - 如果取消成功,则属实
示例
import { TradingSdk } from '@cowprotocol/sdk-trading'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const orderUid = '0xd64389693b6cf89ad6c140a113b10df08073e5ef3063d05a02f3f42e1a42f0ad...'
const success = await sdk.offChainCancelOrder({ orderUid })
if (success) {
console.log('Order cancelled successfully (off-chain)')
}
钱币中止命令
通过发送交易取消链上的命令使其无效。 这是"硬取消",要求加气但保证取消. 根据订单类型自动检测是使用结算合同还是EthFlow合同.
参数:
orderUid- 取消命令的唯一标识符chainId- (可选)链式ID,如果不提供则使用交易员参数signer- (可选的)自定义签名器,如果不提供则使用交易人参数签名器
回返情况: Promise<string> - 注销的散列交易
示例
import { TradingSdk } from '@cowprotocol/sdk-trading'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const orderUid = '0xd64389693b6cf89ad6c140a113b10df08073e5ef3063d05a02f3f42e1a42f0ad...'
const txHash = await sdk.onChainCancelOrder({ orderUid })
console.log('Cancellation transaction:', txHash)
托肯核准
在交易 ERC-20 令牌之前,你需要批准 CoW 协议来使用它们. SDK提供了检查和管理令牌批准的方法.
获得牛协议
检查当前对 CoW 协议.
参数:
tokenAddress- ERC-20契约地址owner- 信物拥有者的地址chainId- (可选)链式ID,如果不提供则使用交易员参数
回返情况: Promise<bigint> - 现行津贴数额
示例
import { TradingSdk } from '@cowprotocol/sdk-trading'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const tokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC
const owner = '0x...' // Your wallet address
const allowance = await sdk.getCowProtocolAllowance({
tokenAddress,
owner,
})
console.log('Current allowance:', allowance.toString())
核准的牛议定书
批准《COW议定书》的舱道更新器,以花费一定数量的ERC-20令牌。 这就产生了一个连锁批准交易.
参数:
tokenAddress- ERC-20契约地址amount- 批准金额(如大意)chainId- (可选)链式ID,如果不提供则使用交易员参数signer- (可选的)自定义签名器,如果不提供则使用交易人参数签名器
回返情况: Promise<string> - 核准的散列交易
示例
import { TradingSdk } from '@cowprotocol/sdk-trading'
import { parseUnits } from 'viem' // or ethers
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const tokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC
const amount = parseUnits('1000', 6) // 1000 USDC (6 decimals)
const txHash = await sdk.approveCowProtocol({
tokenAddress,
amount,
})
console.log('Approval transaction:', txHash)
智能核准流程
建议在批准前先检查目前的备抵,以避免不必要的交易: 1
import { TradingSdk } from '@cowprotocol/sdk-trading'
import { parseUnits } from 'viem'
const sdk = new TradingSdk({
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
}, {}, adapter)
const tokenAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC
const owner = '0x...' // Your wallet address
const requiredAmount = parseUnits('1000', 6) // 1000 USDC
// Check current allowance
const currentAllowance = await sdk.getCowProtocolAllowance({
tokenAddress,
owner,
})
// Only approve if needed
if (currentAllowance < requiredAmount) {
const txHash = await sdk.approveCowProtocol({
tokenAddress,
amount: requiredAmount,
})
console.log('Approval transaction:', txHash)
} else {
console.log('Sufficient allowance already exists')
}
自定义合同地址
对于诸如测试,自定义部署,或以非标准地址部署COW协议合同的链条等高级使用情况,您可以推翻SDK所使用的合同地址.
两个参数都接受 AddressPerChain 对象(Record<SupportedChainId, Address>)),因此它们适用每链并在所有作业中坚持使用 traderParams。 。 。 .
合同重叠/ 电子合同重叠
取代《企业协议解决合同》的地址。 这影响到:
- 命令域签名( EIP-712)
verifyingContract(中文(简体) ) - 链上订单取消
onChainCancelOrder - 通过
getPreSignTransaction
import { SupportedChainId, OrderKind, TradeParameters, TradingSdk, COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS, ETH_FLOW_ADDRESSES } from '@cowprotocol/cow-sdk'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { sepolia } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({
chain: sepolia,
transport: http('YOUR_RPC_URL')
}),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
})
const sdk = new TradingSdk({
chainId: SupportedChainId.SEPOLIA,
appCode: '<YOUR_APP_CODE>',
// Override the settlement contract address for MAINNET
settlementContractOverride: {
...COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS,
[SupportedChainId.MAINNET]: '0x<custom_settlement_contract>',
} as AddressPerChain,
// Override the eth-flow contract address for GNOSIS_CHAIN
ethFlowContractOverride: {
...ETH_FLOW_ADDRESSES,
[SupportedChainId.GNOSIS_CHAIN]: '0x<custom_eth_flow_contract>',
} as AddressPerChain,
}, {}, adapter)
const parameters: TradeParameters = {
kind: OrderKind.BUY,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '120000000000000000',
}
const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote(parameters)
const orderId = await postSwapOrderFromQuote()
console.log('Order created, id: ', orderId)
也可以通过 settlementContractOverride 编号 : ethFlowContractOverride 仅用于此操作的调用 :
const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote({
...parameters,
settlementContractOverride: {
[SupportedChainId.MAINNET]: '0x<custom_settlement_contract>',
} as AddressPerChain,
})
// or
const { orderId } = await sdk.postSwapOrder({
...parameters,
settlementContractOverride: {
[SupportedChainId.MAINNET]: '0x<custom_settlement_contract>',
} as AddressPerChain,
})
自定义顺序- Book API 结束点
默认情况下,SDK使用公开的CoW协议API端点. 您可以通过创建自定义或自托管命令簿来指示 SDK OrderBookApi 带有自定义的示例 baseUrls 并传递作为 orderBookApi 选项.
这对于:
- 开发期间运行本地命令簿节点
- 使用私人/专用的API部署
- 以自定义后端连接到防御或测试网环境
import { SupportedChainId, TradingSdk, OrderKind, TradeParameters } from '@cowprotocol/sdk-trading'
import { OrderBookApi } from '@cowprotocol/sdk-order-book'
import { AddressPerChain } from '@cowprotocol/sdk-config'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { createPublicClient, http, privateKeyToAccount } from 'viem'
import { mainnet } from 'viem/chains'
const adapter = new ViemAdapter({
provider: createPublicClient({ chain: mainnet, transport: http('YOUR_RPC_URL') }),
signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`),
})
// 1. Create an OrderBookApi instance with custom base URLs
const orderBookApi = new OrderBookApi({
chainId: SupportedChainId.MAINNET,
// Provide a base URL for each chain you intend to use
baseUrls: {
// ...
[SupportedChainId.MAINNET]: 'https://your-custom-orderbook.example.com/mainnet',
},
})
// 2. Pass it to TradingSdk via the options object
const sdk = new TradingSdk(
{
chainId: SupportedChainId.MAINNET,
appCode: '<YOUR_APP_CODE>',
},
{
orderBookApi, // All order-book requests will go to your custom endpoint
},
adapter,
)
const parameters: TradeParameters = {
kind: OrderKind.SELL,
sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
sellTokenDecimals: 18,
buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
buyTokenDecimals: 18,
amount: '100000000000000000',
}
const { orderId } = await sdk.postSwapOrder(parameters)
console.log('Order created via custom endpoint, id:', orderId)