@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.mjs
CHANGED
|
@@ -3,20 +3,65 @@ import { SigningScheme as SigningScheme3 } from "@cowprotocol/sdk-order-book";
|
|
|
3
3
|
|
|
4
4
|
// src/consts.ts
|
|
5
5
|
import { EcdsaSigningScheme, SigningScheme } from "@cowprotocol/sdk-order-book";
|
|
6
|
-
import { mapSupportedNetworks
|
|
6
|
+
import { mapSupportedNetworks } from "@cowprotocol/sdk-config";
|
|
7
7
|
var DEFAULT_QUOTE_VALIDITY = 60 * 30;
|
|
8
8
|
var DEFAULT_SLIPPAGE_BPS = 50;
|
|
9
|
-
var ETH_FLOW_DEFAULT_SLIPPAGE_BPS =
|
|
10
|
-
...mapSupportedNetworks(DEFAULT_SLIPPAGE_BPS),
|
|
11
|
-
// 0.5% by default for most chains
|
|
12
|
-
[SupportedChainId.MAINNET]: 200
|
|
13
|
-
// 2% for mainnet
|
|
14
|
-
};
|
|
9
|
+
var ETH_FLOW_DEFAULT_SLIPPAGE_BPS = mapSupportedNetworks(DEFAULT_SLIPPAGE_BPS);
|
|
15
10
|
var SIGN_SCHEME_MAP = {
|
|
16
11
|
[EcdsaSigningScheme.EIP712]: SigningScheme.EIP712,
|
|
17
12
|
[EcdsaSigningScheme.ETHSIGN]: SigningScheme.ETHSIGN
|
|
18
13
|
};
|
|
19
14
|
var GAS_LIMIT_DEFAULT = BigInt(15e4);
|
|
15
|
+
var ERC20_APPROVE_ABI = [
|
|
16
|
+
{
|
|
17
|
+
constant: false,
|
|
18
|
+
inputs: [
|
|
19
|
+
{
|
|
20
|
+
name: "_spender",
|
|
21
|
+
type: "address"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "_value",
|
|
25
|
+
type: "uint256"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
name: "approve",
|
|
29
|
+
outputs: [
|
|
30
|
+
{
|
|
31
|
+
name: "",
|
|
32
|
+
type: "bool"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
payable: false,
|
|
36
|
+
stateMutability: "nonpayable",
|
|
37
|
+
type: "function"
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
41
|
+
{
|
|
42
|
+
constant: true,
|
|
43
|
+
inputs: [
|
|
44
|
+
{
|
|
45
|
+
name: "_owner",
|
|
46
|
+
type: "address"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "_spender",
|
|
50
|
+
type: "address"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
name: "allowance",
|
|
54
|
+
outputs: [
|
|
55
|
+
{
|
|
56
|
+
name: "",
|
|
57
|
+
type: "uint256"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
payable: false,
|
|
61
|
+
stateMutability: "view",
|
|
62
|
+
type: "function"
|
|
63
|
+
}
|
|
64
|
+
];
|
|
20
65
|
|
|
21
66
|
// src/postCoWProtocolTrade.ts
|
|
22
67
|
import { OrderSigningUtils as OrderSigningUtils2 } from "@cowprotocol/sdk-order-signing";
|
|
@@ -320,10 +365,18 @@ async function postSellNativeCurrencyOrder(orderBookApi, appData, _params, addit
|
|
|
320
365
|
}
|
|
321
366
|
|
|
322
367
|
// src/postCoWProtocolTrade.ts
|
|
323
|
-
import {
|
|
324
|
-
|
|
368
|
+
import { log as log2 } from "@cowprotocol/sdk-common";
|
|
369
|
+
|
|
370
|
+
// src/utils/resolveSigner.ts
|
|
371
|
+
import { getGlobalAdapter as getGlobalAdapter3 } from "@cowprotocol/sdk-common";
|
|
372
|
+
function resolveSigner(signer) {
|
|
325
373
|
const adapter = getGlobalAdapter3();
|
|
326
|
-
|
|
374
|
+
return signer ? adapter.createSigner(signer) : adapter.signer;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// src/postCoWProtocolTrade.ts
|
|
378
|
+
async function postCoWProtocolTrade(orderBookApi, appData, params, additionalParams = {}, paramSigner) {
|
|
379
|
+
const signer = resolveSigner(paramSigner);
|
|
327
380
|
const { networkCostsAmount = "0", signingScheme: _signingScheme = SigningScheme3.EIP712 } = additionalParams;
|
|
328
381
|
const isEthFlow = getIsEthFlowOrder(params);
|
|
329
382
|
if (isEthFlow) {
|
|
@@ -364,13 +417,13 @@ async function postCoWProtocolTrade(orderBookApi, appData, params, additionalPar
|
|
|
364
417
|
}
|
|
365
418
|
|
|
366
419
|
// src/getQuote.ts
|
|
367
|
-
import { getGlobalAdapter as getGlobalAdapter5, log as
|
|
420
|
+
import { getGlobalAdapter as getGlobalAdapter5, log as log4 } from "@cowprotocol/sdk-common";
|
|
368
421
|
import {
|
|
369
|
-
getQuoteAmountsAndCosts as
|
|
422
|
+
getQuoteAmountsAndCosts as getQuoteAmountsAndCosts3,
|
|
370
423
|
OrderBookApi as OrderBookApi3,
|
|
371
424
|
OrderQuoteSideKindBuy,
|
|
372
425
|
OrderQuoteSideKindSell,
|
|
373
|
-
PriceQuality,
|
|
426
|
+
PriceQuality as PriceQuality2,
|
|
374
427
|
SigningScheme as SigningScheme4
|
|
375
428
|
} from "@cowprotocol/sdk-order-book";
|
|
376
429
|
|
|
@@ -451,6 +504,10 @@ async function getOrderTypedData(chainId, orderToSign) {
|
|
|
451
504
|
};
|
|
452
505
|
}
|
|
453
506
|
|
|
507
|
+
// src/resolveSlippageSuggestion.ts
|
|
508
|
+
import { bpsToPercentage, log as log3 } from "@cowprotocol/sdk-common";
|
|
509
|
+
import { getQuoteAmountsAndCosts as getQuoteAmountsAndCosts2, PriceQuality } from "@cowprotocol/sdk-order-book";
|
|
510
|
+
|
|
454
511
|
// src/suggestSlippageBps.ts
|
|
455
512
|
import { percentageToBps } from "@cowprotocol/sdk-common";
|
|
456
513
|
import { getQuoteAmountsWithCosts } from "@cowprotocol/sdk-order-book";
|
|
@@ -487,7 +544,13 @@ var MAX_SLIPPAGE_BPS = 1e4;
|
|
|
487
544
|
var SLIPPAGE_FEE_MULTIPLIER_PERCENT = 50;
|
|
488
545
|
var SLIPPAGE_VOLUME_MULTIPLIER_PERCENT = 0.5;
|
|
489
546
|
function suggestSlippageBps(params) {
|
|
490
|
-
const {
|
|
547
|
+
const {
|
|
548
|
+
quote,
|
|
549
|
+
tradeParameters,
|
|
550
|
+
trader,
|
|
551
|
+
isEthFlow,
|
|
552
|
+
volumeMultiplierPercent = SLIPPAGE_VOLUME_MULTIPLIER_PERCENT
|
|
553
|
+
} = params;
|
|
491
554
|
const { sellTokenDecimals, buyTokenDecimals } = tradeParameters;
|
|
492
555
|
const { isSell, sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts } = getQuoteAmountsWithCosts({
|
|
493
556
|
sellDecimals: sellTokenDecimals,
|
|
@@ -504,7 +567,7 @@ function suggestSlippageBps(params) {
|
|
|
504
567
|
isSell,
|
|
505
568
|
sellAmountBeforeNetworkCosts,
|
|
506
569
|
sellAmountAfterNetworkCosts,
|
|
507
|
-
slippagePercent:
|
|
570
|
+
slippagePercent: volumeMultiplierPercent
|
|
508
571
|
});
|
|
509
572
|
const totalSlippageBps = slippageBpsFromFee + slippageBpsFromVolume;
|
|
510
573
|
const slippagePercent = getSlippagePercent({
|
|
@@ -514,7 +577,51 @@ function suggestSlippageBps(params) {
|
|
|
514
577
|
slippage: totalSlippageBps
|
|
515
578
|
});
|
|
516
579
|
const slippageBps = percentageToBps(slippagePercent);
|
|
517
|
-
|
|
580
|
+
const lowerCap = isEthFlow ? ETH_FLOW_DEFAULT_SLIPPAGE_BPS[trader.chainId] : 0;
|
|
581
|
+
return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), lowerCap);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/resolveSlippageSuggestion.ts
|
|
585
|
+
async function resolveSlippageSuggestion(chainId, tradeParameters, trader, quote, isEthFlow, advancedSettings) {
|
|
586
|
+
const suggestSlippageParams = {
|
|
587
|
+
isEthFlow,
|
|
588
|
+
quote,
|
|
589
|
+
tradeParameters,
|
|
590
|
+
trader,
|
|
591
|
+
advancedSettings
|
|
592
|
+
};
|
|
593
|
+
const getSlippageSuggestion = advancedSettings?.getSlippageSuggestion;
|
|
594
|
+
const priceQuality = advancedSettings?.quoteRequest?.priceQuality ?? PriceQuality.OPTIMAL;
|
|
595
|
+
const defaultSuggestion = suggestSlippageBps(suggestSlippageParams);
|
|
596
|
+
if (priceQuality === PriceQuality.FAST || !getSlippageSuggestion) {
|
|
597
|
+
return { slippageBps: defaultSuggestion };
|
|
598
|
+
}
|
|
599
|
+
const amountsAndCosts = getQuoteAmountsAndCosts2({
|
|
600
|
+
orderParams: quote.quote,
|
|
601
|
+
slippagePercentBps: 0,
|
|
602
|
+
partnerFeeBps: getPartnerFeeBps(tradeParameters.partnerFee),
|
|
603
|
+
sellDecimals: tradeParameters.sellTokenDecimals,
|
|
604
|
+
buyDecimals: tradeParameters.buyTokenDecimals
|
|
605
|
+
});
|
|
606
|
+
try {
|
|
607
|
+
const suggestedSlippage = await getSlippageSuggestion({
|
|
608
|
+
chainId,
|
|
609
|
+
sellToken: tradeParameters.sellToken,
|
|
610
|
+
buyToken: tradeParameters.buyToken,
|
|
611
|
+
sellAmount: amountsAndCosts.afterSlippage.sellAmount,
|
|
612
|
+
buyAmount: amountsAndCosts.afterSlippage.buyAmount
|
|
613
|
+
});
|
|
614
|
+
const suggestedSlippageBps = suggestedSlippage.slippageBps;
|
|
615
|
+
return {
|
|
616
|
+
slippageBps: suggestedSlippageBps ? suggestSlippageBps({
|
|
617
|
+
...suggestSlippageParams,
|
|
618
|
+
volumeMultiplierPercent: bpsToPercentage(suggestedSlippageBps)
|
|
619
|
+
}) : defaultSuggestion
|
|
620
|
+
};
|
|
621
|
+
} catch (e) {
|
|
622
|
+
log3(`getSlippageSuggestion() error: ${e.message || String(e)}`);
|
|
623
|
+
return { slippageBps: defaultSuggestion };
|
|
624
|
+
}
|
|
518
625
|
}
|
|
519
626
|
|
|
520
627
|
// src/getQuote.ts
|
|
@@ -535,17 +642,22 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
535
642
|
amount,
|
|
536
643
|
kind,
|
|
537
644
|
partnerFee,
|
|
538
|
-
validFor
|
|
645
|
+
validFor,
|
|
646
|
+
validTo,
|
|
539
647
|
slippageBps,
|
|
540
648
|
env = "prod"
|
|
541
649
|
} = tradeParameters;
|
|
542
|
-
|
|
650
|
+
if (validTo !== void 0 && validFor !== void 0) {
|
|
651
|
+
throw new Error("Cannot specify both validFor and validTo. Use validFor for relative time or validTo for absolute time.");
|
|
652
|
+
}
|
|
653
|
+
const effectiveValidFor = validFor ?? DEFAULT_QUOTE_VALIDITY;
|
|
654
|
+
log4(
|
|
543
655
|
`getQuote for: Swap ${amount} ${sellToken} for ${buyToken} on chain ${chainId} with ${slippageBps !== void 0 ? `${slippageBps} BPS` : "AUTO"} slippage`
|
|
544
656
|
);
|
|
545
657
|
const orderBookApi = _orderBookApi || new OrderBookApi3({ chainId, env });
|
|
546
658
|
const receiver = tradeParameters.receiver || from;
|
|
547
659
|
const isSell = kind === "sell";
|
|
548
|
-
|
|
660
|
+
log4("Building app data...");
|
|
549
661
|
const defaultSlippageBps = getDefaultSlippageBps(chainId, isEthFlow);
|
|
550
662
|
const slippageBpsOrDefault = slippageBps ?? defaultSlippageBps;
|
|
551
663
|
const buildAppDataParams = {
|
|
@@ -556,40 +668,41 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
556
668
|
};
|
|
557
669
|
const appDataInfo = await buildAppData(buildAppDataParams, advancedSettings?.appData);
|
|
558
670
|
const { appDataKeccak256, fullAppData } = appDataInfo;
|
|
559
|
-
|
|
671
|
+
log4(`App data: appDataKeccak256=${appDataKeccak256} fullAppData=${fullAppData}`);
|
|
560
672
|
const quoteRequest = {
|
|
561
673
|
from,
|
|
562
674
|
sellToken,
|
|
563
675
|
buyToken,
|
|
564
676
|
receiver,
|
|
565
|
-
validFor,
|
|
677
|
+
...validTo !== void 0 ? { validTo } : { validFor: effectiveValidFor },
|
|
566
678
|
appData: fullAppData,
|
|
567
679
|
appDataHash: appDataKeccak256,
|
|
568
|
-
priceQuality:
|
|
680
|
+
priceQuality: PriceQuality2.OPTIMAL,
|
|
569
681
|
// Do not change this parameter because we rely on the fact that quote has id
|
|
570
682
|
signingScheme: SigningScheme4.EIP712,
|
|
571
683
|
...isEthFlow ? ETH_FLOW_AUX_QUOTE_PARAMS : {},
|
|
572
684
|
...isSell ? { kind: OrderQuoteSideKindSell.SELL, sellAmountBeforeFee: amount } : { kind: OrderQuoteSideKindBuy.BUY, buyAmountAfterFee: amount },
|
|
573
685
|
...advancedSettings?.quoteRequest
|
|
574
686
|
};
|
|
575
|
-
|
|
687
|
+
log4("Getting quote...");
|
|
576
688
|
const quote = await orderBookApi.getQuote(quoteRequest);
|
|
577
|
-
const suggestedSlippageBps =
|
|
578
|
-
|
|
579
|
-
quote,
|
|
689
|
+
const { slippageBps: suggestedSlippageBps } = await resolveSlippageSuggestion(
|
|
690
|
+
chainId,
|
|
580
691
|
tradeParameters,
|
|
581
692
|
trader,
|
|
693
|
+
quote,
|
|
694
|
+
isEthFlow,
|
|
582
695
|
advancedSettings
|
|
583
|
-
|
|
696
|
+
);
|
|
584
697
|
const commonResult = {
|
|
585
698
|
isEthFlow,
|
|
586
699
|
quote,
|
|
587
700
|
orderBookApi,
|
|
588
|
-
suggestedSlippageBps
|
|
701
|
+
suggestedSlippageBps: suggestedSlippageBps || defaultSlippageBps
|
|
589
702
|
};
|
|
590
703
|
if (slippageBps === void 0) {
|
|
591
|
-
if (suggestedSlippageBps
|
|
592
|
-
|
|
704
|
+
if (suggestedSlippageBps) {
|
|
705
|
+
log4(
|
|
593
706
|
`Suggested slippage is greater than ${defaultSlippageBps} BPS (default), using the suggested slippage (${suggestedSlippageBps} BPS)`
|
|
594
707
|
);
|
|
595
708
|
const newAppDataInfo = await buildAppData(
|
|
@@ -599,7 +712,7 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
599
712
|
},
|
|
600
713
|
advancedSettings?.appData
|
|
601
714
|
);
|
|
602
|
-
|
|
715
|
+
log4(
|
|
603
716
|
`App data with new suggested slippage: appDataKeccak256=${newAppDataInfo.appDataKeccak256} fullAppData=${newAppDataInfo.fullAppData}`
|
|
604
717
|
);
|
|
605
718
|
return {
|
|
@@ -609,9 +722,7 @@ async function getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBoo
|
|
|
609
722
|
slippageBps: suggestedSlippageBps
|
|
610
723
|
};
|
|
611
724
|
} else {
|
|
612
|
-
|
|
613
|
-
`Suggested slippage is only ${suggestedSlippageBps} BPS. Using the default slippage (${defaultSlippageBps} BPS)`
|
|
614
|
-
);
|
|
725
|
+
log4(`No suggested slippage. Using the default slippage (${defaultSlippageBps} BPS)`);
|
|
615
726
|
}
|
|
616
727
|
}
|
|
617
728
|
return {
|
|
@@ -626,7 +737,7 @@ async function getQuote(_tradeParameters, trader, advancedSettings, _orderBookAp
|
|
|
626
737
|
const { quote, orderBookApi, tradeParameters, slippageBps, suggestedSlippageBps, appDataInfo, isEthFlow } = await getQuoteRaw(_tradeParameters, trader, advancedSettings, _orderBookApi);
|
|
627
738
|
const { partnerFee, sellTokenDecimals, buyTokenDecimals } = tradeParameters;
|
|
628
739
|
const { chainId, account: from } = trader;
|
|
629
|
-
const amountsAndCosts =
|
|
740
|
+
const amountsAndCosts = getQuoteAmountsAndCosts3({
|
|
630
741
|
orderParams: quote.quote,
|
|
631
742
|
slippagePercentBps: slippageBps,
|
|
632
743
|
partnerFeeBps: getPartnerFeeBps(partnerFee),
|
|
@@ -662,8 +773,7 @@ async function getTrader(swapParameters) {
|
|
|
662
773
|
};
|
|
663
774
|
}
|
|
664
775
|
async function getQuoteWithSigner(swapParameters, advancedSettings, orderBookApi) {
|
|
665
|
-
const
|
|
666
|
-
const signer = swapParameters.signer ? adapter.createSigner(swapParameters.signer) : adapter.signer;
|
|
776
|
+
const signer = resolveSigner(swapParameters.signer);
|
|
667
777
|
const trader = await getTrader(swapParameters);
|
|
668
778
|
const result = await getQuote(swapParameters, trader, advancedSettings, orderBookApi);
|
|
669
779
|
return {
|
|
@@ -720,7 +830,7 @@ async function postSwapOrderFromQuote({
|
|
|
720
830
|
|
|
721
831
|
// src/postLimitOrder.ts
|
|
722
832
|
import { OrderBookApi as OrderBookApi4 } from "@cowprotocol/sdk-order-book";
|
|
723
|
-
import { log as
|
|
833
|
+
import { log as log5 } from "@cowprotocol/sdk-common";
|
|
724
834
|
async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
725
835
|
const appDataSlippage = advancedSettings?.appData?.metadata?.quote?.slippageBips;
|
|
726
836
|
const partnerFeeOverride = advancedSettings?.appData?.metadata?.partnerFee;
|
|
@@ -737,9 +847,9 @@ async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
|
737
847
|
params.env = "prod";
|
|
738
848
|
}
|
|
739
849
|
const { appCode, chainId, sellToken, buyToken, sellAmount, buyAmount, partnerFee } = params;
|
|
740
|
-
|
|
850
|
+
log5(`Limit order ${sellAmount} ${sellToken} for ${buyAmount} ${buyToken} on chain ${chainId}`);
|
|
741
851
|
const orderBookApi = _orderBookApi || new OrderBookApi4({ chainId, env: params.env });
|
|
742
|
-
|
|
852
|
+
log5("Building app data...");
|
|
743
853
|
const appDataInfo = await buildAppData(
|
|
744
854
|
{
|
|
745
855
|
slippageBps: params.slippageBps,
|
|
@@ -752,26 +862,100 @@ async function postLimitOrder(params, advancedSettings, _orderBookApi) {
|
|
|
752
862
|
return postCoWProtocolTrade(orderBookApi, appDataInfo, params, advancedSettings?.additionalParams, params.signer);
|
|
753
863
|
}
|
|
754
864
|
|
|
755
|
-
// src/
|
|
756
|
-
import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from "@cowprotocol/sdk-config";
|
|
865
|
+
// src/getSettlementContract.ts
|
|
757
866
|
import { ContractFactory as ContractFactory2 } from "@cowprotocol/sdk-common";
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
867
|
+
import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from "@cowprotocol/sdk-config";
|
|
868
|
+
function getSettlementContract(chainId, signer) {
|
|
869
|
+
return ContractFactory2.createSettlementContract(COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId], signer);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// src/getPreSignTransaction.ts
|
|
873
|
+
async function getPreSignTransaction(signer, chainId, orderId) {
|
|
874
|
+
const contract = getSettlementContract(chainId, signer);
|
|
761
875
|
const preSignatureCall = contract.interface.encodeFunctionData("setPreSignature", [orderId, true]);
|
|
762
876
|
const gas = await contract.estimateGas.setPreSignature?.(orderId, true).catch(() => GAS_LIMIT_DEFAULT) || GAS_LIMIT_DEFAULT;
|
|
763
877
|
return {
|
|
764
878
|
data: preSignatureCall,
|
|
765
879
|
gasLimit: "0x" + calculateGasMargin(gas).toString(16),
|
|
766
|
-
to:
|
|
767
|
-
// Para onde enviar a transação
|
|
880
|
+
to: contract.address,
|
|
768
881
|
value: "0"
|
|
769
882
|
};
|
|
770
883
|
}
|
|
771
884
|
|
|
772
885
|
// src/tradingSdk.ts
|
|
773
|
-
import { enableLogging, getGlobalAdapter as getGlobalAdapter6 } from "@cowprotocol/sdk-common";
|
|
774
|
-
import {
|
|
886
|
+
import { enableLogging, getGlobalAdapter as getGlobalAdapter6, setGlobalAdapter } from "@cowprotocol/sdk-common";
|
|
887
|
+
import { OrderSigningUtils as OrderSigningUtils4 } from "@cowprotocol/sdk-order-signing";
|
|
888
|
+
|
|
889
|
+
// src/onChainCancellation.ts
|
|
890
|
+
var CANCELLATION_GAS_LIMIT_DEFAULT = 150000n;
|
|
891
|
+
async function getEthFlowCancellation(ethFlowContract, order) {
|
|
892
|
+
const cancelOrderParams = {
|
|
893
|
+
buyToken: order.buyToken,
|
|
894
|
+
receiver: order.receiver || order.owner,
|
|
895
|
+
sellAmount: order.sellAmount,
|
|
896
|
+
buyAmount: order.buyAmount,
|
|
897
|
+
appData: order.appData.toString(),
|
|
898
|
+
feeAmount: order.feeAmount,
|
|
899
|
+
validTo: order.validTo.toString(),
|
|
900
|
+
partiallyFillable: false,
|
|
901
|
+
quoteId: 0
|
|
902
|
+
// value doesn't matter, set to 0 for reducing gas costs
|
|
903
|
+
};
|
|
904
|
+
return getOnChainCancellation(ethFlowContract, cancelOrderParams);
|
|
905
|
+
}
|
|
906
|
+
async function getSettlementCancellation(settlementContract, order) {
|
|
907
|
+
const cancelOrderParams = order.uid;
|
|
908
|
+
return getOnChainCancellation(settlementContract, cancelOrderParams);
|
|
909
|
+
}
|
|
910
|
+
async function getOnChainCancellation(contract, cancelOrderParams) {
|
|
911
|
+
const estimatedGas = await (async () => {
|
|
912
|
+
try {
|
|
913
|
+
if (contract.estimateGas.invalidateOrder) {
|
|
914
|
+
const estimated = await contract.estimateGas.invalidateOrder(cancelOrderParams);
|
|
915
|
+
return BigInt(estimated.toHexString ? estimated.toHexString() : `0x${estimated.toString(16)}`);
|
|
916
|
+
}
|
|
917
|
+
return CANCELLATION_GAS_LIMIT_DEFAULT;
|
|
918
|
+
} catch (error) {
|
|
919
|
+
console.error(error);
|
|
920
|
+
return CANCELLATION_GAS_LIMIT_DEFAULT;
|
|
921
|
+
}
|
|
922
|
+
})();
|
|
923
|
+
const data = contract.interface.encodeFunctionData("invalidateOrder", [cancelOrderParams]);
|
|
924
|
+
return {
|
|
925
|
+
estimatedGas,
|
|
926
|
+
transaction: {
|
|
927
|
+
data,
|
|
928
|
+
gasLimit: "0x" + estimatedGas.toString(16),
|
|
929
|
+
to: contract.address,
|
|
930
|
+
value: "0x0"
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// src/utils/resolveOrderBookApi.ts
|
|
936
|
+
import { OrderBookApi as OrderBookApi5 } from "@cowprotocol/sdk-order-book";
|
|
937
|
+
var orderBookApiCache = /* @__PURE__ */ new Map([
|
|
938
|
+
["prod", /* @__PURE__ */ new Map()],
|
|
939
|
+
["staging", /* @__PURE__ */ new Map()]
|
|
940
|
+
]);
|
|
941
|
+
function resolveOrderBookApi(chainId, env, existingOrderBookApi) {
|
|
942
|
+
if (existingOrderBookApi) {
|
|
943
|
+
existingOrderBookApi.context.chainId = chainId;
|
|
944
|
+
existingOrderBookApi.context.env = env;
|
|
945
|
+
return existingOrderBookApi;
|
|
946
|
+
}
|
|
947
|
+
const envCache = orderBookApiCache.get(env) ?? /* @__PURE__ */ new Map();
|
|
948
|
+
const cached = envCache.get(chainId);
|
|
949
|
+
if (cached)
|
|
950
|
+
return cached;
|
|
951
|
+
const orderBookApi = new OrderBookApi5({ chainId, env });
|
|
952
|
+
envCache.set(chainId, orderBookApi);
|
|
953
|
+
orderBookApiCache.set(env, envCache);
|
|
954
|
+
return orderBookApi;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// src/tradingSdk.ts
|
|
958
|
+
import { COW_PROTOCOL_VAULT_RELAYER_ADDRESS } from "@cowprotocol/sdk-config";
|
|
775
959
|
var TradingSdk = class {
|
|
776
960
|
constructor(traderParams = {}, options = {}, adapter) {
|
|
777
961
|
this.traderParams = traderParams;
|
|
@@ -873,10 +1057,117 @@ var TradingSdk = class {
|
|
|
873
1057
|
);
|
|
874
1058
|
}
|
|
875
1059
|
async getPreSignTransaction(params) {
|
|
876
|
-
const adapter = getGlobalAdapter6();
|
|
877
1060
|
const traderParams = this.mergeParams(params);
|
|
878
|
-
const signer =
|
|
879
|
-
return getPreSignTransaction(signer, traderParams.chainId, params.
|
|
1061
|
+
const signer = resolveSigner(traderParams.signer);
|
|
1062
|
+
return getPreSignTransaction(signer, traderParams.chainId, params.orderUid);
|
|
1063
|
+
}
|
|
1064
|
+
async getOrder(params) {
|
|
1065
|
+
const orderBookApi = this.resolveOrderBookApi(params);
|
|
1066
|
+
return orderBookApi.getOrder(params.orderUid);
|
|
1067
|
+
}
|
|
1068
|
+
async offChainCancelOrder(params) {
|
|
1069
|
+
const orderBookApi = this.resolveOrderBookApi(params);
|
|
1070
|
+
const signer = resolveSigner(params.signer);
|
|
1071
|
+
const { orderUid } = params;
|
|
1072
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1073
|
+
if (!chainId) {
|
|
1074
|
+
throw new Error("Chain ID is missing in offChainCancelOrder() call");
|
|
1075
|
+
}
|
|
1076
|
+
const orderCancellationSigning = await OrderSigningUtils4.signOrderCancellations([orderUid], chainId, signer);
|
|
1077
|
+
await orderBookApi.sendSignedOrderCancellations({
|
|
1078
|
+
...orderCancellationSigning,
|
|
1079
|
+
orderUids: [orderUid]
|
|
1080
|
+
});
|
|
1081
|
+
return true;
|
|
1082
|
+
}
|
|
1083
|
+
async onChainCancelOrder(params, _order) {
|
|
1084
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1085
|
+
if (!chainId) {
|
|
1086
|
+
throw new Error("Chain ID is missing in offChainCancelOrder() call");
|
|
1087
|
+
}
|
|
1088
|
+
const order = _order ?? await this.getOrder(params);
|
|
1089
|
+
const isEthFlowOrder = !!order.onchainOrderData;
|
|
1090
|
+
const signer = params.signer ? getGlobalAdapter6().createSigner(params.signer) : getGlobalAdapter6().signer;
|
|
1091
|
+
const { transaction } = await (isEthFlowOrder ? getEthFlowCancellation(getEthFlowContract(signer, chainId, params.env ?? this.traderParams.env), order) : getSettlementCancellation(getSettlementContract(chainId, signer), order));
|
|
1092
|
+
const txReceipt = await signer.sendTransaction(transaction);
|
|
1093
|
+
return txReceipt.hash;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Checks the current allowance for the CoW Protocol Vault Relayer to spend an ERC-20 token.
|
|
1097
|
+
*
|
|
1098
|
+
* @param params - Parameters including token address and owner address
|
|
1099
|
+
* @returns Promise resolving to the current allowance amount as a bigint
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* ```typescript
|
|
1103
|
+
* const params = {
|
|
1104
|
+
* tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1105
|
+
* owner: '0x123...',
|
|
1106
|
+
* chainId: 1,
|
|
1107
|
+
* }
|
|
1108
|
+
*
|
|
1109
|
+
* const allowance = await sdk.getCowProtocolAllowance(params)
|
|
1110
|
+
* console.log('Current allowance:', allowance.toString())
|
|
1111
|
+
* ```
|
|
1112
|
+
*/
|
|
1113
|
+
async getCowProtocolAllowance(params) {
|
|
1114
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1115
|
+
if (!chainId) {
|
|
1116
|
+
throw new Error("Chain ID is missing in getCowProtocolAllowance() call");
|
|
1117
|
+
}
|
|
1118
|
+
const adapter = getGlobalAdapter6();
|
|
1119
|
+
const vaultRelayerAddress = COW_PROTOCOL_VAULT_RELAYER_ADDRESS[chainId];
|
|
1120
|
+
return await adapter.readContract({
|
|
1121
|
+
address: params.tokenAddress,
|
|
1122
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
1123
|
+
functionName: "allowance",
|
|
1124
|
+
args: [params.owner, vaultRelayerAddress]
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Approves the CoW Protocol Vault Relayer to spend a specified amount of an ERC-20 token.
|
|
1129
|
+
* This method creates an on-chain approval transaction.
|
|
1130
|
+
*
|
|
1131
|
+
* @param params - Parameters including token address and amount to approve
|
|
1132
|
+
* @returns Promise resolving to the transaction hash of the approval transaction
|
|
1133
|
+
*
|
|
1134
|
+
* @example
|
|
1135
|
+
* ```typescript
|
|
1136
|
+
* const params = {
|
|
1137
|
+
* tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
1138
|
+
* amount: '1000000000', // 1000 USDC (6 decimals)
|
|
1139
|
+
* chainId: 1,
|
|
1140
|
+
* }
|
|
1141
|
+
*
|
|
1142
|
+
* const txHash = await sdk.approveCowProtocol(params)
|
|
1143
|
+
* console.log('Approval transaction:', txHash)
|
|
1144
|
+
* ```
|
|
1145
|
+
*/
|
|
1146
|
+
async approveCowProtocol(params) {
|
|
1147
|
+
const chainId = params.chainId || this.traderParams.chainId;
|
|
1148
|
+
if (!chainId) {
|
|
1149
|
+
throw new Error("Chain ID is missing in approveCowProtocol() call");
|
|
1150
|
+
}
|
|
1151
|
+
const adapter = getGlobalAdapter6();
|
|
1152
|
+
const signer = resolveSigner(params.signer);
|
|
1153
|
+
const vaultRelayerAddress = COW_PROTOCOL_VAULT_RELAYER_ADDRESS[chainId];
|
|
1154
|
+
const txParams = {
|
|
1155
|
+
to: params.tokenAddress,
|
|
1156
|
+
data: adapter.utils.encodeFunction(ERC20_APPROVE_ABI, "approve", [
|
|
1157
|
+
vaultRelayerAddress,
|
|
1158
|
+
"0x" + params.amount.toString(16)
|
|
1159
|
+
])
|
|
1160
|
+
};
|
|
1161
|
+
const txReceipt = await signer.sendTransaction(txParams);
|
|
1162
|
+
return txReceipt.hash;
|
|
1163
|
+
}
|
|
1164
|
+
resolveOrderBookApi(params) {
|
|
1165
|
+
const chainId = params.chainId ?? this.traderParams.chainId;
|
|
1166
|
+
const env = params.env ?? this.traderParams.env ?? "prod";
|
|
1167
|
+
if (!chainId) {
|
|
1168
|
+
throw new Error("Chain ID is missing in getOrder() call");
|
|
1169
|
+
}
|
|
1170
|
+
return resolveOrderBookApi(chainId, env);
|
|
880
1171
|
}
|
|
881
1172
|
mergeParams(params) {
|
|
882
1173
|
const { chainId, signer, appCode, env } = params;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cowprotocol/sdk-trading",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "CowProtocol trading",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -29,18 +29,18 @@
|
|
|
29
29
|
"ts-jest": "^29.0.0",
|
|
30
30
|
"tsx": "^4.19.4",
|
|
31
31
|
"@cow-sdk/typescript-config": "0.0.0-beta.0",
|
|
32
|
-
"@cowprotocol/sdk-ethers-v5-adapter": "0.2
|
|
33
|
-
"@cowprotocol/sdk-ethers-v6-adapter": "0.2
|
|
34
|
-
"@cowprotocol/sdk-viem-adapter": "0.
|
|
32
|
+
"@cowprotocol/sdk-ethers-v5-adapter": "0.1.2",
|
|
33
|
+
"@cowprotocol/sdk-ethers-v6-adapter": "0.1.2",
|
|
34
|
+
"@cowprotocol/sdk-viem-adapter": "0.1.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"deepmerge": "^4.3.1",
|
|
38
|
-
"@cowprotocol/sdk-common": "0.
|
|
39
|
-
"@cowprotocol/sdk-config": "0.
|
|
40
|
-
"@cowprotocol/sdk-
|
|
41
|
-
"@cowprotocol/sdk-order-book": "0.
|
|
42
|
-
"@cowprotocol/sdk-contracts-ts": "
|
|
43
|
-
"@cowprotocol/sdk-
|
|
38
|
+
"@cowprotocol/sdk-common": "0.2.1",
|
|
39
|
+
"@cowprotocol/sdk-config": "0.1.0",
|
|
40
|
+
"@cowprotocol/sdk-order-signing": "0.1.6",
|
|
41
|
+
"@cowprotocol/sdk-order-book": "0.1.2",
|
|
42
|
+
"@cowprotocol/sdk-contracts-ts": "0.4.0",
|
|
43
|
+
"@cowprotocol/sdk-app-data": "4.1.2"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|