@cowprotocol/sdk-trading 0.3.2-beta.0 → 0.4.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/README.md +210 -1
- package/dist/index.d.mts +76 -7
- package/dist/index.d.ts +76 -7
- package/dist/index.js +363 -72
- package/dist/index.mjs +343 -52
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -63,17 +63,62 @@ var import_sdk_order_book = require("@cowprotocol/sdk-order-book");
|
|
|
63
63
|
var import_sdk_config = require("@cowprotocol/sdk-config");
|
|
64
64
|
var DEFAULT_QUOTE_VALIDITY = 60 * 30;
|
|
65
65
|
var DEFAULT_SLIPPAGE_BPS = 50;
|
|
66
|
-
var ETH_FLOW_DEFAULT_SLIPPAGE_BPS =
|
|
67
|
-
...(0, import_sdk_config.mapSupportedNetworks)(DEFAULT_SLIPPAGE_BPS),
|
|
68
|
-
// 0.5% by default for most chains
|
|
69
|
-
[import_sdk_config.SupportedChainId.MAINNET]: 200
|
|
70
|
-
// 2% for mainnet
|
|
71
|
-
};
|
|
66
|
+
var ETH_FLOW_DEFAULT_SLIPPAGE_BPS = (0, import_sdk_config.mapSupportedNetworks)(DEFAULT_SLIPPAGE_BPS);
|
|
72
67
|
var SIGN_SCHEME_MAP = {
|
|
73
68
|
[import_sdk_order_book.EcdsaSigningScheme.EIP712]: import_sdk_order_book.SigningScheme.EIP712,
|
|
74
69
|
[import_sdk_order_book.EcdsaSigningScheme.ETHSIGN]: import_sdk_order_book.SigningScheme.ETHSIGN
|
|
75
70
|
};
|
|
76
71
|
var GAS_LIMIT_DEFAULT = BigInt(15e4);
|
|
72
|
+
var ERC20_APPROVE_ABI = [
|
|
73
|
+
{
|
|
74
|
+
constant: false,
|
|
75
|
+
inputs: [
|
|
76
|
+
{
|
|
77
|
+
name: "_spender",
|
|
78
|
+
type: "address"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "_value",
|
|
82
|
+
type: "uint256"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
name: "approve",
|
|
86
|
+
outputs: [
|
|
87
|
+
{
|
|
88
|
+
name: "",
|
|
89
|
+
type: "bool"
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
payable: false,
|
|
93
|
+
stateMutability: "nonpayable",
|
|
94
|
+
type: "function"
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
98
|
+
{
|
|
99
|
+
constant: true,
|
|
100
|
+
inputs: [
|
|
101
|
+
{
|
|
102
|
+
name: "_owner",
|
|
103
|
+
type: "address"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "_spender",
|
|
107
|
+
type: "address"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
name: "allowance",
|
|
111
|
+
outputs: [
|
|
112
|
+
{
|
|
113
|
+
name: "",
|
|
114
|
+
type: "uint256"
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
payable: false,
|
|
118
|
+
stateMutability: "view",
|
|
119
|
+
type: "function"
|
|
120
|
+
}
|
|
121
|
+
];
|
|
77
122
|
|
|
78
123
|
// src/postCoWProtocolTrade.ts
|
|
79
124
|
var import_sdk_order_signing2 = require("@cowprotocol/sdk-order-signing");
|
|
@@ -365,10 +410,18 @@ async function postSellNativeCurrencyOrder(orderBookApi, appData, _params, addit
|
|
|
365
410
|
}
|
|
366
411
|
|
|
367
412
|
// src/postCoWProtocolTrade.ts
|
|
413
|
+
var import_sdk_common5 = require("@cowprotocol/sdk-common");
|
|
414
|
+
|
|
415
|
+
// src/utils/resolveSigner.ts
|
|
368
416
|
var import_sdk_common4 = require("@cowprotocol/sdk-common");
|
|
369
|
-
|
|
417
|
+
function resolveSigner(signer) {
|
|
370
418
|
const adapter = (0, import_sdk_common4.getGlobalAdapter)();
|
|
371
|
-
|
|
419
|
+
return signer ? adapter.createSigner(signer) : adapter.signer;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// src/postCoWProtocolTrade.ts
|
|
423
|
+
async function postCoWProtocolTrade(orderBookApi, appData, params, additionalParams = {}, paramSigner) {
|
|
424
|
+
const signer = resolveSigner(paramSigner);
|
|
372
425
|
const { networkCostsAmount = "0", signingScheme: _signingScheme = import_sdk_order_book4.SigningScheme.EIP712 } = additionalParams;
|
|
373
426
|
const isEthFlow = getIsEthFlowOrder(params);
|
|
374
427
|
if (isEthFlow) {
|
|
@@ -384,7 +437,7 @@ async function postCoWProtocolTrade(orderBookApi, appData, params, additionalPar
|
|
|
384
437
|
const chainId = orderBookApi.context.chainId;
|
|
385
438
|
const from = owner || await signer.getAddress();
|
|
386
439
|
const orderToSign = getOrderToSign({ chainId, from, networkCostsAmount, isEthFlow }, params, appData.appDataKeccak256);
|
|
387
|
-
(0,
|
|
440
|
+
(0, import_sdk_common5.log)("Signing order...");
|
|
388
441
|
const { signature, signingScheme } = await (async () => {
|
|
389
442
|
if (_signingScheme === import_sdk_order_book4.SigningScheme.PRESIGN) {
|
|
390
443
|
return { signature: from, signingScheme: import_sdk_order_book4.SigningScheme.PRESIGN };
|
|
@@ -402,24 +455,24 @@ async function postCoWProtocolTrade(orderBookApi, appData, params, additionalPar
|
|
|
402
455
|
appData: fullAppData,
|
|
403
456
|
appDataHash: appDataKeccak256
|
|
404
457
|
};
|
|
405
|
-
(0,
|
|
458
|
+
(0, import_sdk_common5.log)("Posting order...");
|
|
406
459
|
const orderId = await orderBookApi.sendOrder(orderBody);
|
|
407
|
-
(0,
|
|
460
|
+
(0, import_sdk_common5.log)(`Order created, id: ${orderId}`);
|
|
408
461
|
return { orderId, signature, signingScheme, orderToSign };
|
|
409
462
|
}
|
|
410
463
|
|
|
411
464
|
// src/getQuote.ts
|
|
412
|
-
var
|
|
413
|
-
var
|
|
465
|
+
var import_sdk_common11 = require("@cowprotocol/sdk-common");
|
|
466
|
+
var import_sdk_order_book7 = require("@cowprotocol/sdk-order-book");
|
|
414
467
|
|
|
415
468
|
// src/appDataUtils.ts
|
|
416
469
|
var import_sdk_app_data = require("@cowprotocol/sdk-app-data");
|
|
417
|
-
var
|
|
470
|
+
var import_sdk_common6 = require("@cowprotocol/sdk-common");
|
|
418
471
|
var import_deepmerge = __toESM(require("deepmerge"));
|
|
419
472
|
async function buildAppData({ slippageBps, appCode, orderClass: orderClassName, partnerFee }, advancedParams) {
|
|
420
473
|
const quoteParams = { slippageBips: slippageBps };
|
|
421
474
|
const orderClass = { orderClass: orderClassName };
|
|
422
|
-
const metadataApiSdk = new import_sdk_app_data.MetadataApi((0,
|
|
475
|
+
const metadataApiSdk = new import_sdk_app_data.MetadataApi((0, import_sdk_common6.getGlobalAdapter)());
|
|
423
476
|
const doc = await metadataApiSdk.generateAppDataDoc(
|
|
424
477
|
(0, import_deepmerge.default)(
|
|
425
478
|
{
|
|
@@ -437,7 +490,7 @@ async function buildAppData({ slippageBps, appCode, orderClass: orderClassName,
|
|
|
437
490
|
return { doc, fullAppData, appDataKeccak256 };
|
|
438
491
|
}
|
|
439
492
|
async function generateAppDataFromDoc(doc) {
|
|
440
|
-
const adapter = (0,
|
|
493
|
+
const adapter = (0, import_sdk_common6.getGlobalAdapter)();
|
|
441
494
|
const fullAppData = await (0, import_sdk_app_data.stringifyDeterministic)(doc);
|
|
442
495
|
const appDataKeccak256 = adapter.utils.keccak256(adapter.utils.toUtf8Bytes(fullAppData));
|
|
443
496
|
return { fullAppData, appDataKeccak256 };
|
|
@@ -486,12 +539,16 @@ async function getOrderTypedData(chainId, orderToSign) {
|
|
|
486
539
|
};
|
|
487
540
|
}
|
|
488
541
|
|
|
542
|
+
// src/resolveSlippageSuggestion.ts
|
|
543
|
+
var import_sdk_common10 = require("@cowprotocol/sdk-common");
|
|
544
|
+
var import_sdk_order_book6 = require("@cowprotocol/sdk-order-book");
|
|
545
|
+
|
|
489
546
|
// src/suggestSlippageBps.ts
|
|
490
|
-
var
|
|
547
|
+
var import_sdk_common9 = require("@cowprotocol/sdk-common");
|
|
491
548
|
var import_sdk_order_book5 = require("@cowprotocol/sdk-order-book");
|
|
492
549
|
|
|
493
550
|
// src/suggestSlippageFromFee.ts
|
|
494
|
-
var
|
|
551
|
+
var import_sdk_common7 = require("@cowprotocol/sdk-common");
|
|
495
552
|
function suggestSlippageFromFee(params) {
|
|
496
553
|
const { feeAmount, multiplyingFactorPercent } = params;
|
|
497
554
|
if (feeAmount < 0n) {
|
|
@@ -500,11 +557,11 @@ function suggestSlippageFromFee(params) {
|
|
|
500
557
|
if (multiplyingFactorPercent < 0) {
|
|
501
558
|
throw new Error("multiplyingFactorPercent must be non-negative: " + multiplyingFactorPercent);
|
|
502
559
|
}
|
|
503
|
-
return (0,
|
|
560
|
+
return (0, import_sdk_common7.applyPercentage)(feeAmount, multiplyingFactorPercent);
|
|
504
561
|
}
|
|
505
562
|
|
|
506
563
|
// src/suggestSlippageFromVolume.ts
|
|
507
|
-
var
|
|
564
|
+
var import_sdk_common8 = require("@cowprotocol/sdk-common");
|
|
508
565
|
function suggestSlippageFromVolume(params) {
|
|
509
566
|
const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params;
|
|
510
567
|
const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts;
|
|
@@ -514,7 +571,7 @@ function suggestSlippageFromVolume(params) {
|
|
|
514
571
|
if (slippagePercent < 0) {
|
|
515
572
|
throw new Error("slippagePercent must be non-negative: " + slippagePercent);
|
|
516
573
|
}
|
|
517
|
-
return (0,
|
|
574
|
+
return (0, import_sdk_common8.applyPercentage)(sellAmount, slippagePercent);
|
|
518
575
|
}
|
|
519
576
|
|
|
520
577
|
// src/suggestSlippageBps.ts
|
|
@@ -522,7 +579,13 @@ var MAX_SLIPPAGE_BPS = 1e4;
|
|
|
522
579
|
var SLIPPAGE_FEE_MULTIPLIER_PERCENT = 50;
|
|
523
580
|
var SLIPPAGE_VOLUME_MULTIPLIER_PERCENT = 0.5;
|
|
524
581
|
function suggestSlippageBps(params) {
|
|
525
|
-
const {
|
|
582
|
+
const {
|
|
583
|
+
quote,
|
|
584
|
+
tradeParameters,
|
|
585
|
+
trader,
|
|
586
|
+
isEthFlow,
|
|
587
|
+
volumeMultiplierPercent = SLIPPAGE_VOLUME_MULTIPLIER_PERCENT
|
|
588
|
+
} = params;
|
|
526
589
|
const { sellTokenDecimals, buyTokenDecimals } = tradeParameters;
|
|
527
590
|
const { isSell, sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts } = (0, import_sdk_order_book5.getQuoteAmountsWithCosts)({
|
|
528
591
|
sellDecimals: sellTokenDecimals,
|
|
@@ -539,7 +602,7 @@ function suggestSlippageBps(params) {
|
|
|
539
602
|
isSell,
|
|
540
603
|
sellAmountBeforeNetworkCosts,
|
|
541
604
|
sellAmountAfterNetworkCosts,
|
|
542
|
-
slippagePercent:
|
|
605
|
+
slippagePercent: volumeMultiplierPercent
|
|
543
606
|
});
|
|
544
607
|
const totalSlippageBps = slippageBpsFromFee + slippageBpsFromVolume;
|
|
545
608
|
const slippagePercent = getSlippagePercent({
|
|
@@ -548,13 +611,57 @@ function suggestSlippageBps(params) {
|
|
|
548
611
|
sellAmountAfterNetworkCosts,
|
|
549
612
|
slippage: totalSlippageBps
|
|
550
613
|
});
|
|
551
|
-
const slippageBps = (0,
|
|
552
|
-
|
|
614
|
+
const slippageBps = (0, import_sdk_common9.percentageToBps)(slippagePercent);
|
|
615
|
+
const lowerCap = isEthFlow ? ETH_FLOW_DEFAULT_SLIPPAGE_BPS[trader.chainId] : 0;
|
|
616
|
+
return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), lowerCap);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// src/resolveSlippageSuggestion.ts
|
|
620
|
+
async function resolveSlippageSuggestion(chainId, tradeParameters, trader, quote, isEthFlow, advancedSettings) {
|
|
621
|
+
const suggestSlippageParams = {
|
|
622
|
+
isEthFlow,
|
|
623
|
+
quote,
|
|
624
|
+
tradeParameters,
|
|
625
|
+
trader,
|
|
626
|
+
advancedSettings
|
|
627
|
+
};
|
|
628
|
+
const getSlippageSuggestion = advancedSettings?.getSlippageSuggestion;
|
|
629
|
+
const priceQuality = advancedSettings?.quoteRequest?.priceQuality ?? import_sdk_order_book6.PriceQuality.OPTIMAL;
|
|
630
|
+
const defaultSuggestion = suggestSlippageBps(suggestSlippageParams);
|
|
631
|
+
if (priceQuality === import_sdk_order_book6.PriceQuality.FAST || !getSlippageSuggestion) {
|
|
632
|
+
return { slippageBps: defaultSuggestion };
|
|
633
|
+
}
|
|
634
|
+
const amountsAndCosts = (0, import_sdk_order_book6.getQuoteAmountsAndCosts)({
|
|
635
|
+
orderParams: quote.quote,
|
|
636
|
+
slippagePercentBps: 0,
|
|
637
|
+
partnerFeeBps: getPartnerFeeBps(tradeParameters.partnerFee),
|
|
638
|
+
sellDecimals: tradeParameters.sellTokenDecimals,
|
|
639
|
+
buyDecimals: tradeParameters.buyTokenDecimals
|
|
640
|
+
});
|
|
641
|
+
try {
|
|
642
|
+
const suggestedSlippage = await getSlippageSuggestion({
|
|
643
|
+
chainId,
|
|
644
|
+
sellToken: tradeParameters.sellToken,
|
|
645
|
+
buyToken: tradeParameters.buyToken,
|
|
646
|
+
sellAmount: amountsAndCosts.afterSlippage.sellAmount,
|
|
647
|
+
buyAmount: amountsAndCosts.afterSlippage.buyAmount
|
|
648
|
+
});
|
|
649
|
+
const suggestedSlippageBps = suggestedSlippage.slippageBps;
|
|
650
|
+
return {
|
|
651
|
+
slippageBps: suggestedSlippageBps ? suggestSlippageBps({
|
|
652
|
+
...suggestSlippageParams,
|
|
653
|
+
volumeMultiplierPercent: (0, import_sdk_common10.bpsToPercentage)(suggestedSlippageBps)
|
|
654
|
+
}) : defaultSuggestion
|
|
655
|
+
};
|
|
656
|
+
} catch (e) {
|
|
657
|
+
(0, import_sdk_common10.log)(`getSlippageSuggestion() error: ${e.message || String(e)}`);
|
|
658
|
+
return { slippageBps: defaultSuggestion };
|
|
659
|
+
}
|
|
553
660
|
}
|
|
554
661
|
|
|
555
662
|
// src/getQuote.ts
|
|
556
663
|
var ETH_FLOW_AUX_QUOTE_PARAMS = {
|
|
557
|
-
signingScheme:
|
|
664
|
+
signingScheme: import_sdk_order_book7.SigningScheme.EIP1271,
|
|
558
665
|
onchainOrder: true,
|
|
559
666
|
// Ethflow orders are subsidized in the backend.
|
|
560
667
|
// This means we can assume the verification gas costs are zero for the quote/fee estimation
|
|
@@ -570,17 +677,22 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
570
677
|
amount,
|
|
571
678
|
kind,
|
|
572
679
|
partnerFee,
|
|
573
|
-
validFor
|
|
680
|
+
validFor,
|
|
681
|
+
validTo,
|
|
574
682
|
slippageBps,
|
|
575
683
|
env = "prod"
|
|
576
684
|
} = tradeParameters;
|
|
577
|
-
(0
|
|
685
|
+
if (validTo !== void 0 && validFor !== void 0) {
|
|
686
|
+
throw new Error("Cannot specify both validFor and validTo. Use validFor for relative time or validTo for absolute time.");
|
|
687
|
+
}
|
|
688
|
+
const effectiveValidFor = validFor ?? DEFAULT_QUOTE_VALIDITY;
|
|
689
|
+
(0, import_sdk_common11.log)(
|
|
578
690
|
`getQuote for: Swap ${amount} ${sellToken} for ${buyToken} on chain ${chainId} with ${slippageBps !== void 0 ? `${slippageBps} BPS` : "AUTO"} slippage`
|
|
579
691
|
);
|
|
580
|
-
const orderBookApi = _orderBookApi || new
|
|
692
|
+
const orderBookApi = _orderBookApi || new import_sdk_order_book7.OrderBookApi({ chainId, env });
|
|
581
693
|
const receiver = tradeParameters.receiver || from;
|
|
582
694
|
const isSell = kind === "sell";
|
|
583
|
-
(0,
|
|
695
|
+
(0, import_sdk_common11.log)("Building app data...");
|
|
584
696
|
const defaultSlippageBps = getDefaultSlippageBps(chainId, isEthFlow);
|
|
585
697
|
const slippageBpsOrDefault = slippageBps ?? defaultSlippageBps;
|
|
586
698
|
const buildAppDataParams = {
|
|
@@ -591,40 +703,41 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
591
703
|
};
|
|
592
704
|
const appDataInfo = await buildAppData(buildAppDataParams, advancedSettings?.appData);
|
|
593
705
|
const { appDataKeccak256, fullAppData } = appDataInfo;
|
|
594
|
-
(0,
|
|
706
|
+
(0, import_sdk_common11.log)(`App data: appDataKeccak256=${appDataKeccak256} fullAppData=${fullAppData}`);
|
|
595
707
|
const quoteRequest = {
|
|
596
708
|
from,
|
|
597
709
|
sellToken,
|
|
598
710
|
buyToken,
|
|
599
711
|
receiver,
|
|
600
|
-
validFor,
|
|
712
|
+
...validTo !== void 0 ? { validTo } : { validFor: effectiveValidFor },
|
|
601
713
|
appData: fullAppData,
|
|
602
714
|
appDataHash: appDataKeccak256,
|
|
603
|
-
priceQuality:
|
|
715
|
+
priceQuality: import_sdk_order_book7.PriceQuality.OPTIMAL,
|
|
604
716
|
// Do not change this parameter because we rely on the fact that quote has id
|
|
605
|
-
signingScheme:
|
|
717
|
+
signingScheme: import_sdk_order_book7.SigningScheme.EIP712,
|
|
606
718
|
...isEthFlow ? ETH_FLOW_AUX_QUOTE_PARAMS : {},
|
|
607
|
-
...isSell ? { kind:
|
|
719
|
+
...isSell ? { kind: import_sdk_order_book7.OrderQuoteSideKindSell.SELL, sellAmountBeforeFee: amount } : { kind: import_sdk_order_book7.OrderQuoteSideKindBuy.BUY, buyAmountAfterFee: amount },
|
|
608
720
|
...advancedSettings?.quoteRequest
|
|
609
721
|
};
|
|
610
|
-
(0,
|
|
722
|
+
(0, import_sdk_common11.log)("Getting quote...");
|
|
611
723
|
const quote = await orderBookApi.getQuote(quoteRequest);
|
|
612
|
-
const suggestedSlippageBps =
|
|
613
|
-
|
|
614
|
-
quote,
|
|
724
|
+
const { slippageBps: suggestedSlippageBps } = await resolveSlippageSuggestion(
|
|
725
|
+
chainId,
|
|
615
726
|
tradeParameters,
|
|
616
727
|
trader,
|
|
728
|
+
quote,
|
|
729
|
+
isEthFlow,
|
|
617
730
|
advancedSettings
|
|
618
|
-
|
|
731
|
+
);
|
|
619
732
|
const commonResult = {
|
|
620
733
|
isEthFlow,
|
|
621
734
|
quote,
|
|
622
735
|
orderBookApi,
|
|
623
|
-
suggestedSlippageBps
|
|
736
|
+
suggestedSlippageBps: suggestedSlippageBps || defaultSlippageBps
|
|
624
737
|
};
|
|
625
738
|
if (slippageBps === void 0) {
|
|
626
|
-
if (suggestedSlippageBps
|
|
627
|
-
(0,
|
|
739
|
+
if (suggestedSlippageBps) {
|
|
740
|
+
(0, import_sdk_common11.log)(
|
|
628
741
|
`Suggested slippage is greater than ${defaultSlippageBps} BPS (default), using the suggested slippage (${suggestedSlippageBps} BPS)`
|
|
629
742
|
);
|
|
630
743
|
const newAppDataInfo = await buildAppData(
|
|
@@ -634,7 +747,7 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
634
747
|
},
|
|
635
748
|
advancedSettings?.appData
|
|
636
749
|
);
|
|
637
|
-
(0,
|
|
750
|
+
(0, import_sdk_common11.log)(
|
|
638
751
|
`App data with new suggested slippage: appDataKeccak256=${newAppDataInfo.appDataKeccak256} fullAppData=${newAppDataInfo.fullAppData}`
|
|
639
752
|
);
|
|
640
753
|
return {
|
|
@@ -644,9 +757,7 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
644
757
|
slippageBps: suggestedSlippageBps
|
|
645
758
|
};
|
|
646
759
|
} else {
|
|
647
|
-
(0,
|
|
648
|
-
`Suggested slippage is only ${suggestedSlippageBps} BPS. Using the default slippage (${defaultSlippageBps} BPS)`
|
|
649
|
-
);
|
|
760
|
+
(0, import_sdk_common11.log)(`No suggested slippage. Using the default slippage (${defaultSlippageBps} BPS)`);
|
|
650
761
|
}
|
|
651
762
|
}
|
|
652
763
|
return {
|
|
@@ -661,7 +772,7 @@ async function getQuote(_tradeParameters, trader, advancedSettings, _orderBookAp
|
|
|
661
772
|
const { quote, orderBookApi, tradeParameters, slippageBps, suggestedSlippageBps, appDataInfo, isEthFlow } = await getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBookApi);
|
|
662
773
|
const { partnerFee, sellTokenDecimals, buyTokenDecimals } = tradeParameters;
|
|
663
774
|
const { chainId, account: from } = trader;
|
|
664
|
-
const amountsAndCosts = (0,
|
|
775
|
+
const amountsAndCosts = (0, import_sdk_order_book7.getQuoteAmountsAndCosts)({
|
|
665
776
|
orderParams: quote.quote,
|
|
666
777
|
slippagePercentBps: slippageBps,
|
|
667
778
|
partnerFeeBps: getPartnerFeeBps(partnerFee),
|
|
@@ -688,7 +799,7 @@ async function getQuote(_tradeParameters, trader, advancedSettings, _orderBookAp
|
|
|
688
799
|
};
|
|
689
800
|
}
|
|
690
801
|
async function getTrader(swapParameters) {
|
|
691
|
-
const signer = (0,
|
|
802
|
+
const signer = (0, import_sdk_common11.getGlobalAdapter)().signerOrNull();
|
|
692
803
|
const account = swapParameters.owner || await signer?.getAddress();
|
|
693
804
|
return {
|
|
694
805
|
chainId: swapParameters.chainId,
|
|
@@ -697,8 +808,7 @@ async function getTrader(swapParameters) {
|
|
|
697
808
|
};
|
|
698
809
|
}
|
|
699
810
|
async function getQuoteWithSigner(swapParameters, advancedSettings, orderBookApi) {
|
|
700
|
-
const
|
|
701
|
-
const signer = swapParameters.signer ? adapter.createSigner(swapParameters.signer) : adapter.signer;
|
|
811
|
+
const signer = resolveSigner(swapParameters.signer);
|
|
702
812
|
const trader = await getTrader(swapParameters);
|
|
703
813
|
const result = await getQuote(swapParameters, trader, advancedSettings, orderBookApi);
|
|
704
814
|
return {
|
|
@@ -754,8 +864,8 @@ async function postSwapOrderFromQuote({
|
|
|
754
864
|
}
|
|
755
865
|
|
|
756
866
|
// src/postLimitOrder.ts
|
|
757
|
-
var
|
|
758
|
-
var
|
|
867
|
+
var import_sdk_order_book8 = require("@cowprotocol/sdk-order-book");
|
|
868
|
+
var import_sdk_common12 = require("@cowprotocol/sdk-common");
|
|
759
869
|
async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
760
870
|
const appDataSlippage = advancedSettings?.appData?.metadata?.quote?.slippageBips;
|
|
761
871
|
const partnerFeeOverride = advancedSettings?.appData?.metadata?.partnerFee;
|
|
@@ -772,9 +882,9 @@ async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
|
772
882
|
params.env = "prod";
|
|
773
883
|
}
|
|
774
884
|
const { appCode, chainId, sellToken, buyToken, sellAmount, buyAmount, partnerFee } = params;
|
|
775
|
-
(0,
|
|
776
|
-
const orderBookApi = _orderBookApi || new
|
|
777
|
-
(0,
|
|
885
|
+
(0, import_sdk_common12.log)(`Limit order ${sellAmount} ${sellToken} for ${buyAmount} ${buyToken} on chain ${chainId}`);
|
|
886
|
+
const orderBookApi = _orderBookApi || new import_sdk_order_book8.OrderBookApi({ chainId, env: params.env });
|
|
887
|
+
(0, import_sdk_common12.log)("Building app data...");
|
|
778
888
|
const appDataInfo = await buildAppData(
|
|
779
889
|
{
|
|
780
890
|
slippageBps: params.slippageBps,
|
|
@@ -787,35 +897,109 @@ async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
|
787
897
|
return postCoWProtocolTrade(orderBookApi, appDataInfo, params, advancedSettings?.additionalParams, params.signer);
|
|
788
898
|
}
|
|
789
899
|
|
|
790
|
-
// src/
|
|
900
|
+
// src/getSettlementContract.ts
|
|
901
|
+
var import_sdk_common13 = require("@cowprotocol/sdk-common");
|
|
791
902
|
var import_sdk_config5 = require("@cowprotocol/sdk-config");
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
903
|
+
function getSettlementContract(chainId, signer) {
|
|
904
|
+
return import_sdk_common13.ContractFactory.createSettlementContract(import_sdk_config5.COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], signer);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
// src/getPreSignTransaction.ts
|
|
908
|
+
async function getPreSignTransaction(signer, chainId, orderId) {
|
|
909
|
+
const contract = getSettlementContract(chainId, signer);
|
|
796
910
|
const preSignatureCall = contract.interface.encodeFunctionData("setPreSignature", [orderId, true]);
|
|
797
911
|
const gas = await contract.estimateGas.setPreSignature?.(orderId, true).catch(() => GAS_LIMIT_DEFAULT) || GAS_LIMIT_DEFAULT;
|
|
798
912
|
return {
|
|
799
913
|
data: preSignatureCall,
|
|
800
914
|
gasLimit: "0x" + calculateGasMargin(gas).toString(16),
|
|
801
|
-
to:
|
|
802
|
-
// Para onde enviar a transação
|
|
915
|
+
to: contract.address,
|
|
803
916
|
value: "0"
|
|
804
917
|
};
|
|
805
918
|
}
|
|
806
919
|
|
|
807
920
|
// src/tradingSdk.ts
|
|
808
|
-
var
|
|
809
|
-
var
|
|
921
|
+
var import_sdk_common14 = require("@cowprotocol/sdk-common");
|
|
922
|
+
var import_sdk_order_signing4 = require("@cowprotocol/sdk-order-signing");
|
|
923
|
+
|
|
924
|
+
// src/onChainCancellation.ts
|
|
925
|
+
var CANCELLATION_GAS_LIMIT_DEFAULT = 150000n;
|
|
926
|
+
async function getEthFlowCancellation(ethFlowContract, order) {
|
|
927
|
+
const cancelOrderParams = {
|
|
928
|
+
buyToken: order.buyToken,
|
|
929
|
+
receiver: order.receiver || order.owner,
|
|
930
|
+
sellAmount: order.sellAmount,
|
|
931
|
+
buyAmount: order.buyAmount,
|
|
932
|
+
appData: order.appData.toString(),
|
|
933
|
+
feeAmount: order.feeAmount,
|
|
934
|
+
validTo: order.validTo.toString(),
|
|
935
|
+
partiallyFillable: false,
|
|
936
|
+
quoteId: 0
|
|
937
|
+
// value doesn't matter, set to 0 for reducing gas costs
|
|
938
|
+
};
|
|
939
|
+
return getOnChainCancellation(ethFlowContract, cancelOrderParams);
|
|
940
|
+
}
|
|
941
|
+
async function getSettlementCancellation(settlementContract, order) {
|
|
942
|
+
const cancelOrderParams = order.uid;
|
|
943
|
+
return getOnChainCancellation(settlementContract, cancelOrderParams);
|
|
944
|
+
}
|
|
945
|
+
async function getOnChainCancellation(contract, cancelOrderParams) {
|
|
946
|
+
const estimatedGas = await (async () => {
|
|
947
|
+
try {
|
|
948
|
+
if (contract.estimateGas.invalidateOrder) {
|
|
949
|
+
const estimated = await contract.estimateGas.invalidateOrder(cancelOrderParams);
|
|
950
|
+
return BigInt(estimated.toHexString ? estimated.toHexString() : `0x${estimated.toString(16)}`);
|
|
951
|
+
}
|
|
952
|
+
return CANCELLATION_GAS_LIMIT_DEFAULT;
|
|
953
|
+
} catch (error) {
|
|
954
|
+
console.error(error);
|
|
955
|
+
return CANCELLATION_GAS_LIMIT_DEFAULT;
|
|
956
|
+
}
|
|
957
|
+
})();
|
|
958
|
+
const data = contract.interface.encodeFunctionData("invalidateOrder", [cancelOrderParams]);
|
|
959
|
+
return {
|
|
960
|
+
estimatedGas,
|
|
961
|
+
transaction: {
|
|
962
|
+
data,
|
|
963
|
+
gasLimit: "0x" + estimatedGas.toString(16),
|
|
964
|
+
to: contract.address,
|
|
965
|
+
value: "0x0"
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/utils/resolveOrderBookApi.ts
|
|
971
|
+
var import_sdk_order_book9 = require("@cowprotocol/sdk-order-book");
|
|
972
|
+
var orderBookApiCache = /* @__PURE__ */ new Map([
|
|
973
|
+
["prod", /* @__PURE__ */ new Map()],
|
|
974
|
+
["staging", /* @__PURE__ */ new Map()]
|
|
975
|
+
]);
|
|
976
|
+
function resolveOrderBookApi(chainId, env, existingOrderBookApi) {
|
|
977
|
+
if (existingOrderBookApi) {
|
|
978
|
+
existingOrderBookApi.context.chainId = chainId;
|
|
979
|
+
existingOrderBookApi.context.env = env;
|
|
980
|
+
return existingOrderBookApi;
|
|
981
|
+
}
|
|
982
|
+
const envCache = orderBookApiCache.get(env) ?? /* @__PURE__ */ new Map();
|
|
983
|
+
const cached = envCache.get(chainId);
|
|
984
|
+
if (cached)
|
|
985
|
+
return cached;
|
|
986
|
+
const orderBookApi = new import_sdk_order_book9.OrderBookApi({ chainId, env });
|
|
987
|
+
envCache.set(chainId, orderBookApi);
|
|
988
|
+
orderBookApiCache.set(env, envCache);
|
|
989
|
+
return orderBookApi;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// src/tradingSdk.ts
|
|
993
|
+
var import_sdk_config6 = require("@cowprotocol/sdk-config");
|
|
810
994
|
var TradingSdk = class {
|
|
811
995
|
constructor(traderParams = {}, options = {}, adapter) {
|
|
812
996
|
this.traderParams = traderParams;
|
|
813
997
|
this.options = options;
|
|
814
998
|
if (options.enableLogging !== void 0) {
|
|
815
|
-
(0,
|
|
999
|
+
(0, import_sdk_common14.enableLogging)(options.enableLogging);
|
|
816
1000
|
}
|
|
817
1001
|
if (adapter) {
|
|
818
|
-
(0,
|
|
1002
|
+
(0, import_sdk_common14.setGlobalAdapter)(adapter);
|
|
819
1003
|
}
|
|
820
1004
|
}
|
|
821
1005
|
setTraderParams(params) {
|
|
@@ -847,7 +1031,7 @@ var TradingSdk = class {
|
|
|
847
1031
|
}),
|
|
848
1032
|
// It's important to get a fresh instance of the signer
|
|
849
1033
|
// Because quote might be called with another signer
|
|
850
|
-
signer: (0,
|
|
1034
|
+
signer: (0, import_sdk_common14.getGlobalAdapter)().signer
|
|
851
1035
|
}
|
|
852
1036
|
},
|
|
853
1037
|
advancedSettings2
|
|
@@ -908,16 +1092,123 @@ var TradingSdk = class {
|
|
|
908
1092
|
);
|
|
909
1093
|
}
|
|
910
1094
|
async getPreSignTransaction(params) {
|
|
911
|
-
const adapter = (0, import_sdk_common12.getGlobalAdapter)();
|
|
912
1095
|
const traderParams = this.mergeParams(params);
|
|
913
|
-
const signer =
|
|
914
|
-
return getPreSignTransaction(signer, traderParams.chainId, params.
|
|
1096
|
+
const signer = resolveSigner(traderParams.signer);
|
|
1097
|
+
return getPreSignTransaction(signer, traderParams.chainId, params.orderUid);
|
|
1098
|
+
}
|
|
1099
|
+
async getOrder(params) {
|
|
1100
|
+
const orderBookApi = this.resolveOrderBookApi(params);
|
|
1101
|
+
return orderBookApi.getOrder(params.orderUid);
|
|
1102
|
+
}
|
|
1103
|
+
async offChainCancelOrder(params) {
|
|
1104
|
+
const orderBookApi = this.resolveOrderBookApi(params);
|
|
1105
|
+
const signer = resolveSigner(params.signer);
|
|
1106
|
+
const { orderUid } = params;
|
|
1107
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1108
|
+
if (!chainId) {
|
|
1109
|
+
throw new Error("Chain ID is missing in offChainCancelOrder() call");
|
|
1110
|
+
}
|
|
1111
|
+
const orderCancellationSigning = await import_sdk_order_signing4.OrderSigningUtils.signOrderCancellations([orderUid], chainId, signer);
|
|
1112
|
+
await orderBookApi.sendSignedOrderCancellations({
|
|
1113
|
+
...orderCancellationSigning,
|
|
1114
|
+
orderUids: [orderUid]
|
|
1115
|
+
});
|
|
1116
|
+
return true;
|
|
1117
|
+
}
|
|
1118
|
+
async onChainCancelOrder(params, _order) {
|
|
1119
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1120
|
+
if (!chainId) {
|
|
1121
|
+
throw new Error("Chain ID is missing in offChainCancelOrder() call");
|
|
1122
|
+
}
|
|
1123
|
+
const order = _order ?? await this.getOrder(params);
|
|
1124
|
+
const isEthFlowOrder = !!order.onchainOrderData;
|
|
1125
|
+
const signer = params.signer ? (0, import_sdk_common14.getGlobalAdapter)().createSigner(params.signer) : (0, import_sdk_common14.getGlobalAdapter)().signer;
|
|
1126
|
+
const { transaction } = await (isEthFlowOrder ? getEthFlowCancellation(getEthFlowContract(signer, chainId, params.env ?? this.traderParams.env), order) : getSettlementCancellation(getSettlementContract(chainId, signer), order));
|
|
1127
|
+
const txReceipt = await signer.sendTransaction(transaction);
|
|
1128
|
+
return txReceipt.hash;
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Checks the current allowance for the CoW Protocol Vault Relayer to spend an ERC-20 token.
|
|
1132
|
+
*
|
|
1133
|
+
* @param params - Parameters including token address and owner address
|
|
1134
|
+
* @returns Promise resolving to the current allowance amount as a bigint
|
|
1135
|
+
*
|
|
1136
|
+
* @example
|
|
1137
|
+
* ```typescript
|
|
1138
|
+
* const params = {
|
|
1139
|
+
* tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1140
|
+
* owner: '0x123...',
|
|
1141
|
+
* chainId: 1,
|
|
1142
|
+
* }
|
|
1143
|
+
*
|
|
1144
|
+
* const allowance = await sdk.getCowProtocolAllowance(params)
|
|
1145
|
+
* console.log('Current allowance:', allowance.toString())
|
|
1146
|
+
* ```
|
|
1147
|
+
*/
|
|
1148
|
+
async getCowProtocolAllowance(params) {
|
|
1149
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1150
|
+
if (!chainId) {
|
|
1151
|
+
throw new Error("Chain ID is missing in getCowProtocolAllowance() call");
|
|
1152
|
+
}
|
|
1153
|
+
const adapter = (0, import_sdk_common14.getGlobalAdapter)();
|
|
1154
|
+
const vaultRelayerAddress = import_sdk_config6.COW_PROTOCOL_VAULT_RELAYER_ADDRESS[chainId];
|
|
1155
|
+
return await adapter.readContract({
|
|
1156
|
+
address: params.tokenAddress,
|
|
1157
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
1158
|
+
functionName: "allowance",
|
|
1159
|
+
args: [params.owner, vaultRelayerAddress]
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Approves the CoW Protocol Vault Relayer to spend a specified amount of an ERC-20 token.
|
|
1164
|
+
* This method creates an on-chain approval transaction.
|
|
1165
|
+
*
|
|
1166
|
+
* @param params - Parameters including token address and amount to approve
|
|
1167
|
+
* @returns Promise resolving to the transaction hash of the approval transaction
|
|
1168
|
+
*
|
|
1169
|
+
* @example
|
|
1170
|
+
* ```typescript
|
|
1171
|
+
* const params = {
|
|
1172
|
+
* tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1173
|
+
* amount: '1000000000', // 1000 USDC (6 decimals)
|
|
1174
|
+
* chainId: 1,
|
|
1175
|
+
* }
|
|
1176
|
+
*
|
|
1177
|
+
* const txHash = await sdk.approveCowProtocol(params)
|
|
1178
|
+
* console.log('Approval transaction:', txHash)
|
|
1179
|
+
* ```
|
|
1180
|
+
*/
|
|
1181
|
+
async approveCowProtocol(params) {
|
|
1182
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1183
|
+
if (!chainId) {
|
|
1184
|
+
throw new Error("Chain ID is missing in approveCowProtocol() call");
|
|
1185
|
+
}
|
|
1186
|
+
const adapter = (0, import_sdk_common14.getGlobalAdapter)();
|
|
1187
|
+
const signer = resolveSigner(params.signer);
|
|
1188
|
+
const vaultRelayerAddress = import_sdk_config6.COW_PROTOCOL_VAULT_RELAYER_ADDRESS[chainId];
|
|
1189
|
+
const txParams = {
|
|
1190
|
+
to: params.tokenAddress,
|
|
1191
|
+
data: adapter.utils.encodeFunction(ERC20_APPROVE_ABI, "approve", [
|
|
1192
|
+
vaultRelayerAddress,
|
|
1193
|
+
"0x" + params.amount.toString(16)
|
|
1194
|
+
])
|
|
1195
|
+
};
|
|
1196
|
+
const txReceipt = await signer.sendTransaction(txParams);
|
|
1197
|
+
return txReceipt.hash;
|
|
1198
|
+
}
|
|
1199
|
+
resolveOrderBookApi(params) {
|
|
1200
|
+
const chainId = params.chainId ?? this.traderParams.chainId;
|
|
1201
|
+
const env = params.env ?? this.traderParams.env ?? "prod";
|
|
1202
|
+
if (!chainId) {
|
|
1203
|
+
throw new Error("Chain ID is missing in getOrder() call");
|
|
1204
|
+
}
|
|
1205
|
+
return resolveOrderBookApi(chainId, env);
|
|
915
1206
|
}
|
|
916
1207
|
mergeParams(params) {
|
|
917
1208
|
const { chainId, signer, appCode, env } = params;
|
|
918
1209
|
const traderParams = {
|
|
919
1210
|
chainId: chainId || this.traderParams.chainId,
|
|
920
|
-
signer: signer || this.traderParams.signer || (0,
|
|
1211
|
+
signer: signer || this.traderParams.signer || (0, import_sdk_common14.getGlobalAdapter)().signer,
|
|
921
1212
|
appCode: appCode || this.traderParams.appCode,
|
|
922
1213
|
env: env || this.traderParams.env
|
|
923
1214
|
};
|