Skip to content

Conversation

@data-cowwboy
Copy link
Contributor

@data-cowwboy data-cowwboy commented Jan 22, 2026

Adds a new tutorial explaining the complete flow from getting a quote to placing an order, with emphasis on properly applying slippage tolerance.

Changes

  • New tutorial: docs/cow-protocol/tutorials/quote-to-order.mdx
  • Updated API integration docs

Summary

  • Explains quote → slippage → sign → submit flow
  • Provides TypeScript examples using @cowprotocol/contracts
  • Documents the basis points formula for sell/buy order slippage
  • Common integration pattern for partners

Summary by CodeRabbit

  • Documentation
    • Updated API integration guide with improved examples demonstrating quote handling and slippage management in the signing workflow.
    • Added new comprehensive tutorial covering the end-to-end process from obtaining quotes through order signing and submission, including both sell and buy order scenarios with detailed implementation guidance.

✏️ Tip: You can customize this high-level summary in your review settings.

@data-cowwboy data-cowwboy requested a review from a team as a code owner January 22, 2026 21:59
@vercel
Copy link

vercel bot commented Jan 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview Jan 22, 2026 10:00pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

Updated API integration documentation to introduce slippage handling and revised signing workflow. Modified existing quick start example with new token addresses and expanded quote-to-order process details. Added comprehensive tutorial documenting the end-to-end flow for converting quotes to orders with EIP-712 signing and API submission.

Changes

Cohort / File(s) Summary
API Integration Documentation
docs/cow-protocol/integrate/api.mdx
Updated Quick Start example with different token addresses and larger amounts. Revised "Sign and Submit Order" section to "Apply Slippage and Sign Order" with caution block. Added slippage computation for buyAmount, EIP-712 domain generation, order signing with signer, and adjusted API payload structure to include signature and signingScheme as strings. Expanded Resources and Next Steps sections with links to Quote to Order Tutorial and Order Signing Guide.
Quote-to-Order Tutorial
docs/cow-protocol/tutorials/quote-to-order.mdx
New comprehensive tutorial documenting end-to-end quote-to-order conversion. Covers quote retrieval, slippage tolerance application for sell/buy scenarios, EIP-712 signing, and order submission. Includes detailed formulas for slippage adjustments, TypeScript code examples with BigInt-based math, error handling patterns, and reference table for slippage impact.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • alfetopito
  • pretf00d

Poem

🐰 A quote hops into the garden, seeking order,
Slippage whispers gently at the border,
EIP-712 signs with a cryptic flourish,
API endpoints receive what we nourish,
From quote to order, the journey complete! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding a quote-to-order tutorial with slippage guidance, which aligns with the primary modifications in the changeset.
Description check ✅ Passed The description provides context about the changes and includes a Changes section listing the modified files. However, it lacks the structured format specified in the template with a more detailed breakdown of all changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@docs/cow-protocol/tutorials/quote-to-order.mdx`:
- Around line 222-244: The payload is sending signature.data but signOrder
returns a hex string; update the API body to send the signature string itself by
replacing signature: signature.data with signature: signature (reference the
signOrder call and the signature variable used when building the fetch body) so
the POST uses the raw ECDSA signature string expected by the API.
🧹 Nitpick comments (2)
docs/cow-protocol/tutorials/quote-to-order.mdx (1)

206-219: Avoid hard‑coding ERC20 balances in the order object.

If a partner requests non‑ERC20 balances in the quote, hard‑coding OrderBalance.ERC20 will make the signed order diverge from the quote. Either propagate the balances from the quote or explicitly call out that this example assumes ERC20 balances only.

docs/cow-protocol/integrate/api.mdx (1)

51-58: Prefer basis‑points constants over magic numbers for slippage.

Using 995/1000 works, but it’s harder to generalize and less consistent with the tutorial’s BPS explanation. Consider defining SLIPPAGE_BPS and BPS_DENOMINATOR here as well.

♻️ Suggested tweak
-// For sell orders: reduce buyAmount by slippage (e.g., 0.5%)
-const buyAmountWithSlippage = BigInt(quoteResponse.quote.buyAmount) * 995n / 1000n
+// For sell orders: reduce buyAmount by slippage (e.g., 0.5%)
+const SLIPPAGE_BPS = 50n
+const BPS_DENOMINATOR = 10_000n
+const buyAmountWithSlippage =
+  (BigInt(quoteResponse.quote.buyAmount) * (BPS_DENOMINATOR - SLIPPAGE_BPS)) /
+  BPS_DENOMINATOR

Comment on lines +222 to +244
const orderDomain = domain(chainId, settlementContract);
const signature = await signOrder(orderDomain, order, signer, SigningScheme.EIP712);

// 4. Submit the signed order to the API
const response = await fetch('https://api.cow.fi/mainnet/api/v1/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sellToken: order.sellToken,
buyToken: order.buyToken,
receiver: order.receiver,
sellAmount: order.sellAmount,
buyAmount: order.buyAmount,
validTo: order.validTo,
appData: order.appData,
feeAmount: order.feeAmount,
kind: quoteResponse.quote.kind, // API expects string: "sell" or "buy"
partiallyFillable: order.partiallyFillable,
sellTokenBalance: 'erc20', // API expects string
buyTokenBalance: 'erc20', // API expects string
signature: signature.data,
signingScheme: 'eip712',
from: quoteResponse.from
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

@cowprotocol/contracts signOrder function return type signature shape

💡 Result:

The signOrder function (in @cowprotocol/contracts) returns a Signature type — which is either:

  • an EcdsaSignature: a 65-byte hex string (0x r||s||v), or
  • a PreSignature: an empty-signature bytes string for presign. (docs.cow.fi)

(When used via the SDK OrderSigningUtils, the SDK wraps that into a SigningResult: { signature: string, signingScheme: EcdsaSigningScheme }.) (app.unpkg.com)

Citations:


🌐 Web query:

CoW Protocol API orders endpoint signature submission format

💡 Result:

Summary — how to submit a signed order to CoW Protocol /api/v1/orders

  • Endpoint: POST https://api.cow.fi/{network}/api/v1/orders. Body: JSON containing the signed order object (the quote/order fields plus signature and signingScheme). [1]

  • Required top-level fields (common): sellToken, buyToken, sellAmountBeforeFee / buyAmount, kind (sell|buy), from, receiver (opt), appData, validTo, feeAmount, signingScheme, signature (bytes hex). Use the full quote/order struct returned by the quote endpoint and add the signing result. Example submission from docs: body = JSON.stringify({ ...quoteResponse, signature: "<0x...>", signingScheme: "eip712" }). [1][2]

  • signingScheme values and signature expectations:

    • "eth_sign" — EOA eth_sign of order digest (standard prefixed message ECDSA). signature = ECDSA bytes. [2]
    • "eip712" (or "EIP-712") — typed-data (recommended). signature = ECDSA bytes of EIP‑712 digest. [2]
    • "erc1271" — for smart-contract wallets: signature is contract-specific bytes; set from field to the contract address. [2]
    • "presign" (PreSign) — on-chain presign; signature must be empty bytes "0x" and the order must be pre-signed on-chain via setPreSignature. [2]
  • Minimal JSON example:
    {
    "sellToken":"0x...","buyToken":"0x...","sellAmountBeforeFee":"1000000000000000000",
    "kind":"sell","from":"0xYourAddr","receiver":"0xYourAddr",
    "validTo":1700000000,"appData":"0x...","feeAmount":"0",
    "signingScheme":"eip712",
    "signature":"0x98ac143a... (ECDSA signature)"
    }
    (Submit with Content-Type: application/json). [1][2]

Sources: CoW docs — API integration / order submission and signing-schemes. [1] [2]

References
[1] CoW Protocol — API Integration / Order Book API (POST /api/v1/orders).
[2] CoW Protocol — Signing schemes (eth_sign, EIP‑712, ERC‑1271, PreSign).


🌐 Web query:

signOrder method @cowprotocol/contracts documentation

💡 Result:

The @cowprotocol/contracts package exposes a signOrder helper to EIP‑712 / eth_sign order signing. Usage (TypeScript):

  • Signature: signOrder(domain, order, signer, signingScheme) → Signature (encoded ECDSA signature + signing scheme). [example in SDK wrapper and mapping]. [1][2]

  • Related helpers: hashOrder, domain, packOrderUidParams, signOrderCancellation, etc.; see the CoW Protocol signing docs for the EIP‑712 types and examples. [1][3]

Sources:

  • CoW Protocol signing docs (hashOrder / domain examples). [1]
  • SDK / package references showing signOrder mapping and usage (unpkg / SDK code). [2]
  • @cowprotocol/contracts repository / package (package & repo). [3]

Remove .data access from signature submission.

The signOrder function returns a hex string (ECDSA signature), not an object with a .data property. The signature should be submitted directly: use signature instead of signature.data in the API payload.

Current (incorrect) code
signature: signature.data,

Correct form:

signature: signature,
🤖 Prompt for AI Agents
In `@docs/cow-protocol/tutorials/quote-to-order.mdx` around lines 222 - 244, The
payload is sending signature.data but signOrder returns a hex string; update the
API body to send the signature string itself by replacing signature:
signature.data with signature: signature (reference the signOrder call and the
signature variable used when building the fetch body) so the POST uses the raw
ECDSA signature string expected by the API.


# From Quote to Order: Applying Slippage

This tutorial explains how to use the CoW Protocol API to get a quote, apply slippage tolerance, and place an order. This is the most common integration pattern for partners building on CoW Protocol.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This tutorial explains how to use the CoW Protocol API to get a quote, apply slippage tolerance, and place an order. This is the most common integration pattern for partners building on CoW Protocol.
This tutorial explains how to use the CoW Protocol API to get a quote, apply slippage tolerance, and place an order.

This tutorial explains how to use the CoW Protocol API to get a quote, apply slippage tolerance, and place an order. This is the most common integration pattern for partners building on CoW Protocol.

:::caution Important
The quote response provides an **estimated** price. You should **not** sign and submit it directly. You must apply your desired slippage tolerance before signing the order.
Copy link
Contributor

@harisang harisang Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The quote response provides an **estimated** price. You should **not** sign and submit it directly. You must apply your desired slippage tolerance before signing the order.
The quote response provides an **estimated** price and does not incorporate any slippage tolerance. Because of this, you should **not** sign and submit it directly, unless you want to submit an order with zero slippage tolerance.

"verified": true
}
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add some explanation here about the decomposition of sellAmountBeforeFee in the request as

sellAmount + feeAmount

in the response.

And what this feeAmount means. And we should stress this fee is just an estimation, and is not used for signing, i.e., what the user will end up signing is always a fee=0 order, which means that the fee needs to be added back to the sellAmount

- Quote `sellAmount`: `294554318` (≈294.55 USDC)
- Slippage: 50 bps (0.5%)
- Calculation: `294554318 × (10000 + 50) / 10000 = 296027089`
- Actual `sellAmount`: `296027089`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. for buy orders, as i mentioned in the comment above, you need to add back the feeAmount returned in the quote response. And there are 2 ways of doing it:

  1. Either you do the slippage tolerance as you did it above and then add back the feeAmount, or
  2. First add back the feeAmount and then apply the slippage tolerance.

I would suggest we go with the (2) to give a bit more room to the limit price

- Calculation: `294554318 × (10000 + 50) / 10000 = 296027089`
- Actual `sellAmount`: `296027089`

This means you're willing to pay at most ~296.03 USDC instead of the quoted ~294.55 USDC.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs fixing


After applying slippage, create the order object with the adjusted amounts and sign it.

### TypeScript Example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wouldn't really add script/code here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants