@cowprotocol/sdk-composable

中文文档
1.8.14发布于 2026/11/04MITTypeScriptESM + CJS构建来源已验证近 30 天下载 4362

COW 协议 SDK 的可编译特性

中文使用文档
文档目录22 节
  1. 测试覆盖率
  2. 安装
  3. 读取 TWAP 历史
  4. 核心组成部分
  5. 有条件的命令事实
  6. 多轴
  7. 有条件的命令
  8. JIT 波尔勒
  9. 使用量
  10. 有条件的顺序类型
  11. TWAP(时间加权平均价格)
  12. DCA(Dollar Cost Avering)——世界投资方案
  13. 停止损失命令——WIP
  14. 高级特性
  15. 默克勒树管理
  16. 顺序验证
  17. 依附关系
  18. 登记管理
  19. 智能合同集成
  20. 可编程 CoW 一体化
  21. 证明生成和储存
  22. 完成 TWAP 设置

SDK 可编译

测试覆盖率

发言分支职能行数
StatementsBranchesFunctionsLines

这个软件包为CoW协议提供了高级的有条件和可编程的命令功能. 它通过在满足特定条件时自动执行的有条件命令,得以制定、管理和执行复杂的交易战略.

安装

npm install @cowprotocol/sdk-composable
or
pnpm add @cowprotocol/sdk-composable
or
yarn add @cowprotocol/sdk-composable

读取 TWAP 历史

import { ProgrammaticOrderApi } from '@cowprotocol/sdk-composable'
import { SupportedChainId } from '@cowprotocol/sdk-config'

const api = new ProgrammaticOrderApi()
const { items: twaps } = await api.getTwapOrders({
  resolvedOwner: '0x...',
  chainId: SupportedChainId.GNOSIS_CHAIN,
})
const { items: parts } = await api.getTwapPartOrders(
  {
    eventId: twaps[0].eventId,
    chainId: SupportedChainId.GNOSIS_CHAIN,
  },
  {
    offset: 0,
    limit: 10,
    direction: 'desc',
  },
)

两种方法返回 QueryPage<T> 并接受可选 QueryOptions (单位:千美元)offset, (中文(简体) ), limit, (中文(简体) ), direction) (中文(简体) ). 父结果包括执行总数和索引部分计数;通过返回 eventId 以获取部件.

核心组成部分

有条件的命令事实

以登记为基础的制造不同类型的有条件订单的工厂:

import { ConditionalOrderFactory } from '@cowprotocol/sdk-composable'

const factory = new ConditionalOrderFactory(registry, adapter)
const conditionalOrder = factory.fromParams(orderParams)

多轴

使用 merkle 树管理批次的有条件订单 :

import { Multiplexer } from '@cowprotocol/sdk-composable'

const multiplexer = new Multiplexer(chainId, orders, root, location)
const proofs = multiplexer.dumpProofsAndParams()

有条件的命令

执行自定义条件排序类型的基础类 :

import { ConditionalOrder } from '@cowprotocol/sdk-composable'

class CustomOrder extends ConditionalOrder<DataType, StaticType> {
  // Implement custom conditional logic
}

JIT 波尔勒

一揽子出口公用事业需要与部署的公用事业结合起来 ComposableCowPoller. Poller 移动从一个供资账户(通常为EOA)及时向可编译的 CoW 订单拥有者/交易者出售代币。 这避免了要求交易员账户为全程预留资金,减少了设置摩擦和闲置资本.

该套件暴露出两个Poller API:低等 ComposableCowPoller 下面只读到状态和编码调用数据,而 ComposableCowPollerSdk 通过配置的适配器添加签名和交易提交.

import { ComposableCowPoller, type ComposableCowPollerSchedule } from '@cowprotocol/sdk-composable'
import { setGlobalAdapter } from '@cowprotocol/sdk-common'

setGlobalAdapter(adapter)

const poller = new ComposableCowPoller(pollerAddress)
const schedule: ComposableCowPollerSchedule = {
  handler,
  authEpoch,
  funder,
  owner,
  salt,
  staticInput,
}
const scheduleId = poller.getScheduleId(schedule)

// Submit this calldata to pollerAddress from schedule.funder.
const registerCalldata = poller.encodeRegister(schedule)

// Anyone may submit this calldata to pollerAddress when the next order part needs funding.
const pollFundsCalldata = poller.encodePollFunds(scheduleId)

// Or authorize registration for submission by another account.
const deadline = Math.floor(Date.now() / 1000) + 15 * 60
const typedData = poller.getRegisterTypedData({ chainId, schedule, deadline })
const signature = await adapter.signer.signTypedData(typedData.domain, typedData.types, typedData.message)
const signedRegisterCalldata = poller.encodeRegisterWithSignature(schedule, deadline, signature)

// Direct revocation must be submitted by schedule.funder.
const revokeCalldata = poller.encodeRevoke(schedule)

// Or authorize revocation for submission by another account.
const revokeAuthorization = {
  handler: schedule.handler,
  authEpoch: schedule.authEpoch,
  funder: schedule.funder,
  owner: schedule.owner,
  salt: schedule.salt,
}
const revokeDeadline = Math.floor(Date.now() / 1000) + 15 * 60
const revokeTypedData = poller.getRevokeTypedData({
  chainId,
  ...revokeAuthorization,
  deadline: revokeDeadline,
})
const revokeSignature = await adapter.signer.signTypedData(
  revokeTypedData.domain,
  revokeTypedData.types,
  revokeTypedData.message,
)
const signedRevokeCalldata = poller.encodeRevokeWithSignature(revokeAuthorization, revokeDeadline, revokeSignature)

安装 CowShed 软件包以获取一个与 Poller 兼容的账户 :

npm install @cowprotocol/sdk-cow-shed

配置 CowShedSdk 与可编译的CoW工厂. 它必须匹配 poller.getCowShedFactoryAddress()。 。 。 .

import {
  COW_SHED_FACTORY_FOR_COMPOSABLE_COW,
  COW_SHED_IMPLEMENTATION_FOR_COMPOSABLE_COW,
  COW_SHED_LATEST_VERSION,
  CowShedSdk,
} from '@cowprotocol/sdk-cow-shed'

const cowShedSdk = new CowShedSdk(adapter, {
  factoryAddress: COW_SHED_FACTORY_FOR_COMPOSABLE_COW[COW_SHED_LATEST_VERSION],
  implementationAddress: COW_SHED_IMPLEMENTATION_FOR_COMPOSABLE_COW[COW_SHED_LATEST_VERSION],
})
const cowShed = cowShedSdk.getCowShedAccount(chainId, funder)

从出资人自己的CowShed注册, 将Poller的呼叫包含在一个签名的捆绑。 计程车的车主必须和牛舍一样 签名前刷新此调度 ID 的时代 .

const shedSchedule = { ...schedule, owner: cowShed }
const { authEpoch: shedAuthEpoch } = await poller.getSchedule(poller.getScheduleId(shedSchedule))

const registration = await cowShedSdk.signCalls({
  chainId,
  signer,
  calls: [
    {
      target: pollerAddress,
      callData: poller.encodeRegisterFromShed({ ...shedSchedule, authEpoch: shedAuthEpoch }),
      value: 0n,
      isDelegateCall: false,
      allowFailure: false,
    },
  ],
})

从出资人自己的"牛舍"中撤销,将"波勒"的电话收录在了签名的捆绑中. 使用原始调度身份并刷新其签署前的时代 。 退位并不要求日程所有者与"牛舍"持平.

const { authEpoch: revokeAuthEpoch } = await poller.getSchedule(scheduleId)

const revocation = await cowShedSdk.signCalls({
  chainId,
  signer,
  calls: [
    {
      target: pollerAddress,
      callData: poller.encodeRevokeFromShed({ ...schedule, authEpoch: revokeAuthEpoch }),
      value: 0n,
      isDelegateCall: false,
      allowFailure: false,
    },
  ],
})

使用 ComposableCowPollerSdk 通过配置的适配器签名或提交交易。 内容 poller 属性暴露出相同的低等调用数据并读取上述方法。 用这个 schedule,在下面选择直接流或签名流;不为同一登记运行两者.

import { ComposableCowPollerSdk } from '@cowprotocol/sdk-composable'

const pollerSdk = new ComposableCowPollerSdk({ chainId, pollerAddress, signer }, adapter)
const deadline = Math.floor(Date.now() / 1000) + 15 * 60

// Direct flow: use the SDK signer, or the adapter signer when none was configured.
const transaction = await pollerSdk.register({ schedule })
await transaction.wait()

// Signature flow: keep the intended schedule and refresh only its replay-protection epoch.
const { authEpoch } = await pollerSdk.poller.getSchedule(scheduleId)
const currentSchedule = { ...schedule, authEpoch }
const authorization = await pollerSdk.signRegister({ schedule: currentSchedule, deadline })
// authorization.calldata is ready for a hook or relayed transaction.
// authorization.typedData and authorization.signature are also available for inspection.

// Alternatively, submit the authorization now with a relayer signer.
const relayedTransaction = await pollerSdk.registerWithSignature({
  schedule: currentSchedule,
  deadline,
  signature: authorization.signature,
  signer: relayerSigner,
})
await relayedTransaction.wait()

signRevoke 遵循相同的签名流程并签名所提供的时间表身份 authEpoch仅刷新 authEpoch 与 pollerSdk.poller.getSchedule(scheduleId) 在签署之前; 一个不活动的时间表保留其时代而不是其他字段.

考克谢德注册,请通过 cowShedSdk 上方配置 。 SDK 使用它配置的标志器, 当没有配置时使用适配器标志器, 或每个调用 signer 超过。 那个签人必须是日程的出资人,日程的主人必须是它的"牛舍".

const registrationSchedule = { ...schedule, owner: cowShed }
const { authEpoch: registrationEpoch } = await pollerSdk.poller.getSchedule(
  pollerSdk.poller.getScheduleId(registrationSchedule),
)
const shedRegistrationParams = {
  cowShedSdk,
  schedule: { ...registrationSchedule, authEpoch: registrationEpoch },
  deadline: BigInt(Math.floor(Date.now() / 1000) + 15 * 60),
}

// Sign only: hand this factory transaction to a relayer or hook.
const signedRegistration = await pollerSdk.signRegisterFromShed(shedRegistrationParams)
// signedRegistration includes cowShedAccount, signedMulticall and gasLimit.

// Alternative: sign and submit now; the resolved signer pays transaction gas.
const shedRegistrationTx = await pollerSdk.registerFromShed(shedRegistrationParams)
await shedRegistrationTx.wait()

选择其中的一种流 。 两人都签了"牛舍"捆绑单波勒电话. 工厂根据需要创建了"牛舍"(CowShed),并从中执行注册. 他们接受牛舍德的 nonce, (中文(简体) ), deadline, (中文(简体) ), signingScheme, (中文(简体) ), gasLimit,以及 defaultGasLimit 选项。 没有气体覆盖, CowShed 估计气体; 失败拒绝调用, 除非提供倒计时。 对于包含其他呼叫的捆绑,使用 pollerSdk.poller.encodeRegisterFromShed 与 cowShedSdk.signCalls。 。 。 .

对于CowShed的撤销,保留原始的排行表身份,包括它的主人,即使它不同于CowShed. 决心的签名者必须是资助者. 签名前刷新时代 :

const { authEpoch: revocationEpoch } = await pollerSdk.poller.getSchedule(scheduleId)
const shedRevocationParams = {
  cowShedSdk,
  handler: schedule.handler,
  funder: schedule.funder,
  owner: schedule.owner,
  salt: schedule.salt,
  authEpoch: revocationEpoch,
  deadline: BigInt(Math.floor(Date.now() / 1000) + 15 * 60),
}

// Sign only: return the factory bundle for a relayer or hook.
const signedRevocation = await pollerSdk.signRevokeFromShed(shedRevocationParams)

// Alternative: sign and submit now; the resolved signer pays transaction gas.
const shedRevocationTx = await pollerSdk.revokeFromShed(shedRevocationParams)
await shedRevocationTx.wait()

选择一流. signRevokeFromShed 返回时 cowShedAccount, (中文(简体) ), signedMulticall,以及 gasLimit 不提交。 两种方法都接受与注册相同的签注和CowShed选项. 对于包含其他通话的捆绑,请使用 pollerSdk.poller.encodeRevokeFromShed 与 cowShedSdk.signCalls。 。 。 .

时间表字段为:

  • handler: 注册的有条件命令的处理者.
  • authEpoch: 调度 ID 当前重放保护时代; 它从零开始,并在撤销时递增.
  • funder: Poller从中提取出销售信使的账户.
  • owner: 接收这些令牌的可编程 CoW 有条件命令所有者 .
  • salt:注册的有条件订单的盐.
  • staticInput:已注册的条件令被编码为静态输入.

低层 ComposableCowPoller 仅编码这些交易;其消费者拥有签名、天然气政策、提交和确认。 将直接注册和撤销调用数据提交 pollerAddress 从 schedule.funder,或提交 signedRegisterCalldata 或者说 signedRevokeCalldata 通过中继器。 已签名的注册呼叫数据包含时间表、截止日期和签名。 已签名的撤销调用数据包含处理者、供资者、所有者、盐、, authEpoch、截止日期和签名。 重放保护范围为列表 ID 通过 authEpoch启用 poller.getComposableCowAddress() 财务报告和审定财务报表 poller.getSchedule(scheduleId) 读取 Poller 状态.

使用量

import { ConditionalOrderFactory, Multiplexer, ConditionalOrder, ProofLocation } from '@cowprotocol/sdk-composable'
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 })

// Create a conditional order factory
const registry = {
  twap: TWAPOrderFactory,
  dca: DCAOrderFactory, // WIP: not implemented
  // ... other order types
}

const factory = new ConditionalOrderFactory(registry, adapter)

// Create conditional orders
const twapOrder = factory.fromParams({
  handler: TWAP_HANDLER_ADDRESS,
  salt: '0x...',
  staticInput: encodedTWAPData,
})

// Create multiplexer for batch management
const orders = {
  order1: twapOrder,
  // ... more orders
}

const multiplexer = new Multiplexer(SupportedChainId.MAINNET, orders, merkleRoot, ProofLocation.PRIVATE)

// Generate proofs for off-chain storage
const proofs = multiplexer.dumpProofsAndParams()

有条件的顺序类型

TWAP(时间加权平均价格)

逐步执行交易,以达到更好的平均价格:

const twapOrder = new TWAPOrder({
  handler: TWAP_HANDLER,
  sellToken: '0x...',
  buyToken: '0x...',
  sellAmount: '1000000000000000000',
  numOfParts: 10,
  timeInterval: 3600, // 1 hour intervals
  startTime: Math.floor(Date.now() / 1000),
  span: 0, // Execute indefinitely
})

DCA(Dollar Cost Avering)——世界投资方案

DCAOrder 尚未执行或导出.

按预定的间隔定期买卖资产:

const dcaOrder = new DCAOrder({
  handler: DCA_HANDLER,
  sellToken: '0x...', // USDC
  buyToken: '0x...', // ETH
  sellAmount: '100000000', // $100 USDC
  timeInterval: 86400, // Daily
  numOfParts: 30, // For 30 days
})

停止损失命令——WIP

StopLossOrder 尚未执行或导出.

价格低于阈值时自动销售 :

const stopLossOrder = new StopLossOrder({
  handler: STOP_LOSS_HANDLER,
  sellToken: '0x...', // ETH
  buyToken: '0x...', // USDC
  sellAmount: '1000000000000000000', // 1 ETH
  strikePrice: '2000000000', // Trigger at $2000
})

高级特性

默克勒树管理

// Create multiplexer with multiple orders
const multiplexer = new Multiplexer(
  SupportedChainId.MAINNET,
  conditionalOrders,
  undefined, // Will generate merkle root
  ProofLocation.PRIVATE,
)

// Get merkle root for on-chain storage
const root = multiplexer.getOrGenerateTree().root

// Generate proofs for specific orders
const proofs = multiplexer.dumpProofsAndParams((order) => {
  return order.isActive // Only include active orders
})

顺序验证

// Check if conditional order is valid
const validationResult = await conditionalOrder.isValid({
  owner: userAddress,
  ctx: contextData,
})

if (validationResult.isValid) {
  // Order can be executed
  const tradeableOrder = await conditionalOrder.poll({
    owner: userAddress,
    proof: merkleProof,
    provider: provider,
  })
}

依附关系

// Orders that depend on external data
const conditionalOrder = new PriceBasedOrder({
  handler: PRICE_HANDLER,
  // ... order parameters
})

// Get context dependency (e.g., price oracle)
const contextDependency = conditionalOrder.getContextDependency()

// Poll with off-chain input
const [orderData, signature] = await ConditionalOrder.poll(
  owner,
  proofWithParams,
  chainId,
  provider,
  async (owner, params) => {
    // Fetch off-chain data (prices, etc.)
    return await fetchOffChainInput(params)
  },
)

登记管理

// Register custom order types
const registry = {
  'custom-twap': CustomTWAPOrder,
  'limit-order': LimitOrder,
  'bracket-order': BracketOrder,
}

const factory = new ConditionalOrderFactory(registry, adapter)

// Register new order type dynamically
Multiplexer.registerOrderType('new-order-type', NewOrderClass)

智能合同集成

可编程 CoW 一体化

// Set merkle root on ComposableCoW contract
const composableCowContract = adapter.getContract(COMPOSABLE_COW_CONTRACT_ADDRESS[chainId], ComposableCowABI)

// Set root with context
await composableCowContract.setRootWithContext(root, contextFactory, contextData)

证明生成和储存

// Generate proofs for watchtowers/indexers
const proofsData = multiplexer.dumpProofs((order) => {
  // Filter criteria for proof inclusion
  return order.status === 'active'
})

// Store proofs off-chain (IPFS, etc.)
await uploadProofs(proofsData)

// Verify proofs on-chain when executing
const isValidProof = multiplexer.getOrGenerateTree().verify(proof, leafData)

完成 TWAP 设置

// 1. Create TWAP order
const twapOrder = new TWAPOrder({
  sellToken: WETH_ADDRESS,
  buyToken: USDC_ADDRESS,
  sellAmount: parseEther('10'), // 10 WETH
  numOfParts: 24, // 24 parts
  timeInterval: 3600, // 1 hour intervals
  startTime: Math.floor(Date.now() / 1000),
})

// 2. Create multiplexer
const multiplexer = new Multiplexer(SupportedChainId.MAINNET)
multiplexer.addOrder('twap-1', twapOrder)

// 3. Set root on ComposableCoW
const root = multiplexer.getOrGenerateTree().root
await composableCowContract.setRoot(root)

// 4. Generate proofs for watchtower
const proofs = multiplexer.dumpProofsAndParams()
await storeProofsOffChain(proofs)

说明: 这个软件包通过可编程的有条件订单,可以实现高级交易策略. 它为需要自动执行复杂交易逻辑的精密用户所设计. 大多数基本贸易需要可以通过贸易SDK来解决.

版本与发布记录

@cowprotocol/sdk-composable 共发布 96 个版本,首次发布于 2025/08/02;过去 12 个月发布了 71 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.8.14latest2026/11/046 天前
1.8.132026/11/046 天前
1.8.122026/11/037 天前
1.8.112026/10/2615 天前
1.8.102026/10/2615 天前
1.8.92026/10/2318 天前

其他发布通道:next → 0.2.1-beta.0。

关于 @cowprotocol/sdk-composable 的常见问题

@cowprotocol/sdk-composable 是什么?

COW 协议 SDK 的可编译特性

如何安装 @cowprotocol/sdk-composable?

在项目目录运行 npm install @cowprotocol/sdk-composable,或使用 pnpm add / yarn add / bun add。

@cowprotocol/sdk-composable 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cowprotocol/sdk-composable 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cowprotocol/sdk-composable 可以商用吗?

@cowprotocol/sdk-composable 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cowprotocol/sdk-composable 的下载量有多少?

根据 npm 官方下载统计,@cowprotocol/sdk-composable 在 2026/10/11 – 2026/11/09 这 30 天内被下载 4,362 次,日均约 145 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cowprotocol/sdk-composable 还在维护吗?

最新版本 1.8.14 发布于 2026/11/04(6 天前);至今共发布 96 个版本,其中过去 12 个月发布了 71 个;首次发布于 2025/08/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。