Skip to main content

Order

The Order dataclass represents a CoW Protocol order with all necessary parameters for trading.
@dataclass
class Order:
    sell_token: str
    buy_token: str
    receiver: str
    sell_amount: str
    buy_amount: str
    valid_to: int
    app_data: str
    fee_amount: str
    kind: str
    partially_fillable: bool = False
    sell_token_balance: Optional[str] = None
    buy_token_balance: Optional[str] = None

Fields

sell_token
str
required
The address of the token to sell. Also accessible via sellToken alias.
buy_token
str
required
The address of the token to buy. Also accessible via buyToken alias.
receiver
str
required
The address to receive the bought tokens. Cannot be address(0).
sell_amount
str
required
The amount of sell tokens (as a string to handle large numbers).
  • For sell orders: exact amount to sell
  • For buy orders: maximum amount to sell
  • For partial fills: component of limit price
Also accessible via sellAmount alias.
buy_amount
str
required
The amount of buy tokens (as a string to handle large numbers).
  • For sell orders: minimum amount to receive
  • For buy orders: exact amount to receive
  • For partial fills: component of limit price
Also accessible via buyAmount alias.
valid_to
int
required
Unix timestamp until which the order is valid. Also accessible via validTo alias.
app_data
str
required
Application-specific data hash (32 bytes). Used for metadata and ensuring order uniqueness. Also accessible via appData alias.
fee_amount
str
required
Fee amount to pay to the protocol (as a string). Usually “0” for CoW Swap. Also accessible via feeAmount alias.
kind
str
required
Order type: either “sell” or “buy”
partially_fillable
bool
default:"False"
Whether the order can be partially filled. Also accessible via partiallyFillable alias.
sell_token_balance
Optional[str]
default:"None"
How to withdraw sell tokens: “erc20” (default), “external”, or “internal” (Balancer Vault). Also accessible via sellTokenBalance alias.
buy_token_balance
Optional[str]
default:"None"
How to receive buy tokens: “erc20” (default) or “internal” (Balancer Vault). Also accessible via buyTokenBalance alias.

Usage Example

from cowdao_cowpy.contracts.order import Order
from cowdao_cowpy.app_data.utils import DEFAULT_APP_DATA_HASH
import time

# Create a sell order
order = Order(
    sell_token="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",  # USDC
    buy_token="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",   # WETH
    receiver="0x1234567890123456789012345678901234567890",
    sell_amount="1000000000",  # 1000 USDC (6 decimals)
    buy_amount="500000000000000000",  # 0.5 WETH minimum
    valid_to=int(time.time()) + 3600,  # Valid for 1 hour
    app_data=DEFAULT_APP_DATA_HASH,
    fee_amount="0",
    kind="sell",
    partially_fillable=False,
)

# Access via original field name
print(f"Sell token: {order.sell_token}")

# Or via camelCase alias
print(f"Sell token: {order.sellToken}")

OrderKind Enum

class OrderKind(Enum):
    SELL = "sell"
    BUY = "buy"

OrderBalance Enum

class OrderBalance(Enum):
    ERC20 = "erc20"        # Use ERC20 token balances
    EXTERNAL = "external"  # Use Balancer Vault external balances
    INTERNAL = "internal"  # Use Balancer Vault internal balances

domain

Create an EIP-712 domain for signing CoW Protocol orders.
def domain(chain: Chain, verifying_contract: str) -> TypedDataDomain
chain
Chain
required
The blockchain network (contains chain ID)
verifying_contract
str
required
The address of the contract that will verify the signature (typically the Settlement contract)
Returns: A TypedDataDomain object for EIP-712 signing
TypedDataDomain
TypedDataDomain
EIP-712 domain data

Usage Example

from cowdao_cowpy.contracts.domain import domain
from cowdao_cowpy.common.chains import Chain
from cowdao_cowpy.common.constants import CowContractAddress

# Create domain for Ethereum mainnet
order_domain = domain(
    chain=Chain.MAINNET,
    verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
)

print(f"Domain name: {order_domain.name}")
print(f"Version: {order_domain.version}")
print(f"Chain ID: {order_domain.chainId}")
print(f"Contract: {order_domain.verifyingContract}")

# Output:
# Domain name: Gnosis Protocol
# Version: v2
# Chain ID: 1
# Contract: 0x9008D19f58AAbD9eD0D60971565AA8510560ab41

For Different Chains

from cowdao_cowpy.common.chains import Chain

# Gnosis Chain
domain_gc = domain(
    chain=Chain.GNOSIS,
    verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
)

# Arbitrum
domain_arb = domain(
    chain=Chain.ARBITRUM_ONE,
    verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
)

sign_order

Sign an order using EIP-712 typed data signing.
def sign_order(
    domain: TypedDataDomain,
    order: Order,
    owner: LocalAccount,
    scheme: SigningScheme
) -> EcdsaSignature
domain
TypedDataDomain
required
The EIP-712 domain for the target chain and contract
order
Order
required
The order to sign
owner
LocalAccount
required
The account to sign with (from eth_account)
scheme
SigningScheme
required
The signing scheme to use (typically SigningScheme.EIP712)
Returns: An EcdsaSignature object containing the signature data

SigningScheme Enum

class SigningScheme(IntEnum):
    EIP712 = 0b00    # EIP-712 typed data (recommended)
    ETHSIGN = 0b01   # eth_sign RPC call
    EIP1271 = 0b10   # Smart contract signatures
    PRESIGN = 0b11   # Pre-signed orders

EcdsaSignature

@dataclass
class EcdsaSignature:
    scheme: SigningScheme
    data: str
    
    def to_string(self) -> str:
        # Returns signature as hex string

Usage Example

from eth_account import Account
from cowdao_cowpy.contracts.sign import sign_order, SigningScheme
from cowdao_cowpy.contracts.domain import domain
from cowdao_cowpy.contracts.order import Order
from cowdao_cowpy.common.chains import Chain
from cowdao_cowpy.common.constants import CowContractAddress

# Create account
private_key = "0x..."
account = Account.from_key(private_key)

# Create domain
order_domain = domain(
    chain=Chain.MAINNET,
    verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
)

# Create order
order = Order(
    sell_token="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    buy_token="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    receiver=account.address,
    sell_amount="1000000000",
    buy_amount="500000000000000000",
    valid_to=1234567890,
    app_data="0x" + "0" * 64,
    fee_amount="0",
    kind="sell",
)

# Sign the order
signature = sign_order(
    domain=order_domain,
    order=order,
    owner=account,
    scheme=SigningScheme.EIP712
)

print(f"Signature scheme: {signature.scheme}")
print(f"Signature data: {signature.to_string()}")

Additional Functions

hash_order

Compute the 32-byte signing hash for an order.
def hash_order(domain: TypedDataDomain, order: Order) -> Hash32
domain
TypedDataDomain
required
The EIP-712 domain
order
Order
required
The order to hash
Returns: 32-byte hash of the order Example:
from cowdao_cowpy.contracts.order import hash_order

order_hash = hash_order(order_domain, order)
print(f"Order hash: {order_hash.hex()}")

compute_order_uid

Compute the unique identifier for an order.
def compute_order_uid(domain: TypedDataDomain, order: Order, owner: str) -> str
domain
TypedDataDomain
required
The EIP-712 domain
order
Order
required
The order
owner
str
required
The owner’s Ethereum address
Returns: The 56-byte order UID as a hex string Example:
from cowdao_cowpy.contracts.order import compute_order_uid

order_uid = compute_order_uid(order_domain, order, account.address)
print(f"Order UID: {order_uid}")
# This UID uniquely identifies the order and can be used to track it

sign_order_cancellation

Sign a cancellation for a single order.
def sign_order_cancellation(
    domain: TypedDataDomain,
    order_uid: Union[str, bytes],
    owner: LocalAccount,
    scheme: SigningScheme,
) -> EcdsaSignature
domain
TypedDataDomain
required
The EIP-712 domain
order_uid
Union[str, bytes]
required
The UID of the order to cancel
owner
LocalAccount
required
The account that owns the order
scheme
SigningScheme
required
The signing scheme
Returns: Signature for the cancellation Example:
from cowdao_cowpy.contracts.sign import sign_order_cancellation, SigningScheme

cancellation_sig = sign_order_cancellation(
    domain=order_domain,
    order_uid=order_uid,
    owner=account,
    scheme=SigningScheme.EIP712
)

print(f"Cancellation signature: {cancellation_sig.to_string()}")

sign_order_cancellations

Sign cancellations for multiple orders at once.
def sign_order_cancellations(
    domain: TypedDataDomain,
    order_uids: List[Union[str, bytes]],
    owner: LocalAccount,
    scheme: SigningScheme,
) -> EcdsaSignature
domain
TypedDataDomain
required
The EIP-712 domain
order_uids
List[Union[str, bytes]]
required
List of order UIDs to cancel
owner
LocalAccount
required
The account that owns the orders
scheme
SigningScheme
required
The signing scheme
Returns: Signature for the batch cancellation Example:
from cowdao_cowpy.contracts.sign import sign_order_cancellations

# Cancel multiple orders
order_uids_to_cancel = [order_uid_1, order_uid_2, order_uid_3]

cancellation_sig = sign_order_cancellations(
    domain=order_domain,
    order_uids=order_uids_to_cancel,
    owner=account,
    scheme=SigningScheme.EIP712
)

Complete Example: Create and Sign Order

import time
from eth_account import Account
from web3 import Web3
from cowdao_cowpy.contracts.order import Order, compute_order_uid
from cowdao_cowpy.contracts.sign import sign_order, SigningScheme
from cowdao_cowpy.contracts.domain import domain
from cowdao_cowpy.common.chains import Chain
from cowdao_cowpy.common.constants import CowContractAddress
from cowdao_cowpy.app_data.utils import DEFAULT_APP_DATA_HASH

# Setup
private_key = "your_private_key"
account = Account.from_key(private_key)

# Token addresses
USDC = Web3.to_checksum_address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
WETH = Web3.to_checksum_address("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")

# Create domain
order_domain = domain(
    chain=Chain.MAINNET,
    verifying_contract=CowContractAddress.SETTLEMENT_CONTRACT.value
)

# Create order
order = Order(
    sell_token=USDC,
    buy_token=WETH,
    receiver=account.address,
    sell_amount="1000000000",  # 1000 USDC
    buy_amount="500000000000000000",  # 0.5 WETH minimum
    valid_to=int(time.time()) + 3600,  # Valid for 1 hour
    app_data=DEFAULT_APP_DATA_HASH,
    fee_amount="0",
    kind="sell",
    partially_fillable=False,
)

# Sign order
signature = sign_order(
    domain=order_domain,
    order=order,
    owner=account,
    scheme=SigningScheme.EIP712
)

# Compute UID
order_uid = compute_order_uid(order_domain, order, account.address)

print(f"Order UID: {order_uid}")
print(f"Signature: {signature.to_string()}")
print(f"Signing scheme: {signature.scheme.name}")

# Now you can submit this order to the OrderBookApi

Build docs developers (and LLMs) love