> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/cowprotocol/cow-sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# Programmatic Orders

> Create conditional and composable orders that execute automatically based on specified conditions

The CoW Protocol Composable SDK enables sophisticated trading strategies through conditional orders that execute automatically when specified conditions are met. This allows you to build advanced trading logic without constant monitoring.

## Installation

```bash theme={null}
npm install @cowprotocol/sdk-composable
```

## Core Components

### ConditionalOrderFactory

Registry-based factory for creating different types of conditional orders:

```typescript theme={null}
import { ConditionalOrderFactory } from '@cowprotocol/sdk-composable'

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

### Multiplexer

Manages batches of conditional orders using merkle trees:

```typescript theme={null}
import { Multiplexer } from '@cowprotocol/sdk-composable'

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

### ConditionalOrder

Base class for implementing custom conditional order types:

```typescript theme={null}
import { ConditionalOrder } from '@cowprotocol/sdk-composable'

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

## Basic Usage

<CodeGroup>
  ```typescript Standalone theme={null}
  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,
    // ... 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()
  ```

  ```typescript With CoW SDK theme={null}
  import { 
    CowSdk, 
    ConditionalOrderFactory, 
    Multiplexer, 
    ProofLocation 
  } from '@cowprotocol/cow-sdk'
  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 the unified SDK
  const sdk = new CowSdk({
    chainId: SupportedChainId.MAINNET,
    adapter,
    composableOptions: {
      registry: orderTypeRegistry,
      orders: initialOrders,
      root: merkleRoot,
      location: ProofLocation.PRIVATE,
    },
  })

  // Access composable functionality
  const factory = sdk.composable.factory
  const multiplexer = sdk.composable.multiplexer

  // Create conditional orders
  const conditionalOrder = factory.fromParams(orderParams)
  ```
</CodeGroup>

## Order Types

### Stop-Loss Orders

Automatically sell when price drops below a threshold:

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

### Limit Orders

Execute trades at specific price points:

```typescript theme={null}
const limitOrder = new LimitOrder({
  handler: LIMIT_ORDER_HANDLER,
  sellToken: '0x...', // USDC
  buyToken: '0x...', // ETH
  sellAmount: '2000000000', // $2000 USDC
  buyAmount: '1000000000000000000', // 1 ETH minimum
  validTo: Math.floor(Date.now() / 1000) + 3600, // Valid for 1 hour
})
```

### DCA (Dollar Cost Averaging)

Regularly buy or sell assets at predetermined intervals:

```typescript theme={null}
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
})
```

<Info>
  See the [TWAP Orders](/advanced/twap-orders) page for detailed information about Time-Weighted Average Price orders.
</Info>

## Merkle Tree Management

Conditional orders are stored in merkle trees for efficient on-chain verification:

```typescript theme={null}
// 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
})
```

## Order Validation

Validate conditional orders before execution:

```typescript theme={null}
// 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,
  })
}
```

## Context Dependencies

Orders can depend on external data sources:

```typescript theme={null}
// 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)
  },
)
```

## Order Registry Management

Register custom order types:

```typescript theme={null}
// 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)
```

## Smart Contract Integration

### ComposableCoW Contract

```typescript theme={null}
// 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
)
```

### Proof Generation and Storage

```typescript theme={null}
// 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)
```

## Complete Example

Here's a complete example setting up a stop-loss order:

```typescript theme={null}
import { 
  ConditionalOrderFactory,
  Multiplexer,
  ProofLocation,
  SupportedChainId
} from '@cowprotocol/sdk-composable'
import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'

// 1. Initialize adapter and factory
const adapter = new EthersV6Adapter({ provider, signer: wallet })
const factory = new ConditionalOrderFactory(registry, adapter)

// 2. Create stop-loss order
const stopLoss = new StopLossOrder({
  sellToken: WETH_ADDRESS,
  buyToken: USDC_ADDRESS,
  sellAmount: parseEther('10'),
  strikePrice: '2000000000', // $2000
})

// 3. Create multiplexer
const multiplexer = new Multiplexer(SupportedChainId.MAINNET)
multiplexer.addOrder('stop-loss-1', stopLoss)

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

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

console.log('Stop-loss order created and activated')
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always validate orders before submission">
    Use the `isValid()` method to catch configuration errors early:

    ```typescript theme={null}
    const validation = await order.isValid({ owner, ctx })
    if (!validation.isValid) {
      throw new Error(`Invalid order: ${validation.reason}`)
    }
    ```
  </Accordion>

  <Accordion title="Store proofs off-chain">
    Generate and store merkle proofs off-chain to enable watchtowers to execute your orders:

    ```typescript theme={null}
    const proofs = multiplexer.dumpProofsAndParams()
    await uploadToIPFS(proofs)
    ```
  </Accordion>

  <Accordion title="Use appropriate context factories">
    Set context factories for orders that need on-chain data:

    ```typescript theme={null}
    const order = new TWAPOrder({
      // ... parameters
    })
    // TWAP automatically uses CurrentBlockTimestampFactory when needed
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="TWAP Orders" icon="chart-line" href="/advanced/twap-orders">
    Learn about Time-Weighted Average Price orders
  </Card>

  <Card title="Hooks" icon="webhook" href="/advanced/hooks">
    Execute custom logic with pre and post hooks
  </Card>
</CardGroup>
