feat(sdk-agnostic-lib): refactor tutorials for new SDK monorepo with provider adapters#45
feat(sdk-agnostic-lib): refactor tutorials for new SDK monorepo with provider adapters#45jeffersonBastos wants to merge 20 commits into
Conversation
WalkthroughAdded and updated many tutorial files: new umbrella SDK and adapter documentation, metadata and tsconfig files, example code switching to a global EthersV5Adapter and new @cowprotocol/cow-sdk APIs (including CowSdk), adjusted app-data APIs to Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UserApp
participant Web3Provider
participant Adapter as EthersV5Adapter
participant Global as GlobalAdapterRegistry
participant CowSdk
participant OrderBook
participant Metadata
UserApp->>Web3Provider: request signer & chainId
Web3Provider-->>UserApp: signer, chainId
UserApp->>Adapter: new Adapter(provider, signer)
Adapter-->>UserApp: adapterInstance
UserApp->>Global: setGlobalAdapter(adapterInstance)
Global-->>UserApp: adapter registered
UserApp->>CowSdk: init(adapter, chainId, env)
CowSdk-->>OrderBook: expose orderBook module
CowSdk-->>Metadata: expose metadataApi module
UserApp->>Metadata: generate app data -> getAppDataInfo()
Metadata-->>UserApp: { cid, appDataHex, appDataContent }
UserApp->>OrderBook: getQuote(appData, appDataHash)
OrderBook-->>UserApp: quote
UserApp->>CowSdk: orderSigning.signOrder(quote, signer)
CowSdk-->>UserApp: signature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20-30 minutes
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 23
🔭 Outside diff range comments (5)
content/tutorial/02-advanced-orders/01-eth-flow/03-cancel-eth-flow/app-a/src/lib/run.ts (1)
14-15: Use hex chainId with wallet_switchEthereumChain and handle chain-not-added (4902).EIP-3326 expects
chainIdas a hex string (e.g.,'0x64'for Gnosis). Passing100can fail on many wallets. Add a fallback towallet_addEthereumChainfor error 4902.- await provider.send('wallet_switchEthereumChain', [{ chainId: 100 }]); + const gnosisChainIdHex = '0x' + SupportedChainId.GNOSIS_CHAIN.toString(16); // 0x64 + try { + await provider.send('wallet_switchEthereumChain', [{ chainId: gnosisChainIdHex }]); + } catch (err: any) { + const code = err?.code ?? err?.data?.originalError?.code; + if (code === 4902) { + await provider.send('wallet_addEthereumChain', [{ + chainId: gnosisChainIdHex, + chainName: 'Gnosis', + nativeCurrency: { name: 'xDAI', symbol: 'xDAI', decimals: 18 }, + rpcUrls: ['https://rpc.gnosischain.com/'], + blockExplorerUrls: ['https://gnosisscan.io'] + }]); + } else { + throw err; + } + }content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (1)
49-53: Fix parameters for signOrderCancellations.The object literal
{ [orderUid], chainId, signer }is invalid. The API expectsorderUidsto be an array.Use:
- const orderCancellationsSigningResult = await OrderSigningUtils.signOrderCancellations({ - [orderUid], - chainId, - signer - }); + const orderCancellationsSigningResult = await OrderSigningUtils.signOrderCancellations({ + orderUids: [orderUid], + chainId, + signer, + });content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-b/src/lib/run.ts (2)
31-36:chainIdbecomes stale afterwallet_switchEthereumChain– leads to wrong addressesAfter requesting the chain switch you still use the old
chainIdwhen:
- instantiating
OrderBookApi- indexing
COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS- selecting the Safe TX service URL.
Re-read the chainId or hard-set it after the switch.
- if (chainId !== SupportedChainId.GNOSIS_CHAIN) { - await provider.send('wallet_switchEthereumChain', [{ chainId: SupportedChainId.GNOSIS_CHAIN }]); - } + if (chainId !== SupportedChainId.GNOSIS_CHAIN) { + await provider.send('wallet_switchEthereumChain', [{ chainId: SupportedChainId.GNOSIS_CHAIN }]); + chainId = SupportedChainId.GNOSIS_CHAIN; + }
107-110:new Contract(address, abi)needs a provider or signerWithout passing
provider/signer, the contract instance can’t perform calls. Use the signer fromsetupAdapteror the provider:- const settlementContract = new Contract(COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], abi) + const settlementContract = new Contract( + COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], + abi, + provider // or signer + )content/tutorial/02-advanced-orders/03-pre-signed-orders/03-cancel-pre-signed-order/app-a/src/lib/run.ts (1)
104-104: Pass a signer or provider toContractWithout the third argument
ethers.Contractcan’t send transactions.- const settlementContract = new Contract(COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], abi) + const settlementContract = new Contract( + COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], + abi, + signer + )
🧹 Nitpick comments (56)
content/tutorial/03-umbrella-sdk/02-individual-packages/meta.json (1)
3-6: Align scope prefix/name for clarity
prefixtargets/src/lib/whilenameissrc. To avoid confusion in the UI, broaden the prefix to cover the entiresrctree.Apply:
"scope": { - "prefix": "/src/lib/", - "name": "src" + "prefix": "/src/", + "name": "src" },content/tutorial/00-setup/tsconfig.json (1)
4-9: Wildcard path mapping may mask local modules.Redirecting every import to
../common/node_modules/*can inadvertently hide typos or local module resolutions. Consider narrowing the pattern or adding"paths"only for the specific shared packages you intend to hoist.content/tutorial/00-setup/00-getting-started/app-a/src/lib/run.ts (1)
3-6: Implement or clarify placeholderrunlogic.
runnow returns{}typed asunknown, which provides no instructional value and can hide type-checking errors. Either:
- Change the return type to
voiduntil real logic is added, or- Flesh out a minimal example (e.g., echo provider network) so readers see a working snippet.
content/tutorial/01-simple-orders/01-order/01-approve-sell-token-order/app-a/src/lib/run.ts (1)
3-6: Make the run() return type explicit (avoid Promise).Returning an empty object is fine as a placeholder, but the
unknownreturn type is ambiguous. Prefer a concrete type alias orvoidfor clarity and consistency.Apply one of the following:
Option A: Keep the empty object but type it:
export async function run(provider: Web3Provider): Promise<unknown> { // TODO: Implement - return {} + type RunResult = Record<string, never> + return {} as RunResult }Option B: Return nothing (void):
-export async function run(provider: Web3Provider): Promise<unknown> { +export async function run(provider: Web3Provider): Promise<void> { // TODO: Implement - return {} + return }content/tutorial/02-advanced-orders/01-eth-flow/03-cancel-eth-flow/app-a/src/lib/run.ts (1)
29-31: Prefer a concrete result type or Promise over returning{}.For tutorial consistency, either:
- Keep
Promise<void>and return nothing, or- Define a
RunResulttype with the fields you intend to surface later.-export async function run(provider: Web3Provider): Promise<unknown> { +export async function run(provider: Web3Provider): Promise<void> { ... - return {} + return }content/tutorial/01-simple-orders/01-order/02-quote-order/app-a/src/lib/run.ts (2)
4-4: Clarify next step in TODO (quote order).Consider specifying the intended implementation here (e.g., instantiate OrderBookApi and call quote endpoint) to guide readers. I can draft it when you’re ready.
5-5: Narrow the return type for consistency.Returning
{}is fine as a placeholder, but defining an explicit result type improves tutorial clarity and future refactors.Apply this small refactor:
-import type { Web3Provider } from '@ethersproject/providers' +import type { Web3Provider } from '@ethersproject/providers' + +type RunResult = Record<string, never>; -export async function run(provider: Web3Provider): Promise<unknown> { +export async function run(provider: Web3Provider): Promise<RunResult> { // TODO: Implement return {} }content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (2)
44-44: Remove stray diff markers from code snippet.The
+++ ... +++around the import will confuse readers and break copy/paste.Use this corrected line in the snippet:
-+++import { SupportedChainId, OrderBookApi, OrderSigningUtils } from '@cowprotocol/cow-sdk';+++ +import { SupportedChainId, OrderBookApi, OrderSigningUtils } from '@cowprotocol/cow-sdk';
13-16: Add adapter setup to match the new SDK pattern.You mention configuring the signer, but with provider adapters now standard, show setting the global adapter for coherence with the rest of the tutorials.
Consider adding a short snippet prior to usage:
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'; import { EthersV5Adapter } from '@cowprotocol/sdk-ethers-v5-adapter'; // ... const signer = provider.getSigner(); const adapter = new EthersV5Adapter({ provider, signer }); setGlobalAdapter(adapter);content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/app-b/src/lib/run.ts (1)
29-37: Make log parsing resilient to unrelated events.
iface.parseLog(log)throws if the log’s topics don’t match any ABI event. Wrap in try/catch to skip safely.- const ethFlowOrderUids: string[] = receipt.logs.reduce((orderIds, log) => { + const ethFlowOrderUids: string[] = receipt.logs.reduce((orderIds, log) => { if (log.address !== ethFlowAddress) { return orderIds; } - const parsedLog = iface.parseLog(log); - if (parsedLog.name === 'OrderPlacement') { - const [, order, ,] = parsedLog.args; - - orderIds.push(ethFlowOrderUid(order)); - } + try { + const parsedLog = iface.parseLog(log); + if (parsedLog.name === 'OrderPlacement') { + const [, order] = parsedLog.args; + orderIds.push(ethFlowOrderUid(order)); + } + } catch { + // Skip logs not in the ABI + } return orderIds; }, []);content/tutorial/01-simple-orders/02-app-data/04-view-app-data/app-b/src/lib/run.ts (1)
4-4: Provider param is unused.Either remove the provider argument from run() or use it (e.g., derive chainId dynamically for consistency with other steps).
content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/app-a/src/lib/run.ts (1)
12-13: Remove or defer unused variables until implementation.iface and ethFlowAddress are currently unused. Trim to reduce noise until the TODO is implemented.
- const ethFlowAddress = '0x40A50cf069e992AA4536211B23F286eF88752187'; - const iface = new utils.Interface(abi); + // const ethFlowAddress = '0x40A50cf069e992AA4536211B23F286eF88752187'; + // const iface = new utils.Interface(abi);content/tutorial/00-setup/01-provider-adapters/app-b/src/lib/run.ts (1)
2-2: Fix import spacing for consistency.Minor style nit to align with the rest of the repo.
-import { setGlobalAdapter , getGlobalAdapter} from '@cowprotocol/cow-sdk' +import { setGlobalAdapter, getGlobalAdapter } from '@cowprotocol/cow-sdk'content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-a/src/lib/run.ts (3)
12-15: Prefer explicit hex-to-int parsing for chainId instead of unary plusUsing unary plus on the result of
eth_chainIdrelies on implicit coercion. Be explicit and robust to both hex string and numeric responses.- const chainId = +(await provider.send('eth_chainId', [])); + const chainIdHex = await provider.send('eth_chainId', []); + const chainId = typeof chainIdHex === 'string' ? parseInt(chainIdHex, 16) : chainIdHex;
2-9: If you plan to use OrderSigningUtils (or any global adapter consumer), set the global adapterSeveral tutorials in this PR set a global adapter for utilities that read it implicitly. If that’s the intended pattern here, add
setGlobalAdapter(adapter)after constructing the adapter.import { OrderBookApi, MetadataApi, OrderSigningUtils, SupportedChainId, - OrderQuoteSideKindSell + OrderQuoteSideKindSell, + setGlobalAdapter } from '@cowprotocol/cow-sdk'; @@ const signer = provider.getSigner(); const adapter = new EthersV5Adapter({ provider, signer }); +setGlobalAdapter(adapter);If instead you’ll instantiate utilities with the adapter directly (no global state), feel free to ignore this.
Also applies to: 17-23
24-29: Complete the workflow or reference the implemented exampleThis file is a scaffold. Consider either:
- Implementing the steps (get app data via
MetadataApi, request quote viaOrderBookApi, sign withOrderSigningUtils), or- Linking to the completed “app-b” variant so readers know where to see the full flow.
I can mirror the “app-b” flow here once you confirm whether to use global or per-instance utilities.
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-a/src/lib/run.ts (2)
5-8: Parse chainId explicitly from hexBe explicit when converting
eth_chainIdto a number to avoid implicit coercion pitfalls.- const chainId = +(await provider.send('eth_chainId', [])); + const chainIdHex = await provider.send('eth_chainId', []); + const chainId = typeof chainIdHex === 'string' ? parseInt(chainIdHex, 16) : chainIdHex;
10-13: Initialize OrderBookApi so the example actually demonstrates basic usageInstantiate the API now; you can keep the method calls as follow-ups if you prefer.
- // TODO: Initialize OrderBookApi individually - // TODO: Test basic functionality + // Initialize OrderBookApi individually + const orderBookApi = new OrderBookApi({ chainId }); + // TODO: Use orderBookApi (e.g., fetch an order by UID) and return a meaningful resultIf you want, I can add a minimal call (e.g., get an order by UID) consistent with other examples in this tutorial section.
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/app-b/src/lib/run.ts (2)
6-9: Use explicit hex-to-int parsing for chainIdSame note as other files—be explicit when converting
eth_chainId.- const chainId = +(await provider.send('eth_chainId', [])); + const chainIdHex = await provider.send('eth_chainId', []); + const chainId = typeof chainIdHex === 'string' ? parseInt(chainIdHex, 16) : chainIdHex;
29-31: Optionally guard the order fetch for a better tutorial UXWrap the fetch with try/catch to avoid unhandled rejections in the UI if the UID is invalid or the network is down.
- const order = await cowSdk.orderBook.getOrder(testOrderUid); - return { order }; + try { + const order = await cowSdk.orderBook.getOrder(testOrderUid); + return { order }; + } catch (e) { + return { error: `Failed to fetch order: ${(e as Error).message}` }; + }content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/README.md (2)
73-75: Handle the case where getTransactionReceipt returns nullOn ethers v5,
getTransactionReceiptcan returnnullif the tx is not yet mined or unknown. Add a guard to make the tutorial more robust.- const receipt = await provider.getTransactionReceipt(txHash); + const receipt = await provider.getTransactionReceipt(txHash); + if (!receipt) { + throw new Error('Transaction receipt not found. Ensure the txHash is valid on the connected chain and the tx is mined.'); + }
89-96: Make log filtering and arg access more robust
- Compare addresses using checksum-normalized values to avoid case mismatches.
- Prefer named args when available to avoid brittle positional destructuring.
- if (log.address !== ethFlowAddress) { + if (utils.getAddress(log.address) !== utils.getAddress(ethFlowAddress)) { return orderIds; } const parsedLog = iface.parseLog(log); if (parsedLog.name === 'OrderPlacement') { - const [, order, ,] = parsedLog.args; + const order = (parsedLog.args.order ?? parsedLog.args[1]) as any; orderIds.push(ethFlowOrderUid(order)); } return orderIds;Also applies to: 98-102
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-a/src/lib/run.ts (1)
6-9: ClarifychainIdconversion
provider.send('eth_chainId', [])returns a hex string (e.g."0x64").
Unary+works but relies on implicit radix detection;parseInt(hex, 16)is clearer and immune to edge-case surprises in strict lint setups.-const chainId = +(await provider.send('eth_chainId', [])); +const chainIdHex = await provider.send('eth_chainId', []); +const chainId = parseInt(chainIdHex, 16);content/tutorial/01-simple-orders/01-order/03-sign-order/app-b/src/lib/run.ts (1)
14-19: Return value ofsetupAdapter
adapteris returned but never used by the caller; if future examples won’t need it, drop it from the return signature to keep the helper minimal.-return { signer, adapter }; +return { signer };(or use the adapter downstream)
content/tutorial/01-simple-orders/01-order/03-sign-order/app-a/src/lib/run.ts (1)
30-33: Optional: keep constants in one placeThe same hard-coded token addresses/sell amount appear across many tutorial files.
Extracting them into a shared constants module reduces duplication and risk of inconsistent edits later.content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md (1)
30-37: Missing import forEthersV5AdapterThe snippet uses
new EthersV5Adapterbut the import statement is absent. Add for copy-paste completeness:import { EthersV5Adapter } from '@cowprotocol/sdk-ethers-v5-adapter';content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md (1)
63-69: Order of operations in example
chainIdconstant is set after it’s needed to constructCowSdk(which also takeschainId). Moveconst chainId = SupportedChainId.GNOSIS_CHAIN;above the adapter creation for clearer flow.content/tutorial/01-simple-orders/01-order/04-submit-order/app-a/src/lib/run.ts (1)
21-61: Return the concrete signed-order type instead ofunknown
OrderSigningUtils.signOrder()returns aSignedOrder(or similar) – exposing that type here improves downstream type-safety and IDE support.-export async function run(provider: Web3Provider): Promise<unknown> { +export async function run(provider: Web3Provider): Promise<SignedOrder> {content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/app-b/src/lib/run.ts (1)
47-52: You computecidbut never use it
getAppDataInfo()now returns{ cid, … }yetcidis discarded. If the CID is meant to be surfaced to the UI or logged, please return or log it; otherwise remove it from the destructuring.content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-b/src/lib/run.ts (1)
54-57: Reuse the signer returned bysetupAdapterYou already obtain a signer via
setupAdapter. Callingprovider.getSigner()again is redundant and risks diverging signers if a different account is selected later.content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/app-a/src/lib/run.ts (2)
19-23: Initialise the adapter before creatingOrderBookApifor consistencyAs in other examples, move
setupAdapterabove the API construction; this guarantees the global adapter is always in place.- const orderBookApi = new OrderBookApi({ chainId: SupportedChainId.GNOSIS_CHAIN }); - const { signer } = setupAdapter(provider); + const { signer } = setupAdapter(provider); + const orderBookApi = new OrderBookApi({ chainId: SupportedChainId.GNOSIS_CHAIN });
21-24: Function currently does nothing – consider implementing or marking TODO
run()returns an empty object. If cancellation logic is planned add a TODO; otherwise the tutorial step might confuse readers.content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-a/src/lib/run.ts (2)
19-21: Unimplemented code pathA TODO comment is present and the function returns
{}. Either implement the sample or link to the next tutorial section to avoid dead-end code.
13-15: Expose explicit return type instead ofunknownEven if the body is TBD, declaring a concrete return type sets expectations for implementers.
content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/app-b/src/lib/run.ts (2)
10-16: Avoid resetting the global adapter on everyrun()call
setupAdapter()callssetGlobalAdapter()each time the tutorial is executed. If the playground re-invokesrun()(e.g. hot-reload, multiple components), the global singleton keeps being replaced, which may break stateful caches inside other SDK classes.-export function setupAdapter(provider: Web3Provider) { +let cachedAdapter: EthersV5Adapter | undefined; +export function setupAdapter(provider: Web3Provider) { const signer = provider.getSigner(); - const adapter = new EthersV5Adapter({ provider, signer }); - setGlobalAdapter(adapter); - return { signer, adapter }; + if (!cachedAdapter) { + cachedAdapter = new EthersV5Adapter({ provider, signer }); + setGlobalAdapter(cachedAdapter); + } + return { signer, adapter: cachedAdapter }; }
18-26: Narrow the return typeThe function returns either
{ cancellationsResult }or the error object. Prefer a discriminated union so callers can handle both cases safely.export async function run(provider: Web3Provider): Promise< | { kind: 'ok'; cancellationsResult: unknown } | { kind: 'error'; error: unknown } > { … }content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (2)
33-50: Code snippet is missingchainIddefinition
new OrderBookApi({ chainId })will not compile aschainIdis undefined in the snippet.-import type { Web3Provider } from '@ethersproject/providers'; +import type { Web3Provider } from '@ethersproject/providers'; + +const chainId = SupportedChainId.GNOSIS_CHAIN; // or derive from the provider
47-66: Adapter not made globally availableLater tutorials rely on
MetadataApipicking up the global adapter. Either callsetGlobalAdapter(adapter)here or mention that some packages (e.g.OrderSigningUtils) will require it.content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-b/src/lib/run.ts (2)
11-17: Consider registering the adapter globallyIf another SDK helper (e.g.
OrderSigningUtils) gets added later, it will look forgetGlobalAdapter(). A one-liner keeps future snippets consistent:import { setGlobalAdapter } from '@cowprotocol/cow-sdk'; … setGlobalAdapter(adapter);
43-47: Return the actual error for easier debuggingSwallowing the exception hides valuable info.
- } catch (error) { - return { - error: 'Test order not found, but packages initialized correctly' - }; + } catch (error) { + return { error }; }content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/README.md (1)
47-48: Strip+++diff markers from code blocksThe
+++prefixes are rendered literally and will cause copy-pasted code to fail.- +++appData: appDataContent,+++ - +++appDataHash: appDataHex,+++ + appData: appDataContent, + appDataHash: appDataHex, … - +++appData: appDataHex,+++ + appData: appDataHex,Also applies to: 67-68
content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/app-a/src/lib/run.ts (2)
11-17: Return type is implicit – please make it explicitExplicitly annotate the return type of
setupAdapter()(e.g.{ signer: JsonRpcSigner; adapter: EthersV5Adapter }) to help IDEs and future readers.
30-31: TODO left in production tutorial code
// TODO: Generate app data document and upload to APIplus returning an empty object leaves the example non-functional. Either implement the missing logic or add a short note explaining that the snippet is intentionally partial.content/tutorial/01-simple-orders/01-order/03-sign-order/README.md (1)
39-50:sellAmountused but never defined in snippetThe code builds an
UnsignedOrderwithsellAmount, yet the snippet never assigns that variable (only a comment above mentions it). Add the definition to avoid copy-paste confusion.content/tutorial/01-simple-orders/02-app-data/04-view-app-data/README.md (2)
16-20:providerparameter is unusedThe
run(provider: Web3Provider)signature suggests the function needs a provider, but the body doesn’t reference it. Either use the provider (e.g. for chain-ID validation) or drop the parameter to keep the example minimal.
77-90: Hard tabs trigger markdown-lint MD010Replace the leading tab characters in the JSON block with spaces to satisfy Markdown linters and keep formatting consistent.
content/tutorial/00-setup/01-provider-adapters/README.md (1)
1-160: Replace hard tabs with spaces across the file
markdownlintreports multiple MD010 violations. Converting indentation to spaces prevents lint noise and keeps style consistent with the rest of the docs.content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-b/src/lib/run.ts (1)
52-54: Unused variablecid
cidreturned fromgetAppDataInfo()is never referenced. If it’s intentionally ignored, prefix with_or remove it to avoid dead-code warnings.content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-b/src/lib/run.ts (1)
1-8:latestimport is unusedIf
noUnusedLocalsis enabled the build will fail.-import { … , latest, UnsignedOrder } from '@cowprotocol/cow-sdk'; +import { … , UnsignedOrder } from '@cowprotocol/cow-sdk';content/tutorial/02-advanced-orders/03-pre-signed-orders/03-cancel-pre-signed-order/app-a/src/lib/run.ts (1)
30-31: Hex string required forwallet_switchEthereumChainSame fix as suggested in the ETH-flow tutorial.
content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-a/src/lib/run.ts (1)
21-22: Switch network with hex id- await provider.send('wallet_switchEthereumChain', [{ chainId: SupportedChainId.GNOSIS_CHAIN }]); + await provider.send('wallet_switchEthereumChain', [{ chainId: '0x64' }]);content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (2)
13-16: Chain ID conversion works; consider ethers-native alternative
+await provider.send('eth_chainId')works with hex strings. Optionally preferconst { chainId } = await provider.getNetwork()for v5 providers to avoid raw RPC calls.
75-77: Harden error handling for unknown error typesIn some TS configs,
catch (error)isunknown. Safely serialize the error to avoiderror.messageaccess issues.- } catch (error) { - return { error: error.message }; - } + } catch (err) { + const message = + err instanceof Error + ? err.message + : typeof err === 'string' + ? err + : JSON.stringify(err); + return { error: message }; + }content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/README.md (1)
86-86: Replace hard tab in JSON example (MD010)Remove the hard tab in the JSON snippet to satisfy markdownlint.
content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/README.md (1)
79-79: Fix formatting: Replace hard tabs with spaces.The markdown content uses hard tabs instead of spaces for indentation, which violates markdown formatting standards.
Apply consistent spacing instead of hard tabs for proper markdown formatting.
Also applies to: 106-109, 168-184
content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/README.md (1)
21-21: Fix formatting: Replace hard tabs with spaces.Similar to the previous file, hard tabs should be replaced with spaces for proper markdown formatting.
Apply consistent spacing throughout the markdown content.
Also applies to: 49-53
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
content/tutorial/common/yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (59)
content/tutorial/00-setup/00-getting-started/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/01-provider-adapters/README.md(1 hunks)content/tutorial/00-setup/01-provider-adapters/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/01-provider-adapters/app-b/src/lib/run.ts(1 hunks)content/tutorial/00-setup/01-provider-adapters/meta.json(1 hunks)content/tutorial/00-setup/meta.json(1 hunks)content/tutorial/00-setup/tsconfig.json(1 hunks)content/tutorial/01-simple-orders/01-order/01-approve-sell-token-order/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/02-quote-order/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/03-sign-order/README.md(4 hunks)content/tutorial/01-simple-orders/01-order/03-sign-order/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/03-sign-order/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/04-submit-order/README.md(2 hunks)content/tutorial/01-simple-orders/01-order/04-submit-order/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/04-submit-order/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md(3 hunks)content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/README.md(4 hunks)content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/README.md(2 hunks)content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/README.md(2 hunks)content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/04-view-app-data/README.md(2 hunks)content/tutorial/01-simple-orders/02-app-data/04-view-app-data/app-a/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/02-app-data/04-view-app-data/app-b/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/README.md(5 hunks)content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/app-a/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/app-b/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/README.md(2 hunks)content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/app-a/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/02-view-eth-flow/app-b/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/03-cancel-eth-flow/app-a/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/01-eth-flow/03-cancel-eth-flow/app-b/src/lib/run.ts(1 hunks)content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/README.md(13 hunks)content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-a/src/lib/run.ts(2 hunks)content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-b/src/lib/run.ts(5 hunks)content/tutorial/02-advanced-orders/03-pre-signed-orders/03-cancel-pre-signed-order/app-a/src/lib/run.ts(5 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/app-a/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/app-b/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-a/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-b/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/meta.json(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-a/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-b/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-a/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/meta.json(1 hunks)content/tutorial/03-umbrella-sdk/meta.json(1 hunks)content/tutorial/03-umbrella-sdk/tsconfig.json(1 hunks)content/tutorial/common/package.json(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md
79-79: Hard tabs
Column: 1
(MD010, no-hard-tabs)
80-80: Hard tabs
Column: 1
(MD010, no-hard-tabs)
82-82: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/README.md
86-86: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md
16-16: Hard tabs
Column: 1
(MD010, no-hard-tabs)
17-17: Hard tabs
Column: 1
(MD010, no-hard-tabs)
18-18: Hard tabs
Column: 1
(MD010, no-hard-tabs)
19-19: Hard tabs
Column: 1
(MD010, no-hard-tabs)
20-20: Hard tabs
Column: 1
(MD010, no-hard-tabs)
21-21: Hard tabs
Column: 1
(MD010, no-hard-tabs)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
33-33: Hard tabs
Column: 1
(MD010, no-hard-tabs)
34-34: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
38-38: Hard tabs
Column: 1
(MD010, no-hard-tabs)
39-39: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1
(MD010, no-hard-tabs)
50-50: Hard tabs
Column: 1
(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1
(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1
(MD010, no-hard-tabs)
53-53: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/01-simple-orders/02-app-data/04-view-app-data/README.md
79-79: Hard tabs
Column: 1
(MD010, no-hard-tabs)
80-80: Hard tabs
Column: 1
(MD010, no-hard-tabs)
81-81: Hard tabs
Column: 1
(MD010, no-hard-tabs)
82-82: Hard tabs
Column: 1
(MD010, no-hard-tabs)
83-83: Hard tabs
Column: 1
(MD010, no-hard-tabs)
84-84: Hard tabs
Column: 1
(MD010, no-hard-tabs)
85-85: Hard tabs
Column: 1
(MD010, no-hard-tabs)
86-86: Hard tabs
Column: 1
(MD010, no-hard-tabs)
87-87: Hard tabs
Column: 1
(MD010, no-hard-tabs)
88-88: Hard tabs
Column: 1
(MD010, no-hard-tabs)
89-89: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/README.md
71-71: Hard tabs
Column: 1
(MD010, no-hard-tabs)
73-73: Hard tabs
Column: 1
(MD010, no-hard-tabs)
74-74: Hard tabs
Column: 1
(MD010, no-hard-tabs)
87-87: Hard tabs
Column: 1
(MD010, no-hard-tabs)
89-89: Hard tabs
Column: 1
(MD010, no-hard-tabs)
102-102: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/README.md
21-21: Hard tabs
Column: 1
(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1
(MD010, no-hard-tabs)
50-50: Hard tabs
Column: 1
(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1
(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1
(MD010, no-hard-tabs)
53-53: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/README.md
79-79: Hard tabs
Column: 1
(MD010, no-hard-tabs)
106-106: Hard tabs
Column: 1
(MD010, no-hard-tabs)
107-107: Hard tabs
Column: 1
(MD010, no-hard-tabs)
109-109: Hard tabs
Column: 1
(MD010, no-hard-tabs)
168-168: Hard tabs
Column: 1
(MD010, no-hard-tabs)
169-169: Hard tabs
Column: 1
(MD010, no-hard-tabs)
170-170: Hard tabs
Column: 1
(MD010, no-hard-tabs)
171-171: Hard tabs
Column: 1
(MD010, no-hard-tabs)
172-172: Hard tabs
Column: 1
(MD010, no-hard-tabs)
173-173: Hard tabs
Column: 1
(MD010, no-hard-tabs)
174-174: Hard tabs
Column: 1
(MD010, no-hard-tabs)
175-175: Hard tabs
Column: 1
(MD010, no-hard-tabs)
176-176: Hard tabs
Column: 1
(MD010, no-hard-tabs)
177-177: Hard tabs
Column: 1
(MD010, no-hard-tabs)
178-178: Hard tabs
Column: 1
(MD010, no-hard-tabs)
179-179: Hard tabs
Column: 1
(MD010, no-hard-tabs)
180-180: Hard tabs
Column: 1
(MD010, no-hard-tabs)
181-181: Hard tabs
Column: 1
(MD010, no-hard-tabs)
182-182: Hard tabs
Column: 1
(MD010, no-hard-tabs)
183-183: Hard tabs
Column: 1
(MD010, no-hard-tabs)
184-184: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🪛 Gitleaks (8.27.2)
content/tutorial/01-simple-orders/01-order/03-sign-order/app-b/src/lib/run.ts
32-32: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/01-simple-orders/01-order/03-sign-order/app-a/src/lib/run.ts
30-30: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
31-31: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-a/src/lib/run.ts
56-56: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
57-57: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-a/src/lib/run.ts
30-30: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
31-31: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts
41-41: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
42-42: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-b/src/lib/run.ts
56-56: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
57-57: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-b/src/lib/run.ts
30-30: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
31-31: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md
[grammar] ~17-~17: Ensure spelling is correct
Context: ...ustom rate limits, URLs, etc. ### 📋 MetadataApi Generates and processes app data: - *...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (38)
content/tutorial/00-setup/01-provider-adapters/meta.json (1)
1-8: Looks good – no issues found.content/tutorial/00-setup/meta.json (1)
1-8: Metadata OK.content/tutorial/02-advanced-orders/01-eth-flow/03-cancel-eth-flow/app-b/src/lib/run.ts (1)
54-55: Nit: whitespace fix acknowledged.content/tutorial/03-umbrella-sdk/meta.json (1)
1-8: LGTM: metadata structure is consistent.Title, scope, and focus keys look aligned with other tutorial entries.
content/tutorial/03-umbrella-sdk/01-unified-approach/meta.json (1)
1-8: LGTM: metadata structure is consistent.Matches the umbrella SDK conventions for scope and focus.
content/tutorial/01-simple-orders/01-order/03-sign-order/app-b/src/lib/run.ts (1)
32-35: False-positive “API key” warningsThe static-analysis hit is only an Ethereum token address, not a credential. Safe to ignore.
content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/app-b/src/lib/run.ts (1)
34-37:slippageBipsAPI expects a string – confirm the numeric literal compilesHistorically
latest.Quote.slippageBipsis typed asstring. Switching from'50'to50will break the build if the type definition hasn’t changed in the new SDK. Please re-check the type or convert withString(50).content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (1)
24-28: Minor wording“eye-ed” → “eyed”.
content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-a/src/lib/run.ts (1)
56-58: False positive from gitleaksThe flagged strings are plain ERC-20 token addresses, not secrets. Safe to keep.
content/tutorial/01-simple-orders/02-app-data/02-create-order-app-data/app-b/src/lib/run.ts (1)
56-57: Gitleaks false positive – addresses, not secretsThe detector flagged the token addresses as “Generic API Key”. They’re public ERC-20 addresses, safe to commit. No action needed.
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/app-b/src/lib/run.ts (1)
29-33: Gitleaks warning is a false positiveThe hard-coded token addresses are public ERC-20 contracts, not credentials. Safe to ignore the “generic-api-key” alert.
content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/app-a/src/lib/run.ts (1)
49-51:runcurrently returns an empty objectAdd a TODO or implement the remainder of the workflow; exporting an empty result is confusing for learners following the tutorial.
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (2)
37-49: Quote payload looks aligned with new appData API; sanity-check token addressesPassing
appData: appDataContentandappDataHash: appDataHexmatches the updated flow. Please verify the wxDAI and COW addresses for Gnosis are correct, and consider centralizing them as constants.Also, gitleaks flagged these lines as "Generic API Key" due to 0x-prefixed strings. If these are known token addresses, mark as false positives or add an allowlist rule in your gitleaks config to ignore 40-byte hex addresses that are not secrets.
60-61: Signing flow LGTMUsing
OrderSigningUtils.signOrder(order, chainId, signer)with the constructedUnsignedOrderis correct in this context.content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (2)
28-33: Unified SDK init example looks correct
CowSdkinitialized withEthersV5Adapter,SupportedChainId.GNOSIS_CHAIN, andenv: 'prod'matches the new umbrella SDK approach.
16-37: No hard tabs detected – no action requiredA search for literal
\tincontent/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.mdreturned no matches. The file already uses spaces exclusively, so the MD010 recommendation can be ignored.Likely an incorrect or invalid review comment.
content/tutorial/01-simple-orders/02-app-data/03-orderbook-upload-app-data/README.md (2)
16-36: Ensure “+++” inline markers are intended; otherwise they break TypeScript snippetsThe code block uses
+++prefixes within atypescriptfence. If the site renderer doesn’t support this highlighting syntax, readers will copy invalid TS. Prefer adiffcode block for highlighting or remove the markers.Example using diff:
```diff - import { OrderBookApi } from '@cowprotocol/...' + import { OrderBookApi, MetadataApi, latest, SupportedChainId, setGlobalAdapter } from '@cowprotocol/cow-sdk'; + import { EthersV5Adapter } from '@cowprotocol/sdk-ethers-v5-adapter';--- `40-49`: **New app data flow reads well and matches updated API** - Using `getAppDataInfo()` to obtain `{ cid, appDataHex, appDataContent }` is correct. - `uploadAppData(appDataHex, appDataContent)` returning the confirmed appData hash (`fullAppData`) is consistent with the new semantics. Also applies to: 63-67, 72-72 </details> <details> <summary>content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/app-b/src/lib/run.ts (2)</summary> `5-11`: **Global adapter setup is consistent and clear** `setupAdapter` with `EthersV5Adapter` and `setGlobalAdapter`, then `new MetadataApi()` without params aligns with the new global adapter pattern. Also applies to: 14-19 --- `24-26`: **Updated types and app data processing look correct** - `latest.Quote` with numeric `slippageBips: 50` and `latest.OrderClass` are consistent. - `getAppDataInfo` returning `{ cid, appDataHex, appDataContent }` matches the new API. Also applies to: 37-44 </details> <details> <summary>content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/README.md (3)</summary> `35-56`: **Good exposition of the global adapter pattern and updated MetadataApi usage** Examples clearly show: - Using umbrella package imports - Global adapter setup - Environment string as `'production'` - Transition to `getAppDataInfo` returning CID, hash, and content Also applies to: 72-91, 99-123, 133-154 --- `38-47`: **Confirm whether “+++” markers are needed in TS code fences** If not processed by your doc tooling, they will invalidate the snippet when copied. Prefer `diff` fences for highlighting or remove the markers. Also applies to: 75-77, 102-104, 136-138 --- `71-74`: **No hard tabs detected in README.md; markdownlint MD010 fix not required** I searched the entire `content/tutorial/01-simple-orders/02-app-data/01-simple-app-data/README.md` and found zero tab characters—there’s nothing to replace. You can ignore this suggestion. > Likely an incorrect or invalid review comment. </details> <details> <summary>content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/README.md (4)</summary> `29-38`: **LGTM: Consistent adapter setup pattern.** The `setupAdapter` helper function correctly initializes the EthersV5Adapter and sets it globally. This follows the established pattern across the SDK refactor. --- `100-109`: **LGTM: Comprehensive imports for EthFlow functionality.** The expanded imports include all necessary types and APIs for EthFlow order creation, properly using the consolidated `@cowprotocol/cow-sdk` package. --- `162-183`: **LGTM: Updated app data processing with new API.** The migration from `appDataToCid()` to `getAppDataInfo()` is correct and provides richer information including the CID alongside hex and content. --- `196-196`: **LGTM: Proper slippage calculation.** The slippage calculation using BigNumber arithmetic (0.5% = 9950/10000) is mathematically correct and safe for large numbers. </details> <details> <summary>content/tutorial/02-advanced-orders/03-pre-signed-orders/01-create-pre-signed-order/README.md (3)</summary> `55-61`: **LGTM: Consistent adapter setup implementation.** The adapter setup helper function matches the pattern used across other tutorials and correctly initializes the global adapter for MetadataApi usage. --- `268-289`: **LGTM: Proper app data processing update.** The migration to `getAppDataInfo()` is implemented correctly, providing the CID along with hex and content data for comprehensive app data handling. --- `362-364`: **LGTM: Correct PRESIGN order configuration.** The order fields are properly set for pre-signed orders: - `from` set to Safe address - `signature` set to empty bytes (`0x`) - `signingScheme` set to `SigningScheme.PRESIGN` </details> <details> <summary>content/tutorial/02-advanced-orders/01-eth-flow/01-create-eth-flow/app-b/src/lib/run.ts (8)</summary> `17-23`: **LGTM: Well-structured adapter setup.** The helper function properly encapsulates adapter initialization and global setup, returning both signer and adapter for flexibility. --- `25-30`: **LGTM: Proper EthFlowOrder type definition.** The type correctly omits fields not required for EthFlow orders and adds the `quoteId` field. The type definition accurately reflects the EthFlow contract requirements. --- `35-38`: **LGTM: Proper chain handling for Gnosis Chain.** The chain ID verification and automatic switching to Gnosis Chain ensures the tutorial runs on the correct network where the EthFlow contract is deployed. --- `58-58`: **LGTM: Updated app data API usage.** The migration to `getAppDataInfo()` with destructuring assignment is clean and provides the required `cid`, `appDataHex`, and `appDataContent` properties. --- `75-79`: **LGTM: Proper EthFlow quote configuration.** The additional fields (`from`, `signingScheme: EIP1271`, `onchainOrder: true`) are correctly set for EthFlow orders that require on-chain signing. --- `86-86`: **LGTM: Correct slippage calculation.** The 0.5% slippage calculation using BigNumber arithmetic (mul(9950).div(10000)) is mathematically sound and prevents precision loss. --- `92-92`: **LGTM: Proper ETH value transfer.** The contract call correctly includes `{ value: sellAmount }` to send ETH with the transaction, which is required for EthFlow orders. --- `45-45`: **LGTM: Standardized parameter type.** The change from `slippageBips: '50'` to `slippageBips: 50` (string to number) standardizes the parameter type across the SDK. </details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
|
@jeffersonBastos the build failed. Can you take a look?
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (8)
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md (3)
32-41: Quote params: ensure appData/appDataHash alignment and type imports
- After fixing Step 1,
appDataContentwill be defined; otherwise this snippet fails.- Confirm the quote API expects both
appData(content) andappDataHash(hex). If only one is required, remove the other to avoid confusion.- You reference
OrderQuoteSideKindSell.SELLbut no import is shown. Add the import or inline the string literal.- kind: OrderQuoteSideKindSell.SELL, + // import { OrderQuoteSideKindSell } from '@cowprotocol/cow-sdk' (if needed) + kind: OrderQuoteSideKindSell.SELL,Or:
- kind: OrderQuoteSideKindSell.SELL, + kind: 'sell',
82-87: Naming consistency: appDataHex vs appDataHash in outputYou return
{ appDataHash: appDataHex }. Prefer consistent naming to avoid confusion.-return { - appDataHash: appDataHex, +return { + appDataHex, expectedBuyAmount: quote.buyAmount, signature: signature.signature.substring(0, 20) + '...', signingScheme: signature.signingScheme };Or rename the variable earlier to
appDataHash.
88-90: Type-safe error handling in TS
errorcan be unknown. Narrow before reading.message.-} catch (error) { - return { error: error.message }; +} catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { error: message }; }content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (1)
69-77: Signing example clarity
signOrder(order, chainId, signer)assumesorderis an unsigned order. The preceding snippet showsgetOrder(orderUid)which returns an existing on-chain order, not an unsigned payload. Consider clarifying that the signed object must be anUnsignedOrderconstructed from a quote.Example:
// After obtaining a quote: // const order: UnsignedOrder = { ...quote, appData: appDataHex, ... } const signature = await cowSdk.orderSigning.signOrder(order, chainId, signer);content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts (4)
5-5: Return a strongly-typed result instead of Promise.Make the return type explicit to improve readability and caller ergonomics.
Update the signature only within the selected range:
-export async function run(provider: Web3Provider): Promise<unknown> { +export async function run(provider: Web3Provider): Promise<RunResult> {Add this type alias outside the selected range (e.g., below the imports):
type RunResult = { globalAdapter: EthersV5Adapter chainId: number address: string }Also applies to: 19-24
14-15: Fetch chainId and address concurrently.Minor optimization and slightly cleaner code.
- const chainId = await adapter.getChainId() - const address = await adapter.signer.getAddress() + const [chainId, address] = await Promise.all([ + adapter.getChainId(), + adapter.signer.getAddress(), + ])
13-16: Guard against locked wallets by requesting accounts before getAddress.Depending on the environment, getAddress may throw if the wallet isn’t connected. Proactively requesting accounts improves tutorial UX.
Insert before reading the address:
await provider.send('eth_requestAccounts', []).catch(() => { throw new Error('Please connect your wallet to continue') })If your tutorial flow guarantees a connected wallet earlier, you can skip this. Otherwise, adding it avoids common pitfalls during first run.
17-23: Avoid redundant getGlobalAdapter call (optional).You already hold adapter; unless you’re explicitly demonstrating getGlobalAdapter, you can return the local instance.
- const globalAdapter = getGlobalAdapter() - - return { - globalAdapter, + return { + globalAdapter: adapter, chainId, address, }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
content/tutorial/00-setup/00-getting-started/00-getting-started/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/README.md(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/meta.json(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/meta.json
- content/tutorial/00-setup/00-getting-started/00-getting-started/app-a/src/lib/run.ts
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md
24-24: Hard tabs
Column: 1
(MD010, no-hard-tabs)
25-25: Hard tabs
Column: 1
(MD010, no-hard-tabs)
27-27: Hard tabs
Column: 1
(MD010, no-hard-tabs)
28-28: Hard tabs
Column: 1
(MD010, no-hard-tabs)
29-29: Hard tabs
Column: 1
(MD010, no-hard-tabs)
30-30: Hard tabs
Column: 1
(MD010, no-hard-tabs)
31-31: Hard tabs
Column: 1
(MD010, no-hard-tabs)
32-32: Hard tabs
Column: 1
(MD010, no-hard-tabs)
34-34: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
90-90: Hard tabs
Column: 1
(MD010, no-hard-tabs)
91-91: Hard tabs
Column: 1
(MD010, no-hard-tabs)
92-92: Hard tabs
Column: 1
(MD010, no-hard-tabs)
93-93: Hard tabs
Column: 1
(MD010, no-hard-tabs)
94-94: Hard tabs
Column: 1
(MD010, no-hard-tabs)
95-95: Hard tabs
Column: 1
(MD010, no-hard-tabs)
96-96: Hard tabs
Column: 1
(MD010, no-hard-tabs)
content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md
16-16: Hard tabs
Column: 1
(MD010, no-hard-tabs)
17-17: Hard tabs
Column: 1
(MD010, no-hard-tabs)
18-18: Hard tabs
Column: 1
(MD010, no-hard-tabs)
19-19: Hard tabs
Column: 1
(MD010, no-hard-tabs)
20-20: Hard tabs
Column: 1
(MD010, no-hard-tabs)
21-21: Hard tabs
Column: 1
(MD010, no-hard-tabs)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
33-33: Hard tabs
Column: 1
(MD010, no-hard-tabs)
34-34: Hard tabs
Column: 1
(MD010, no-hard-tabs)
35-35: Hard tabs
Column: 1
(MD010, no-hard-tabs)
36-36: Hard tabs
Column: 1
(MD010, no-hard-tabs)
37-37: Hard tabs
Column: 1
(MD010, no-hard-tabs)
38-38: Hard tabs
Column: 1
(MD010, no-hard-tabs)
39-39: Hard tabs
Column: 1
(MD010, no-hard-tabs)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1
(MD010, no-hard-tabs)
50-50: Hard tabs
Column: 1
(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1
(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1
(MD010, no-hard-tabs)
53-53: Hard tabs
Column: 1
(MD010, no-hard-tabs)
107-107: Hard tabs
Column: 1
(MD010, no-hard-tabs)
108-108: Hard tabs
Column: 1
(MD010, no-hard-tabs)
109-109: Hard tabs
Column: 1
(MD010, no-hard-tabs)
110-110: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🪛 LanguageTool
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md
[grammar] ~17-~17: Ensure spelling is correct
Context: ...ustom rate limits, URLs, etc. ### 📋 MetadataApi Generates and processes app data: - *...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (4)
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (1)
21-22: Confirm adapter package and version alignmentEnsure
@cowprotocol/sdk-ethers-v5-adapterversion matches the umbrella@cowprotocol/cow-sdkversion expected by this tutorial to avoid peer-dependency mismatches in examples.content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (3)
84-90: Adapters example looks goodDemonstrates read-only vs signing adapters clearly and matches the individual-package approach.
98-110: Ensure the sample output matches the returned object shapeYour code originally returned
{ order, appDataDoc }while the sample output shows{ orderBook, metadata: { appDataHex } }. With the suggested changes above, the code will match the sample. If you prefer a different shape, update either the code or this example to stay consistent.
75-82: Env and GNOSIS baseUrl are correct; please verify backoffOpts keysWe’ve confirmed from the official docs that:
envaccepts only'prod'(production) or'staging'.- The GNOSIS_CHAIN production base URL remains
https://api.cow.fi/xdai(full endpoint at/xdai/api).Please double-check in the SDK’s type definitions that your
backoffOptsproperties—namelymaxDelayandnumOfAttempts—match the library’s configuration interface exactly.
abde82f to
b65519d
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (2)
43-53: Missing variables: define chainId and orderUid before usage
chainIdandorderUidare referenced but not defined, making the snippet non-runnable. Define them right after creating the adapter.Apply this diff:
export async function run(provider: Web3Provider): Promise<unknown> { const signer = provider.getSigner(); const adapter = new EthersV5Adapter({ provider, signer }); + // Resolve chainId from the connected network + const { chainId } = await provider.getNetwork(); + // Example: use env var or fallback placeholder for docs + const orderUid = + (process?.env?.ORDER_UID as string | undefined) ?? + '0x8464af00000000000000000000000000000000000000000000000000000000'; + // Initialize packages individually const orderBookApi = new OrderBookApi({ chainId }); const metadataApi = new MetadataApi(adapter); // Test OrderBookApi const order = await orderBookApi.getOrder(orderUid);
55-66: Align with new API and example output: add getAppDataInfo and return expected keysCall
getAppDataInfo()and return keys to match the “Example output” (orderBook,metadata.appDataHex).Apply this diff:
// Test MetadataApi const appDataDoc = await metadataApi.generateAppDataDoc({ appCode: 'Individual Basic Usage', environment: 'production', metadata: { quote: { slippageBips: 50 }, orderClass: { orderClass: 'market' } } }); - return { order, appDataDoc }; + // Convert doc into on-chain usable fields (hex, cid, etc.) + const appDataInfo = await metadataApi.getAppDataInfo(appDataDoc); + + // Return shape aligned with the "Example output" section + return { + orderBook: order, + metadata: { appDataHex: appDataInfo.appDataHex } + }; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
content/tutorial/00-setup/00-getting-started/00-getting-started/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/README.md(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-a/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts(1 hunks)content/tutorial/00-setup/00-getting-started/01-provider-adapters/meta.json(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md(1 hunks)src/routes/+page.server.js(1 hunks)src/routes/tutorial/+page.js(1 hunks)src/routes/tutorial/[slug]/+page.server.js(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- src/routes/tutorial/[slug]/+page.server.js
- src/routes/tutorial/+page.js
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/README.md
- content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/README.md
🚧 Files skipped from review as they are similar to previous changes (6)
- content/tutorial/00-setup/00-getting-started/00-getting-started/app-a/src/lib/run.ts
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-a/src/lib/run.ts
- content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/meta.json
- content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md
🧰 Additional context used
🪛 LanguageTool
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md
[grammar] ~17-~17: Ensure spelling is correct
Context: ...ustom rate limits, URLs, etc. ### 📋 MetadataApi Generates and processes app data: - *...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (1)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (1)
73-82: Verify OrderBookApi option names and valuesEnsure that the config keys you’re passing to
new OrderBookApi({ … })match your installed SDK’s types exactly:
env
– Confirm that'prod'is an accepted literal (or whether the enum expects something likeEnv.PRODor'production').backoffOpts
– Validate thatmaxDelayandnumOfAttemptsalign with the definedBackoffOptsinterface.baseUrls
– Make sure the keys (e.g.SupportedChainId.GNOSIS_CHAIN) and their URL values conform to the SDK’s type definitions.You can inspect your local SDK package’s type declarations (usually under
node_modules/<your-cow-sdk-package>/dist/*.d.ts) to verify exactly which names and string literals are allowed. For example:grep -R "interface .*OrderBook.*Options" -n node_modules grep -R "class OrderBookApi" -n node_modules
My branch wasn’t up to date with the fix made on main… I’ve updated it and it’s working now. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (1)
49-53: Bug: invalid object literal forsignOrderCancellations(computed key used incorrectly).
{ [orderUid] }is not a valid way to pass the order IDs. The API expects an array under a named key (typicallyorderUids). This is a syntax/functional error.- const orderCancellationsSigningResult = await OrderSigningUtils.signOrderCancellations({ - [orderUid], - chainId, - signer - }); + const orderCancellationsSigningResult = await OrderSigningUtils.signOrderCancellations({ + orderUids: [orderUid], + chainId, + signer, + });
♻️ Duplicate comments (5)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (2)
47-49: Make the snippet runnable: resolve chainId from provider and provide a usable orderUidUsing a fixed chain constant may mismatch the connected wallet’s network, and an empty
orderUidwill makegetOrderfail immediately. ResolvechainIdfrom the provider (still fine to keep a constant if you want) and provide a realistic UID via env or a placeholder.Apply this diff:
- const chainId = SupportedChainId.GNOSIS_CHAIN; - const orderUid = ''; + // Resolve chain ID from the connected wallet to avoid network mismatches + const { chainId } = await provider.getNetwork(); + // Provide an order UID from env or a safe placeholder for docs + const orderUid = + (process?.env?.ORDER_UID as string | undefined) ?? + '0x8464af00000000000000000000000000000000000000000000000000000000';
57-68: Align code with new API and the “Example output”: add getAppDataInfo and return matching keysThe text and PR objectives mention replacing deprecated appDataToCid with
getAppDataInfo, and your “Example output” showsmetadata.appDataHex. The current snippet returns{ order, appDataDoc }, which doesn’t match.Apply this diff:
const appDataDoc = await metadataApi.generateAppDataDoc({ appCode: 'Individual Basic Usage', environment: 'production', metadata: { quote: { slippageBips: 50 }, orderClass: { orderClass: 'market' } } }); - return { order, appDataDoc }; + // Convert the document into on-chain usable fields (hex, cid, etc.) + const appDataInfo = await metadataApi.getAppDataInfo(appDataDoc); + + // Return shape aligned with the "Example output" section below + return { + orderBook: order, + metadata: { appDataHex: appDataInfo.appDataHex } + };content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (1)
29-29: Replace hard tabs with spaces to satisfy markdownlint (MD010).This mirrors a prior comment and still applies here. Convert all
\tcharacters to spaces in these regions to keep CI green.You can verify/fix with:
#!/bin/bash # Show remaining hard tabs rg -nP "\t" content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md # Replace tabs with 2 spaces (adjust to your convention) sed -i'' $'s/\t/ /g' content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.mdAlso applies to: 31-31, 33-33, 71-82, 103-103
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (1)
24-26: Fix markdownlint MD010 (hard tabs) to unblock the buildReplace hard tabs with spaces in the indicated ranges. This was flagged previously and still applies to this file.
Example diff for one block (apply same replacement pattern elsewhere):
- export async function run(provider: Web3Provider): Promise<unknown> { - const signer = provider.getSigner(); - const adapter = new EthersV5Adapter({ provider, signer }); + export async function run(provider: Web3Provider): Promise<unknown> { + const signer = provider.getSigner(); + const adapter = new EthersV5Adapter({ provider, signer });Also applies to: 34-35, 90-96
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (1)
51-53: Good: feeAmount is no longer overridden (previous feedback addressed)You kept the quoted fee intact, which preserves quote validity and prevents API rejections.
🧹 Nitpick comments (13)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (2)
75-86: Config naming consistency: env vs environmentYou use
environment: 'production'above (MetadataApi) andenv: 'prod'here (OrderBookApi). If both are the intended option names for their respective packages, add a short note to prevent confusion. If the SDK now prefers a single naming convention, align them.
54-56: Optional: guard or handle missing/invalid orderUid for a smoother tutorial runIf
ORDER_UIDisn’t provided,getOrder(orderUid)will throw. Consider a small guard or try/catch to keep the example flow friendly.Example adjustment:
- const order = await orderBookApi.getOrder(orderUid); + let order: unknown = null; + if (orderUid && /^0x[0-9a-fA-F]+$/.test(orderUid)) { + order = await orderBookApi.getOrder(orderUid); + } else { + console.warn('Tip: set ORDER_UID env var to fetch a real order.'); + }content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (4)
31-31: Use a plain string literal fororderUid(template literal unnecessary).Keeps the sample minimal and avoids implying interpolation.
- const orderUid = `0x8464affce2df48b60f6976e51414dbc079e9c30ef64f4c1f78c7abe2c7f96a0c29104bb91ada737a89393c78335e48ff4708727e659523a1`; + const orderUid = '0x8464affce2df48b60f6976e51414dbc079e9c30ef64f4c1f78c7abe2c7f96a0c29104bb91ada737a89393c78335e48ff4708727e659523a1';
44-44: Import looks good; ensurechainIdis actually defined or removeSupportedChainId.Either show a concrete
chainIdassignment (helps copy/paste-ability) or drop the unused import ifchainIdis defined elsewhere in the snippet.For example:
import type { Web3Provider } from '@ethersproject/providers'; -import { SupportedChainId, OrderBookApi, OrderSigningUtils } from '@cowprotocol/cow-sdk'; +import { SupportedChainId, OrderBookApi, OrderSigningUtils } from '@cowprotocol/cow-sdk'; export async function run(provider: Web3Provider): Promise<unknown> { // ... + const chainId = SupportedChainId.SEPOLIA; // or derive from provider/network
79-79: Consider returning theorderUidalongside the result for traceability.Helps readers correlate the response with the attempted cancellation when running multiple examples.
- return { cancellationsResult }; + return { orderUid, cancellationsResult };
81-81: Avoid returning raw errors; return a structured error or rethrow.Returning the raw error object can leak internals and varies by runtime. Prefer a stable shape.
- } catch (e) { - return e; + } catch (e) { + return { error: e instanceof Error ? e.message : String(e) }; }content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (5)
87-98: Make JSON example valid (use jsonc or remove the comment line)The code fence is tagged as JSON, but the first line inside is a comment. Either switch the fence to jsonc or remove the comment line so users can copy-paste valid JSON.
-```json -/// file: output.json +```jsonc { "cowSdkInitialized": true, "availableModules": { "orderBook": true, "metadataApi": true, "orderSigning": true, "subgraph": true } }--- `5-13`: **Tighten naming consistency: “CowSdk” vs “CowSdk class”; brand casing “CoW”** - Prefer “CowSdk” (or “CoW SDK” for prose) consistently; avoid switching between “CowSdk class” and “CowSdk Class”. - Example: change the heading to “Why use CowSdk?” and the first sentence to “CowSdk provides a unified interface…”. ```diff -The **CowSdk class** provides a unified interface to access all CoW Protocol functionality through a single SDK instance. +CowSdk provides a unified interface to access all CoW Protocol functionality through a single SDK instance. -## Why Use CowSdk Class? +## Why use CowSdk?
17-37: Optional: clarify signer availability and adapter expectationsReaders may copy-paste this. Consider a brief note that
provider.getSigner()requires a connected wallet context; otherwise, some modules (like signing) won’t work. You can show a guard or mention read-only mode.export async function run(provider: Web3Provider): Promise<unknown> { - const signer = provider.getSigner(); + // Requires a connected wallet; in read-only contexts, omit the signer. + const signer = provider.getSigner(); const adapter = new EthersV5Adapter({ provider, signer });
49-61: Avoid ellipses in TypeScript blocks; prefer comments so copy-paste compilesUsing
...inside a TS code fence breaks copy-paste. Replace with comments and include a trailing comma fix.-const cowSdk = new CowSdk({ - adapter, // Required: Your provider adapter - chainId, // Required: Target blockchain - env: 'prod', // Optional: 'prod' or 'staging' (default: 'prod') - orderBookOptions: { // Optional: Advanced order book configuration - backoffOpts: {...}, - baseUrls: {...} - } - ... -}) +const cowSdk = new CowSdk({ + adapter, // Required: your provider adapter + chainId, // Required: target blockchain + env: 'prod', // Optional: 'prod' or 'staging' (default: 'prod') + // Optional: advanced order book configuration + // orderBookOptions: { + // backoffOpts: { /* retry/backoff options */ }, + // baseUrls: { /* override base URLs if needed */ }, + // }, +});
69-77: Consider showing the inferred-signing variant (if supported) alongside the explicit oneIf the unified SDK infers
chainIdandsignerfrom the adapter, show both forms so users pick the recommended path.// Sign an order using the unified SDK -const signature = await cowSdk.orderSigning.signOrder(order, chainId, signer) +// Explicit: +const signature = await cowSdk.orderSigning.signOrder(order, chainId, signer) +// Or, if supported by the current SDK (preferred for simplicity): +// const signature = await cowSdk.orderSigning.signOrder(order)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (2)
74-76: Narrow the error type to avoid “unknown” access in strict TSIn TS 4.4+, catch variable is unknown. Accessing error.message can fail under stricter configs. Narrow or stringify safely.
Apply this diff:
- } catch (error) { - return { error: error.message }; - } + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { error: message }; + }
41-45: Optional: centralize chain-specific token addressesSince this tutorial set uses these addresses in multiple places, consider extracting them to a small constants module keyed by chainId to avoid duplication and reduce copy/paste errors.
Example:
// tokens.ts export const GNOSIS_TOKENS = { WXDAI: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', COW: '0x177127622c4A00F3d409B75571e12cB3c8973d3c', };Then:
sellToken: GNOSIS_TOKENS.WXDAI, buyToken: GNOSIS_TOKENS.COW,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts(1 hunks)content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md(2 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md(1 hunks)content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md(1 hunks)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts(1 hunks)src/routes/+page.server.js(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts
- src/routes/+page.server.js
- content/tutorial/03-umbrella-sdk/01-unified-approach/02-complete-workflow/README.md
🧰 Additional context used
🧬 Code graph analysis (1)
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (4)
content/tutorial/00-setup/00-getting-started/01-provider-adapters/app-b/src/lib/run.ts (1)
run(5-31)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-a/src/lib/run.ts (1)
run(4-14)content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/app-b/src/lib/run.ts (1)
run(5-48)content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-a/src/lib/run.ts (1)
run(11-30)
🪛 Gitleaks (8.27.2)
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts
33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
34-34: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md
[grammar] ~12-~12: There might be a mistake here.
Context: ...t**: One import, one initialization - 🔧 Consistent Configuration: Same settin...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ...**: Same settings for all modules - 📦 Batteries Included: All functionality ...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...**: All functionality in one place ## Basic Initialization ```typescript /// fil...
(QB_NEW_EN)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md
[grammar] ~11-~11: There might be a mistake here.
Context: ...dual packages: ### 📊 OrderBookApi Handles order management and quotes: - **...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ...Standalone* - no adapter required - Simple initialization - just needs chai...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...itialization** - just needs chainId - Independent configuration - custom rate...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...ation** - custom rate limits, URLs, etc. ### 📋 MetadataApi Generates and processes ...
(QB_NEW_EN)
[grammar] ~17-~17: There might be a mistake here.
Context: ...its, URLs, etc. ### 📋 MetadataApi Generates and processes app data: - **Req...
(QB_NEW_EN)
[grammar] ~19-~19: There might be a mistake here.
Context: ...* Generates and processes app data: - Requires adapter for blockchain operati...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ...adapter** for blockchain operations - Flexible adapter - can use different ad...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...pter** - can use different adapters - Blockchain aware - can interact with on...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ...ware** - can interact with on-chain data ### ✍️ OrderSigningUtils Static utility cla...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...n-chain data ### ✍️ OrderSigningUtils Static utility class for signing orders:...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...Static utility class for signing orders: - No initialization needed - **Static me...
(QB_NEW_EN)
🔇 Additional comments (7)
content/tutorial/03-umbrella-sdk/02-individual-packages/01-basic-usage/README.md (1)
87-93: Nice demonstration of per-usage adaptersShowing separate read-only and signing adapters for MetadataApi is clear and helps readers understand adapter granularity.
content/tutorial/01-simple-orders/01-order/06-cancel-off-chain-order/README.md (2)
76-77: Good: explicitly settingorderUidsafter spreading the signing result.Placing
orderUids: [orderUid]after...orderCancellationsSigningResultensures your explicit value wins if the spread contains the same key. Nice attention to ordering.
59-59: Add documentation links for the deprecated single-UID cancellation endpointPlease add direct links to the official docs where we mark the single-UID
/cancelendpoint as deprecated and show the plural-payload version, so readers can verify and explore further:
- Link to the CoW Learn tutorial “Cancelling off-chain” where the single-UID endpoint is noted as deprecated and the plural endpoint is introduced:
https://learn.cow.fi/tutorial/cancel-off-chain-order?utm_source=chatgpt.com- Link to the SDK reference for
OrderBookApi.sendSignedOrderCancellations, which accepts the pluralOrderCancellationsrequest body:
https://docs.cow.fi/cow-protocol/reference/sdks/cow-sdk/classes/OrderBookApi?utm_source=chatgpt.com#sendSignedOrderCancellations- (Optional) Link to the
OrderCancellationsmodel definition showing the payload shape (orderUids?: UID[]plussignature/signingScheme):
https://docs.cow.fi/cow-protocol/reference/sdks/cow-sdk/modules?utm_source=chatgpt.com#OrderCancellationsThese links will give readers confidence that the deprecation note is accurate and point them to the exact TypeScript types and examples.
content/tutorial/03-umbrella-sdk/01-unified-approach/01-simple-setup/README.md (2)
1-3: Overall: clear, well-structured tutorial and aligns with the PR goalsThe document effectively introduces the unified CowSdk, adapter setup, and module usage; headings, code fences, and flow are easy to follow. Once the small nits above are addressed, this is good to go.
Also applies to: 5-14, 39-47, 63-67, 79-86
28-33: Manual verification required: Confirm SDK API surface against the monorepoThis tutorial repository contains only usage examples; the actual
CowSdkimplementation lives externally. Before merging, please cross-check the following against the latest umbrella-sdk monorepo and update these code snippets as needed:
Config key
• Should beenv(notenvironment)
• Allowed values: exactly'prod'or'staging'SDK modules on
CowSdkinstance
•.orderBook
•.metadataApi
•.orderSigning
•.subgraphSigning API signature
• Examples currently useawait cowSdk.orderSigning.signOrder(order, chainId, signer)
• If the latest SDK infers any parameters (e.g. signer or chainId), adjust calls accordingly (e.g.signOrder(order))Affected sections:
- 01-simple-setup README.md (lines 28–33)
- 02-complete-workflow README.md (lines 69–77, 91–96)
content/tutorial/03-umbrella-sdk/02-individual-packages/02-advanced-usage/app-b/src/lib/run.ts (2)
27-38: Solid switch to getAppDataInfo and correct pairing of appDataContent/hashThe generateAppDataDoc → getAppDataInfo flow looks correct, and passing appDataContent to quoting while keeping appDataHex for the order aligns with the new SDK APIs.
39-49: Quote request parameters look consistent for SELL-side flowsUsing sellAmountBeforeFee with OrderQuoteSideKindSell.SELL and providing both appData (content) and appDataHash (hex) is coherent. Token addresses match Gnosis, and from/receiver are aligned.
|
Looks cool, would be great if this could be merged or actioned! 🙏 @alfetopito 😉 |
|
Continued in #46 |


Description
This PR updates the CoW Protocol Learn tutorials to align with the new SDK monorepo architecture that introduces provider adapters.
It also adds new tutorial sections to demonstrate different SDK usage patterns.
Changes
Existing tutorial updates:
appDataToCid()→getAppDataInfo()MetadataApi,OrderSigningUtils, etc.@cowprotocol/cow-sdk) with specific adapter packagesNew tutorial sections:
00-setup/01-provider-adapters03-umbrella-sdk/— complete new section comparing different SDK usage approachesSummary by CodeRabbit
New Features
Improvements
Chores