@cowprotocol/sdk-trading 0.1.0-monorepo.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1025 @@
1
+ // src/postCoWProtocolTrade.ts
2
+ import { SigningScheme as SigningScheme3 } from "@cowprotocol/sdk-order-book";
3
+
4
+ // src/consts.ts
5
+ import { EcdsaSigningScheme, SigningScheme } from "@cowprotocol/sdk-order-book";
6
+ import { SupportedChainId } from "@cowprotocol/sdk-config";
7
+ var DEFAULT_QUOTE_VALIDITY = 60 * 30;
8
+ var DEFAULT_SLIPPAGE_BPS = 50;
9
+ var ETH_FLOW_DEFAULT_SLIPPAGE_BPS = {
10
+ [SupportedChainId.MAINNET]: 200,
11
+ // 2%,
12
+ [SupportedChainId.ARBITRUM_ONE]: 50,
13
+ // 0.5%,
14
+ [SupportedChainId.BASE]: 50,
15
+ // 0.5%,
16
+ [SupportedChainId.GNOSIS_CHAIN]: 50,
17
+ // 0.5%,
18
+ [SupportedChainId.SEPOLIA]: 50,
19
+ // 0.5%,
20
+ [SupportedChainId.POLYGON]: 50,
21
+ // 0.5%,
22
+ [SupportedChainId.AVALANCHE]: 50
23
+ // 0.5%,
24
+ };
25
+ var SIGN_SCHEME_MAP = {
26
+ [EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,
27
+ [EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN
28
+ };
29
+ var GAS_LIMIT_DEFAULT = BigInt(15e4);
30
+
31
+ // src/postCoWProtocolTrade.ts
32
+ import { OrderSigningUtils as OrderSigningUtils2 } from "@cowprotocol/sdk-order-signing";
33
+
34
+ // src/getOrderToSign.ts
35
+ import { BuyTokenDestination, getQuoteAmountsAndCosts, SellTokenSource } from "@cowprotocol/sdk-order-book";
36
+
37
+ // src/utils/getPartnerFeeBps.ts
38
+ function getPartnerFeeBps(partnerFee) {
39
+ if (!partnerFee) {
40
+ return void 0;
41
+ }
42
+ if ("volumeBps" in partnerFee) {
43
+ return partnerFee.volumeBps;
44
+ }
45
+ if (Array.isArray(partnerFee)) {
46
+ for (const fee of partnerFee) {
47
+ if ("volumeBps" in fee) {
48
+ return fee.volumeBps;
49
+ }
50
+ }
51
+ }
52
+ return void 0;
53
+ }
54
+
55
+ // src/getOrderToSign.ts
56
+ function getOrderToSign({ from, networkCostsAmount = "0" }, limitOrderParams, appDataKeccak256) {
57
+ const {
58
+ sellAmount,
59
+ buyAmount,
60
+ sellToken,
61
+ sellTokenDecimals,
62
+ buyToken,
63
+ buyTokenDecimals,
64
+ kind,
65
+ partiallyFillable = false,
66
+ slippageBps = DEFAULT_SLIPPAGE_BPS,
67
+ partnerFee,
68
+ validFor
69
+ } = limitOrderParams;
70
+ const receiver = limitOrderParams.receiver || from;
71
+ const validTo = limitOrderParams.validTo || Math.floor(Date.now() / 1e3) + (validFor || DEFAULT_QUOTE_VALIDITY);
72
+ const orderParams = {
73
+ sellToken,
74
+ buyToken,
75
+ sellAmount,
76
+ buyAmount,
77
+ receiver,
78
+ validTo,
79
+ kind,
80
+ feeAmount: networkCostsAmount,
81
+ appData: appDataKeccak256,
82
+ partiallyFillable
83
+ };
84
+ const { afterSlippage } = getQuoteAmountsAndCosts({
85
+ orderParams,
86
+ slippagePercentBps: slippageBps,
87
+ partnerFeeBps: getPartnerFeeBps(partnerFee),
88
+ sellDecimals: sellTokenDecimals,
89
+ buyDecimals: buyTokenDecimals
90
+ });
91
+ return {
92
+ sellToken,
93
+ buyToken,
94
+ sellAmount: afterSlippage.sellAmount.toString(),
95
+ buyAmount: afterSlippage.buyAmount.toString(),
96
+ validTo,
97
+ kind,
98
+ partiallyFillable,
99
+ appData: appDataKeccak256,
100
+ receiver,
101
+ feeAmount: "0",
102
+ sellTokenBalance: SellTokenSource.ERC20,
103
+ buyTokenBalance: BuyTokenDestination.ERC20
104
+ };
105
+ }
106
+
107
+ // src/postSellNativeCurrencyOrder.ts
108
+ import { getGlobalAdapter as getGlobalAdapter2 } from "@cowprotocol/sdk-common";
109
+ import { SigningScheme as SigningScheme2 } from "@cowprotocol/sdk-order-book";
110
+
111
+ // src/calculateUniqueOrderId.ts
112
+ import { OrderSigningUtils } from "@cowprotocol/sdk-order-signing";
113
+ import {
114
+ BARN_ETH_FLOW_ADDRESS,
115
+ ETH_FLOW_ADDRESS,
116
+ MAX_VALID_TO_EPOCH,
117
+ WRAPPED_NATIVE_CURRENCIES
118
+ } from "@cowprotocol/sdk-config";
119
+ async function calculateUniqueOrderId(chainId, order, checkEthFlowOrderExists, env) {
120
+ const { orderDigest, orderId } = await OrderSigningUtils.generateOrderId(
121
+ chainId,
122
+ {
123
+ ...order,
124
+ sellTokenBalance: order.sellTokenBalance,
125
+ buyTokenBalance: order.buyTokenBalance,
126
+ validTo: MAX_VALID_TO_EPOCH,
127
+ sellToken: WRAPPED_NATIVE_CURRENCIES[chainId].address
128
+ },
129
+ {
130
+ owner: env === "staging" ? BARN_ETH_FLOW_ADDRESS : ETH_FLOW_ADDRESS
131
+ }
132
+ );
133
+ if (checkEthFlowOrderExists && await checkEthFlowOrderExists(orderId, orderDigest)) {
134
+ console.error("ETH FLOW", "[calculateUniqueOrderId] \u274C Collision detected: " + orderId, {
135
+ sellAmount: order.sellAmount,
136
+ fee: order.feeAmount
137
+ });
138
+ return calculateUniqueOrderId(chainId, adjustAmounts(order), checkEthFlowOrderExists);
139
+ }
140
+ return orderId;
141
+ }
142
+ function adjustAmounts(order) {
143
+ const buyAmount = BigInt(order.buyAmount);
144
+ return { ...order, buyAmount: (buyAmount - BigInt(1)).toString() };
145
+ }
146
+
147
+ // src/getEthFlowTransaction.ts
148
+ import { BARN_ETH_FLOW_ADDRESS as BARN_ETH_FLOW_ADDRESS2, ETH_FLOW_ADDRESS as ETH_FLOW_ADDRESS2 } from "@cowprotocol/sdk-config";
149
+
150
+ // src/utils/misc.ts
151
+ import { ETH_ADDRESS, WRAPPED_NATIVE_CURRENCIES as WRAPPED_NATIVE_CURRENCIES2 } from "@cowprotocol/sdk-config";
152
+ function swapParamsToLimitOrderParams(params, quoteResponse) {
153
+ return {
154
+ ...params,
155
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
156
+ quoteId: quoteResponse.id,
157
+ sellAmount: quoteResponse.quote.sellAmount,
158
+ buyAmount: quoteResponse.quote.buyAmount
159
+ };
160
+ }
161
+ function getIsEthFlowOrder(params) {
162
+ return params.sellToken.toLowerCase() === ETH_ADDRESS.toLowerCase();
163
+ }
164
+ function calculateGasMargin(value) {
165
+ return value + value * BigInt(20) / BigInt(100);
166
+ }
167
+ function mapQuoteAmountsAndCosts(value, mapper) {
168
+ const {
169
+ costs: { networkFee, partnerFee }
170
+ } = value;
171
+ function serializeAmounts(value2) {
172
+ return {
173
+ sellAmount: mapper(value2.sellAmount),
174
+ buyAmount: mapper(value2.buyAmount)
175
+ };
176
+ }
177
+ return {
178
+ ...value,
179
+ costs: {
180
+ ...value.costs,
181
+ networkFee: {
182
+ ...networkFee,
183
+ amountInSellCurrency: mapper(networkFee.amountInSellCurrency),
184
+ amountInBuyCurrency: mapper(networkFee.amountInBuyCurrency)
185
+ },
186
+ partnerFee: {
187
+ ...partnerFee,
188
+ amount: mapper(partnerFee.amount)
189
+ }
190
+ },
191
+ beforeNetworkCosts: serializeAmounts(value.beforeNetworkCosts),
192
+ afterNetworkCosts: serializeAmounts(value.afterNetworkCosts),
193
+ afterPartnerFees: serializeAmounts(value.afterPartnerFees),
194
+ afterSlippage: serializeAmounts(value.afterSlippage)
195
+ };
196
+ }
197
+ function getTradeParametersAfterQuote({
198
+ quoteParameters,
199
+ sellToken
200
+ }) {
201
+ return { ...quoteParameters, sellToken };
202
+ }
203
+ function adjustEthFlowOrderParams(chainId, params) {
204
+ return {
205
+ ...params,
206
+ sellToken: WRAPPED_NATIVE_CURRENCIES2[chainId].address,
207
+ slippageBps: typeof params.slippageBps === "number" ? params.slippageBps : ETH_FLOW_DEFAULT_SLIPPAGE_BPS[chainId]
208
+ };
209
+ }
210
+
211
+ // src/getEthFlowTransaction.ts
212
+ import {
213
+ getGlobalAdapter,
214
+ ContractFactory
215
+ } from "@cowprotocol/sdk-common";
216
+ async function getEthFlowTransaction(appDataKeccak256, _params, chainId, additionalParams = {}, paramSigner) {
217
+ const signer = paramSigner ? getGlobalAdapter().createSigner(paramSigner) : getGlobalAdapter().signer;
218
+ const { networkCostsAmount = "0", checkEthFlowOrderExists } = additionalParams;
219
+ const from = await signer.getAddress();
220
+ const params = {
221
+ ..._params,
222
+ ...adjustEthFlowOrderParams(chainId, _params)
223
+ };
224
+ const { quoteId } = params;
225
+ const contract = getEthFlowContract(signer, params.env);
226
+ const orderToSign = getOrderToSign({ from, networkCostsAmount }, params, appDataKeccak256);
227
+ const orderId = await calculateUniqueOrderId(chainId, orderToSign, checkEthFlowOrderExists, params.env);
228
+ const ethOrderParams = {
229
+ buyToken: orderToSign.buyToken,
230
+ receiver: orderToSign.receiver,
231
+ sellAmount: orderToSign.sellAmount,
232
+ buyAmount: orderToSign.buyAmount,
233
+ feeAmount: orderToSign.feeAmount,
234
+ partiallyFillable: orderToSign.partiallyFillable,
235
+ quoteId,
236
+ appData: appDataKeccak256,
237
+ validTo: orderToSign.validTo.toString()
238
+ };
239
+ const estimatedGas = await contract.estimateGas.createOrder?.(ethOrderParams, { value: orderToSign.sellAmount }).catch((error) => {
240
+ console.error(error);
241
+ return GAS_LIMIT_DEFAULT;
242
+ }) || GAS_LIMIT_DEFAULT;
243
+ const data = contract.interface.encodeFunctionData("createOrder", [ethOrderParams]);
244
+ return {
245
+ orderId,
246
+ orderToSign,
247
+ transaction: {
248
+ data,
249
+ gasLimit: "0x" + calculateGasMargin(estimatedGas).toString(16),
250
+ to: contract.address,
251
+ value: "0x" + BigInt(orderToSign.sellAmount).toString(16)
252
+ }
253
+ };
254
+ }
255
+ function getEthFlowContract(signer, env) {
256
+ const address = env === "staging" ? BARN_ETH_FLOW_ADDRESS2 : ETH_FLOW_ADDRESS2;
257
+ return ContractFactory.createEthFlowContract(address, signer);
258
+ }
259
+
260
+ // src/postSellNativeCurrencyOrder.ts
261
+ import { log } from "@cowprotocol/sdk-common";
262
+ async function postSellNativeCurrencyOrder(orderBookApi, appData, _params, additionalParams = {}, paramSigner) {
263
+ const signer = paramSigner ? getGlobalAdapter2().createSigner(paramSigner) : getGlobalAdapter2().signer;
264
+ const { appDataKeccak256, fullAppData } = appData;
265
+ const { orderId, transaction, orderToSign } = await getEthFlowTransaction(
266
+ appDataKeccak256,
267
+ _params,
268
+ orderBookApi.context.chainId,
269
+ additionalParams,
270
+ signer
271
+ );
272
+ log("Uploading app-data");
273
+ await orderBookApi.uploadAppData(appDataKeccak256, fullAppData);
274
+ log("Sending on-chain order transaction");
275
+ const txReceipt = await signer.sendTransaction(transaction);
276
+ log(`On-chain order transaction sent, txHash: ${txReceipt.hash}, order: ${orderId}`);
277
+ return { txHash: txReceipt.hash, orderId, orderToSign, signature: "", signingScheme: SigningScheme2.EIP1271 };
278
+ }
279
+
280
+ // src/postCoWProtocolTrade.ts
281
+ import { CowError, getGlobalAdapter as getGlobalAdapter4, log as log2 } from "@cowprotocol/sdk-common";
282
+
283
+ // src/appDataUtils.ts
284
+ import {
285
+ MetadataApi,
286
+ stringifyDeterministic
287
+ } from "@cowprotocol/sdk-app-data";
288
+ import { getGlobalAdapter as getGlobalAdapter3 } from "@cowprotocol/sdk-common";
289
+ import deepmerge from "deepmerge";
290
+ async function buildAppData({ slippageBps, appCode, orderClass: orderClassName, partnerFee }, advancedParams) {
291
+ const quoteParams = { slippageBips: slippageBps };
292
+ const orderClass = { orderClass: orderClassName };
293
+ const metadataApiSdk = new MetadataApi(getGlobalAdapter3());
294
+ const doc = await metadataApiSdk.generateAppDataDoc(
295
+ deepmerge(
296
+ {
297
+ appCode,
298
+ metadata: {
299
+ quote: quoteParams,
300
+ orderClass,
301
+ partnerFee
302
+ }
303
+ },
304
+ advancedParams || {}
305
+ )
306
+ );
307
+ const { fullAppData, appDataKeccak256 } = await generateAppDataFromDoc(doc);
308
+ return { doc, fullAppData, appDataKeccak256 };
309
+ }
310
+ async function generateAppDataFromDoc(doc) {
311
+ const adapter = getGlobalAdapter3();
312
+ const fullAppData = await stringifyDeterministic(doc);
313
+ const appDataKeccak256 = adapter.utils.keccak256(adapter.utils.toUtf8Bytes(fullAppData));
314
+ return { fullAppData, appDataKeccak256 };
315
+ }
316
+ async function mergeAppDataDoc(_doc, appDataOverride) {
317
+ const doc = appDataOverride.metadata?.hooks ? {
318
+ ..._doc,
319
+ metadata: {
320
+ ..._doc.metadata,
321
+ hooks: {}
322
+ }
323
+ } : _doc;
324
+ const appData = appDataOverride ? deepmerge(doc, appDataOverride) : doc;
325
+ const { fullAppData, appDataKeccak256 } = await generateAppDataFromDoc(appData);
326
+ return {
327
+ fullAppData,
328
+ appDataKeccak256,
329
+ doc: appData
330
+ };
331
+ }
332
+
333
+ // ../sdk/package.json
334
+ var package_default = {
335
+ name: "@cowprotocol/cow-sdk",
336
+ version: "7.0.0-monorepo.0",
337
+ license: "(MIT OR Apache-2.0)",
338
+ description: "CowProtocol SDK - Complete umbrella package for CoW Protocol interactions",
339
+ main: "./dist/index.js",
340
+ module: "./dist/index.mjs",
341
+ types: "./dist/index.d.ts",
342
+ exports: {
343
+ ".": {
344
+ types: "./dist/index.d.ts",
345
+ import: "./dist/index.mjs",
346
+ require: "./dist/index.js"
347
+ }
348
+ },
349
+ sideEffects: false,
350
+ files: [
351
+ "dist/**"
352
+ ],
353
+ scripts: {
354
+ build: "tsup src/index.ts --format esm,cjs --dts --treeshake",
355
+ postbuild: "cp package.json dist && pnpm copy-md-files",
356
+ "copy-md-files": 'npx cpx "**/*.md" dist',
357
+ lint: "eslint src/**/*.ts",
358
+ typecheck: "tsc --noEmit",
359
+ clean: "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
360
+ },
361
+ devDependencies: {
362
+ "@cow-sdk/typescript-config": "workspace:*",
363
+ "@types/node": "^20.17.31",
364
+ jest: "^29.7.0",
365
+ "ts-node": "^10.8.2",
366
+ tsup: "^7.2.0",
367
+ typescript: "^5.2.2"
368
+ },
369
+ dependencies: {
370
+ "@cowprotocol/sdk-app-data": "workspace:*",
371
+ "@cowprotocol/sdk-bridging": "workspace:*",
372
+ "@cowprotocol/sdk-common": "workspace:*",
373
+ "@cowprotocol/sdk-composable": "workspace:*",
374
+ "@cowprotocol/sdk-config": "workspace:*",
375
+ "@cowprotocol/sdk-contracts-ts": "workspace:*",
376
+ "@cowprotocol/sdk-cow-shed": "workspace:*",
377
+ "@cowprotocol/sdk-order-book": "workspace:*",
378
+ "@cowprotocol/sdk-order-signing": "workspace:*",
379
+ "@cowprotocol/sdk-subgraph": "workspace:*",
380
+ "@cowprotocol/sdk-trading": "workspace:*",
381
+ "@cowprotocol/sdk-weiroll": "workspace:*"
382
+ },
383
+ peerDependencies: {
384
+ "@openzeppelin/merkle-tree": "^1.x",
385
+ "cross-fetch": "^3.x",
386
+ "ipfs-only-hash": "^4.x",
387
+ multiformats: "^9.x"
388
+ },
389
+ peerDependenciesMeta: {
390
+ "cross-fetch": {
391
+ optional: false
392
+ },
393
+ "ipfs-only-hash": {
394
+ optional: true
395
+ },
396
+ multiformats: {
397
+ optional: true
398
+ },
399
+ "@openzeppelin/merkle-tree": {
400
+ optional: true
401
+ }
402
+ },
403
+ keywords: [
404
+ "cow",
405
+ "cow-protocol",
406
+ "sdk",
407
+ "crypto",
408
+ "typescript",
409
+ "subgraph"
410
+ ],
411
+ repository: {
412
+ type: "git",
413
+ url: "https://github.com/cowprotocol/cow-sdk.git",
414
+ directory: "packages/sdk"
415
+ },
416
+ bugs: {
417
+ url: "https://github.com/cowprotocol/cow-sdk/issues"
418
+ },
419
+ homepage: "https://github.com/cowprotocol/cow-sdk#readme"
420
+ };
421
+
422
+ // src/postCoWProtocolTrade.ts
423
+ async function postCoWProtocolTrade(orderBookApi, paramAppData, params, additionalParams = {}, paramSigner) {
424
+ const adapter = getGlobalAdapter4();
425
+ const appData = await createAppDataWithUTM(paramAppData);
426
+ const signer = paramSigner ? adapter.createSigner(paramSigner) : adapter.signer;
427
+ const { networkCostsAmount = "0", signingScheme: _signingScheme = SigningScheme3.EIP712 } = additionalParams;
428
+ if (getIsEthFlowOrder(params)) {
429
+ const quoteId2 = params.quoteId;
430
+ if (typeof quoteId2 === "number") {
431
+ return postSellNativeCurrencyOrder(orderBookApi, appData, { ...params, quoteId: quoteId2 }, additionalParams, paramSigner);
432
+ } else {
433
+ throw new Error("quoteId is required for EthFlow orders");
434
+ }
435
+ }
436
+ const { quoteId = null, owner } = params;
437
+ const { appDataKeccak256, fullAppData } = appData;
438
+ const chainId = orderBookApi.context.chainId;
439
+ const from = owner || await signer.getAddress();
440
+ const orderToSign = getOrderToSign({ from, networkCostsAmount }, params, appData.appDataKeccak256);
441
+ log2("Signing order...");
442
+ const { signature, signingScheme } = await (async () => {
443
+ if (_signingScheme === SigningScheme3.PRESIGN) {
444
+ return { signature: from, signingScheme: SigningScheme3.PRESIGN };
445
+ } else {
446
+ const signingResult = await OrderSigningUtils2.signOrder(orderToSign, chainId, signer);
447
+ return { signature: signingResult.signature, signingScheme: SIGN_SCHEME_MAP[signingResult.signingScheme] };
448
+ }
449
+ })();
450
+ const orderBody = {
451
+ ...orderToSign,
452
+ from,
453
+ signature,
454
+ signingScheme,
455
+ quoteId,
456
+ appData: fullAppData,
457
+ appDataHash: appDataKeccak256
458
+ };
459
+ log2("Posting order...");
460
+ const orderId = await orderBookApi.sendOrder(orderBody);
461
+ log2(`Order created, id: ${orderId}`);
462
+ return { orderId, signature, signingScheme, orderToSign };
463
+ }
464
+ async function createAppDataWithUTM(originalAppData) {
465
+ if (disableUtm) {
466
+ return originalAppData;
467
+ }
468
+ let parsedData;
469
+ try {
470
+ parsedData = JSON.parse(originalAppData.fullAppData);
471
+ } catch {
472
+ try {
473
+ const unescapedData = originalAppData.fullAppData.replace(/\\"/g, '"');
474
+ parsedData = JSON.parse(unescapedData);
475
+ } catch (error) {
476
+ throw new CowError(`Failed to parse app data: ${originalAppData.fullAppData}: ${error}`);
477
+ }
478
+ }
479
+ const orderSpecificUtmContent = parsedData.utm?.utmContent;
480
+ const defaultUtmContent = "\u{1F42E} moo-ving to defi \u{1F42E}";
481
+ const utmContent2 = orderSpecificUtmContent || utmContent || defaultUtmContent;
482
+ const defaultUtm = {
483
+ utmCampaign: "developer-cohort",
484
+ utmContent: utmContent2,
485
+ utmMedium: `cow-sdk@${package_default.version}`,
486
+ utmSource: "cowmunity",
487
+ utmTerm: "js"
488
+ };
489
+ parsedData.utm = defaultUtm;
490
+ const { fullAppData, appDataKeccak256 } = await generateAppDataFromDoc(parsedData);
491
+ return {
492
+ ...originalAppData,
493
+ fullAppData,
494
+ appDataKeccak256
495
+ };
496
+ }
497
+
498
+ // src/getQuote.ts
499
+ import { getGlobalAdapter as getGlobalAdapter5, log as log3 } from "@cowprotocol/sdk-common";
500
+ import {
501
+ getQuoteAmountsAndCosts as getQuoteAmountsAndCosts2,
502
+ OrderBookApi as OrderBookApi3,
503
+ OrderQuoteSideKindBuy,
504
+ OrderQuoteSideKindSell,
505
+ PriceQuality,
506
+ SigningScheme as SigningScheme4
507
+ } from "@cowprotocol/sdk-order-book";
508
+
509
+ // src/getOrderTypedData.ts
510
+ import { ORDER_TYPE_FIELDS } from "@cowprotocol/sdk-contracts-ts";
511
+
512
+ // src/types.ts
513
+ var ORDER_PRIMARY_TYPE = "Order";
514
+
515
+ // src/getOrderTypedData.ts
516
+ import { OrderSigningUtils as OrderSigningUtils3 } from "@cowprotocol/sdk-order-signing";
517
+ var EIP712DomainTypes = [
518
+ { name: "name", type: "string" },
519
+ { name: "version", type: "string" },
520
+ { name: "chainId", type: "uint256" },
521
+ { name: "verifyingContract", type: "address" }
522
+ ];
523
+ async function getOrderTypedData(chainId, orderToSign) {
524
+ const domain = await OrderSigningUtils3.getDomain(chainId);
525
+ return {
526
+ domain,
527
+ primaryType: ORDER_PRIMARY_TYPE,
528
+ types: {
529
+ [ORDER_PRIMARY_TYPE]: ORDER_TYPE_FIELDS,
530
+ EIP712Domain: EIP712DomainTypes
531
+ },
532
+ message: orderToSign
533
+ };
534
+ }
535
+
536
+ // src/suggestSlippageBps.ts
537
+ import { percentageToBps } from "@cowprotocol/sdk-common";
538
+ import { getQuoteAmountsWithCosts } from "@cowprotocol/sdk-order-book";
539
+
540
+ // src/utils/slippage.ts
541
+ var SCALE = 10n ** 6n;
542
+ function getSlippagePercent(params) {
543
+ const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params;
544
+ const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts;
545
+ if (sellAmount <= 0n) {
546
+ throw new Error("sellAmount must be greater than 0: " + sellAmount);
547
+ }
548
+ if (slippage < 0n) {
549
+ throw new Error("slippage must be non-negative: " + slippage);
550
+ }
551
+ if (isSell) {
552
+ const percentageInScale = SCALE - SCALE * (sellAmount - slippage) / sellAmount;
553
+ return Number(percentageInScale) / Number(SCALE);
554
+ } else {
555
+ const percentageInScale = SCALE * (sellAmount + slippage) / sellAmount - SCALE;
556
+ return Number(percentageInScale) / Number(SCALE);
557
+ }
558
+ }
559
+
560
+ // src/suggestSlippageFromFee.ts
561
+ import { applyPercentage } from "@cowprotocol/sdk-common";
562
+ function suggestSlippageFromFee(params) {
563
+ const { feeAmount, multiplyingFactorPercent } = params;
564
+ if (feeAmount < 0n) {
565
+ throw new Error("Fee amount must be non-negative: " + feeAmount);
566
+ }
567
+ if (multiplyingFactorPercent < 0) {
568
+ throw new Error("multiplyingFactorPercent must be non-negative: " + multiplyingFactorPercent);
569
+ }
570
+ return applyPercentage(feeAmount, multiplyingFactorPercent);
571
+ }
572
+
573
+ // src/suggestSlippageFromVolume.ts
574
+ import { applyPercentage as applyPercentage2 } from "@cowprotocol/sdk-common";
575
+ function suggestSlippageFromVolume(params) {
576
+ const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params;
577
+ const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts;
578
+ if (sellAmount <= 0n) {
579
+ throw new Error("sellAmount must be greater than 0: " + sellAmount);
580
+ }
581
+ if (slippagePercent < 0) {
582
+ throw new Error("slippagePercent must be non-negative: " + slippagePercent);
583
+ }
584
+ return applyPercentage2(sellAmount, slippagePercent);
585
+ }
586
+
587
+ // src/suggestSlippageBps.ts
588
+ var MIN_SLIPPAGE_BPS = 50;
589
+ var MAX_SLIPPAGE_BPS = 1e4;
590
+ var SLIPPAGE_FEE_MULTIPLIER_PERCENT = 50;
591
+ var SLIPPAGE_VOLUME_MULTIPLIER_PERCENT = 0.5;
592
+ function suggestSlippageBps(params) {
593
+ const { quote, tradeParameters } = params;
594
+ const { sellTokenDecimals, buyTokenDecimals } = tradeParameters;
595
+ const { isSell, sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts } = getQuoteAmountsWithCosts({
596
+ sellDecimals: sellTokenDecimals,
597
+ buyDecimals: buyTokenDecimals,
598
+ orderParams: quote.quote
599
+ });
600
+ const { feeAmount: feeAmountString } = quote.quote;
601
+ const feeAmount = BigInt(feeAmountString);
602
+ const slippageBpsFromFee = suggestSlippageFromFee({
603
+ feeAmount,
604
+ multiplyingFactorPercent: SLIPPAGE_FEE_MULTIPLIER_PERCENT
605
+ });
606
+ const slippageBpsFromVolume = suggestSlippageFromVolume({
607
+ isSell,
608
+ sellAmountBeforeNetworkCosts,
609
+ sellAmountAfterNetworkCosts,
610
+ slippagePercent: SLIPPAGE_VOLUME_MULTIPLIER_PERCENT
611
+ });
612
+ const totalSlippageBps = slippageBpsFromFee + slippageBpsFromVolume;
613
+ const slippagePercent = getSlippagePercent({
614
+ isSell,
615
+ sellAmountBeforeNetworkCosts,
616
+ sellAmountAfterNetworkCosts,
617
+ slippage: totalSlippageBps
618
+ });
619
+ const slippageBps = percentageToBps(slippagePercent);
620
+ return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), MIN_SLIPPAGE_BPS);
621
+ }
622
+
623
+ // src/getQuote.ts
624
+ var ETH_FLOW_AUX_QUOTE_PARAMS = {
625
+ signingScheme: SigningScheme4.EIP1271,
626
+ onchainOrder: true,
627
+ // Ethflow orders are subsidized in the backend.
628
+ // This means we can assume the verification gas costs are zero for the quote/fee estimation
629
+ verificationGasLimit: 0
630
+ };
631
+ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBookApi) {
632
+ const { appCode, chainId, account: from } = trader;
633
+ const isEthFlow = getIsEthFlowOrder(_tradeParameters);
634
+ const tradeParameters = isEthFlow ? {
635
+ ..._tradeParameters,
636
+ ...adjustEthFlowOrderParams(chainId, _tradeParameters)
637
+ } : _tradeParameters;
638
+ const {
639
+ sellToken,
640
+ buyToken,
641
+ amount,
642
+ kind,
643
+ partnerFee,
644
+ validFor = DEFAULT_QUOTE_VALIDITY,
645
+ slippageBps,
646
+ env = "prod"
647
+ } = tradeParameters;
648
+ log3(
649
+ `getQuote for: Swap ${amount} ${sellToken} for ${buyToken} on chain ${chainId} with ${slippageBps !== void 0 ? `${slippageBps} BPS` : "AUTO"} slippage`
650
+ );
651
+ const orderBookApi = _orderBookApi || new OrderBookApi3({ chainId, env });
652
+ const receiver = tradeParameters.receiver || from;
653
+ const isSell = kind === "sell";
654
+ log3("Building app data...");
655
+ const slippageBpsOrDefault = slippageBps ?? DEFAULT_SLIPPAGE_BPS;
656
+ const buildAppDataParams = {
657
+ slippageBps: slippageBpsOrDefault,
658
+ orderClass: "market",
659
+ appCode,
660
+ partnerFee
661
+ };
662
+ const appDataInfo = await buildAppData(buildAppDataParams, advancedSettings?.appData);
663
+ const { appDataKeccak256, fullAppData } = appDataInfo;
664
+ log3(`App data: appDataKeccak256=${appDataKeccak256} fullAppData=${fullAppData}`);
665
+ const quoteRequest = {
666
+ from,
667
+ sellToken,
668
+ buyToken,
669
+ receiver,
670
+ validFor,
671
+ appData: fullAppData,
672
+ appDataHash: appDataKeccak256,
673
+ priceQuality: PriceQuality.OPTIMAL,
674
+ // Do not change this parameter because we rely on the fact that quote has id
675
+ signingScheme: SigningScheme4.EIP712,
676
+ ...isEthFlow ? ETH_FLOW_AUX_QUOTE_PARAMS : {},
677
+ ...isSell ? { kind: OrderQuoteSideKindSell.SELL, sellAmountBeforeFee: amount } : { kind: OrderQuoteSideKindBuy.BUY, buyAmountAfterFee: amount },
678
+ ...advancedSettings?.quoteRequest
679
+ };
680
+ log3("Getting quote...");
681
+ const quote = await orderBookApi.getQuote(quoteRequest);
682
+ const suggestedSlippageBps = suggestSlippageBps({ quote, tradeParameters, trader, advancedSettings });
683
+ if (slippageBps === void 0) {
684
+ if (suggestedSlippageBps > DEFAULT_SLIPPAGE_BPS) {
685
+ log3(
686
+ `Suggested slippage is greater than ${DEFAULT_SLIPPAGE_BPS} BPS (default), using the suggested slippage (${suggestedSlippageBps} BPS)`
687
+ );
688
+ const newAppDataInfo = await buildAppData(
689
+ {
690
+ ...buildAppDataParams,
691
+ slippageBps: suggestedSlippageBps
692
+ },
693
+ advancedSettings?.appData
694
+ );
695
+ log3(
696
+ `App data with new suggested slippage: appDataKeccak256=${newAppDataInfo.appDataKeccak256} fullAppData=${newAppDataInfo.fullAppData}`
697
+ );
698
+ return {
699
+ slippageBps: suggestedSlippageBps,
700
+ suggestedSlippageBps,
701
+ tradeParameters: { ..._tradeParameters, slippageBps: suggestedSlippageBps },
702
+ appDataInfo: newAppDataInfo,
703
+ // We reuse the quote, because the slippage has no fundamental impact on the quote
704
+ quote,
705
+ orderBookApi
706
+ };
707
+ } else {
708
+ log3(
709
+ `Suggested slippage is only ${suggestedSlippageBps} BPS. Using the default slippage (${DEFAULT_SLIPPAGE_BPS} BPS)`
710
+ );
711
+ }
712
+ }
713
+ return {
714
+ quote,
715
+ appDataInfo,
716
+ orderBookApi,
717
+ tradeParameters,
718
+ slippageBps: slippageBpsOrDefault,
719
+ suggestedSlippageBps
720
+ };
721
+ }
722
+ async function getQuote(_tradeParameters, trader, advancedSettings, _orderBookApi) {
723
+ const { quote, orderBookApi, tradeParameters, slippageBps, suggestedSlippageBps, appDataInfo } = await getQuoteRaw(
724
+ _tradeParameters,
725
+ trader,
726
+ advancedSettings,
727
+ _orderBookApi
728
+ );
729
+ const { partnerFee, sellTokenDecimals, buyTokenDecimals } = tradeParameters;
730
+ const { chainId, account: from } = trader;
731
+ const amountsAndCosts = getQuoteAmountsAndCosts2({
732
+ orderParams: quote.quote,
733
+ slippagePercentBps: slippageBps,
734
+ partnerFeeBps: getPartnerFeeBps(partnerFee),
735
+ sellDecimals: sellTokenDecimals,
736
+ buyDecimals: buyTokenDecimals
737
+ });
738
+ const orderToSign = getOrderToSign(
739
+ { from, networkCostsAmount: quote.quote.feeAmount },
740
+ swapParamsToLimitOrderParams(tradeParameters, quote),
741
+ appDataInfo.appDataKeccak256
742
+ );
743
+ const orderTypedData = await getOrderTypedData(chainId, orderToSign);
744
+ return {
745
+ result: {
746
+ tradeParameters,
747
+ suggestedSlippageBps,
748
+ amountsAndCosts,
749
+ orderToSign,
750
+ quoteResponse: quote,
751
+ appDataInfo,
752
+ orderTypedData
753
+ },
754
+ orderBookApi
755
+ };
756
+ }
757
+ async function getTrader(swapParameters) {
758
+ const signer = getGlobalAdapter5().signerOrNull();
759
+ const account = swapParameters.owner || await signer?.getAddress();
760
+ return {
761
+ chainId: swapParameters.chainId,
762
+ appCode: swapParameters.appCode,
763
+ account
764
+ };
765
+ }
766
+ async function getQuoteWithSigner(swapParameters, advancedSettings, orderBookApi) {
767
+ const adapter = getGlobalAdapter5();
768
+ const signer = swapParameters.signer ? adapter.createSigner(swapParameters.signer) : adapter.signer;
769
+ const trader = await getTrader(swapParameters);
770
+ const result = await getQuote(swapParameters, trader, advancedSettings, orderBookApi);
771
+ return {
772
+ result: {
773
+ ...result.result,
774
+ signer
775
+ },
776
+ orderBookApi: result.orderBookApi
777
+ };
778
+ }
779
+
780
+ // src/postSwapOrder.ts
781
+ async function postSwapOrder(params, advancedSettings, orderBookApi) {
782
+ return postSwapOrderFromQuote(await getQuoteWithSigner(params, advancedSettings, orderBookApi), advancedSettings);
783
+ }
784
+ async function postSwapOrderFromQuote({
785
+ orderBookApi,
786
+ result: { signer, appDataInfo: _appDataInfo, quoteResponse, tradeParameters }
787
+ }, advancedSettings) {
788
+ const params = swapParamsToLimitOrderParams(tradeParameters, quoteResponse);
789
+ const appDataOverride = advancedSettings?.appData;
790
+ const appDataInfo = appDataOverride ? await mergeAppDataDoc(_appDataInfo.doc, appDataOverride) : _appDataInfo;
791
+ const appDataSlippageOverride = appDataOverride?.metadata?.quote?.slippageBips;
792
+ const partnerFeeOverride = appDataOverride?.metadata?.partnerFee;
793
+ if (typeof appDataSlippageOverride !== "undefined") {
794
+ params.slippageBps = appDataSlippageOverride;
795
+ }
796
+ if (partnerFeeOverride) {
797
+ params.partnerFee = partnerFeeOverride;
798
+ }
799
+ if (advancedSettings?.quoteRequest) {
800
+ const { receiver, validTo, sellToken, buyToken } = advancedSettings.quoteRequest;
801
+ if (receiver)
802
+ params.receiver = receiver;
803
+ if (validTo)
804
+ params.validTo = validTo;
805
+ if (sellToken)
806
+ params.sellToken = sellToken;
807
+ if (buyToken)
808
+ params.buyToken = buyToken;
809
+ }
810
+ return postCoWProtocolTrade(
811
+ orderBookApi,
812
+ appDataInfo,
813
+ params,
814
+ {
815
+ signingScheme: advancedSettings?.quoteRequest?.signingScheme,
816
+ networkCostsAmount: quoteResponse.quote.feeAmount,
817
+ ...advancedSettings?.additionalParams
818
+ },
819
+ signer
820
+ );
821
+ }
822
+
823
+ // src/postLimitOrder.ts
824
+ import { OrderBookApi as OrderBookApi4 } from "@cowprotocol/sdk-order-book";
825
+ import { log as log4 } from "@cowprotocol/sdk-common";
826
+ async function postLimitOrder(params, advancedSettings, _orderBookApi) {
827
+ const appDataSlippage = advancedSettings?.appData?.metadata?.quote?.slippageBips;
828
+ const partnerFeeOverride = advancedSettings?.appData?.metadata?.partnerFee;
829
+ if (typeof appDataSlippage !== "undefined") {
830
+ params.slippageBps = appDataSlippage;
831
+ }
832
+ if (partnerFeeOverride) {
833
+ params.partnerFee = partnerFeeOverride;
834
+ }
835
+ if (!params.slippageBps) {
836
+ params.slippageBps = 0;
837
+ }
838
+ if (!params.env) {
839
+ params.env = "prod";
840
+ }
841
+ const { appCode, chainId, sellToken, buyToken, sellAmount, buyAmount, partnerFee } = params;
842
+ log4(`Limit order ${sellAmount} ${sellToken} for ${buyAmount} ${buyToken} on chain ${chainId}`);
843
+ const orderBookApi = _orderBookApi || new OrderBookApi4({ chainId, env: params.env });
844
+ log4("Building app data...");
845
+ const appDataInfo = await buildAppData(
846
+ {
847
+ slippageBps: params.slippageBps,
848
+ orderClass: "limit",
849
+ appCode,
850
+ partnerFee
851
+ },
852
+ advancedSettings?.appData
853
+ );
854
+ return postCoWProtocolTrade(orderBookApi, appDataInfo, params, advancedSettings?.additionalParams, params.signer);
855
+ }
856
+
857
+ // src/getPreSignTransaction.ts
858
+ import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from "@cowprotocol/sdk-config";
859
+ import { ContractFactory as ContractFactory2 } from "@cowprotocol/sdk-common";
860
+ async function getPreSignTransaction(signer, chainId, account, orderId) {
861
+ const contract = ContractFactory2.createSettlementContract(account, signer);
862
+ const settlementContractAddress = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId];
863
+ const preSignatureCall = contract.interface.encodeFunctionData("setPreSignature", [orderId, true]);
864
+ const gas = await contract.estimateGas.setPreSignature?.(orderId, true).catch(() => GAS_LIMIT_DEFAULT) || GAS_LIMIT_DEFAULT;
865
+ return {
866
+ data: preSignatureCall,
867
+ gasLimit: "0x" + calculateGasMargin(gas).toString(16),
868
+ to: settlementContractAddress,
869
+ // Para onde enviar a transação
870
+ value: "0"
871
+ };
872
+ }
873
+
874
+ // src/tradingSdk.ts
875
+ import { enableLogging, getGlobalAdapter as getGlobalAdapter6 } from "@cowprotocol/sdk-common";
876
+ import { setGlobalAdapter } from "@cowprotocol/sdk-common";
877
+ var utmContent = void 0;
878
+ var disableUtm = false;
879
+ var TradingSdk = class {
880
+ constructor(traderParams = {}, options = {}, adapter) {
881
+ this.traderParams = traderParams;
882
+ this.options = options;
883
+ if (options.enableLogging !== void 0) {
884
+ enableLogging(options.enableLogging);
885
+ }
886
+ if (adapter) {
887
+ setGlobalAdapter(adapter);
888
+ }
889
+ utmContent = options.utmContent;
890
+ disableUtm = options.disableUtm || false;
891
+ }
892
+ setTraderParams(params) {
893
+ this.traderParams = { ...this.traderParams, ...params };
894
+ return this;
895
+ }
896
+ async getQuote(params, advancedSettings) {
897
+ const quoteResults = await getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi);
898
+ return {
899
+ quoteResults: quoteResults.result,
900
+ postSwapOrderFromQuote: (advancedSettings2) => postSwapOrderFromQuote(
901
+ {
902
+ ...quoteResults,
903
+ result: {
904
+ ...quoteResults.result,
905
+ tradeParameters: getTradeParametersAfterQuote({
906
+ quoteParameters: quoteResults.result.tradeParameters,
907
+ sellToken: params.sellToken
908
+ })
909
+ }
910
+ },
911
+ advancedSettings2
912
+ )
913
+ };
914
+ }
915
+ async getQuoteResults(params, advancedSettings) {
916
+ return getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi);
917
+ }
918
+ async postSwapOrder(params, advancedSettings) {
919
+ return postSwapOrder(this.mergeParams(params), advancedSettings, this.options.orderBookApi);
920
+ }
921
+ async postLimitOrder(params, advancedSettings) {
922
+ return postLimitOrder(this.mergeParams(params), advancedSettings, this.options.orderBookApi);
923
+ }
924
+ /**
925
+ * Posts a sell order for native currency (e.g., ETH) using the EthFlow contract.
926
+ * This method creates an on-chain transaction for selling native tokens.
927
+ *
928
+ * @param params - The trade parameters including token addresses and amounts
929
+ * @param advancedSettings - Optional advanced settings for the swap
930
+ * @returns Promise resolving to the order posting result with transaction hash and order ID
931
+ *
932
+ * @example
933
+ * ```typescript
934
+ * const parameters: TradeParameters = {
935
+ * kind: OrderKind.SELL,
936
+ * sellToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // Native ETH
937
+ * sellTokenDecimals: 18,
938
+ * buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
939
+ * buyTokenDecimals: 18,
940
+ * amount: '100000000000000000', // 0.1 ETH
941
+ * }
942
+ *
943
+ * const { orderId, txHash } = await sdk.postSellNativeCurrencyOrder(parameters)
944
+ * ```
945
+ */
946
+ async postSellNativeCurrencyOrder(params, advancedSettings) {
947
+ const quoteResults = await getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi);
948
+ const { tradeParameters, quoteResponse } = quoteResults.result;
949
+ return postSellNativeCurrencyOrder(
950
+ quoteResults.orderBookApi,
951
+ quoteResults.result.appDataInfo,
952
+ // Quote response always has an id
953
+ swapParamsToLimitOrderParams(
954
+ getTradeParametersAfterQuote({ quoteParameters: tradeParameters, sellToken: params.sellToken }),
955
+ quoteResponse
956
+ ),
957
+ advancedSettings?.additionalParams,
958
+ quoteResults.result.signer
959
+ );
960
+ }
961
+ async getPreSignTransaction(params) {
962
+ const adapter = getGlobalAdapter6();
963
+ const traderParams = this.mergeParams(params);
964
+ const signer = traderParams.signer ? adapter.createSigner(traderParams.signer) : adapter.signer;
965
+ return getPreSignTransaction(signer, traderParams.chainId, params.account, params.orderId);
966
+ }
967
+ mergeParams(params) {
968
+ const { chainId, signer, appCode, env } = params;
969
+ const traderParams = {
970
+ chainId: chainId || this.traderParams.chainId,
971
+ signer: signer || this.traderParams.signer,
972
+ appCode: appCode || this.traderParams.appCode,
973
+ env: env || this.traderParams.env
974
+ };
975
+ assertTraderParams(traderParams);
976
+ return {
977
+ ...params,
978
+ ...traderParams
979
+ };
980
+ }
981
+ };
982
+ function assertTraderParams(params) {
983
+ if (!isTraderParameters(params)) {
984
+ throw new Error("Missing trader parameters: " + getMissingTraderParams(params).join(", "));
985
+ }
986
+ }
987
+ function getMissingTraderParams(params) {
988
+ const missingParams = [];
989
+ if (!params.chainId)
990
+ missingParams.push("chainId");
991
+ if (!params.signer)
992
+ missingParams.push("signer");
993
+ if (!params.appCode)
994
+ missingParams.push("appCode");
995
+ return missingParams;
996
+ }
997
+ function isTraderParameters(params) {
998
+ return getMissingTraderParams(params).length === 0;
999
+ }
1000
+ export {
1001
+ ORDER_PRIMARY_TYPE,
1002
+ TradingSdk,
1003
+ buildAppData,
1004
+ calculateUniqueOrderId,
1005
+ disableUtm,
1006
+ generateAppDataFromDoc,
1007
+ getEthFlowContract,
1008
+ getEthFlowTransaction,
1009
+ getOrderToSign,
1010
+ getPartnerFeeBps,
1011
+ getPreSignTransaction,
1012
+ getQuote,
1013
+ getQuoteWithSigner,
1014
+ getTradeParametersAfterQuote,
1015
+ mapQuoteAmountsAndCosts,
1016
+ mergeAppDataDoc,
1017
+ postCoWProtocolTrade,
1018
+ postLimitOrder,
1019
+ postSellNativeCurrencyOrder,
1020
+ postSwapOrder,
1021
+ postSwapOrderFromQuote,
1022
+ suggestSlippageBps,
1023
+ swapParamsToLimitOrderParams,
1024
+ utmContent
1025
+ };