@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/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, SupportedChainId } from "@cowprotocol/sdk-config";
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 { getGlobalAdapter as getGlobalAdapter3, log as log2 } from "@cowprotocol/sdk-common";
324
- async function postCoWProtocolTrade(orderBookApi, appData, params, additionalParams = {}, paramSigner) {
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
- const signer = paramSigner ? adapter.createSigner(paramSigner) : adapter.signer;
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 log3 } from "@cowprotocol/sdk-common";
420
+ import { getGlobalAdapter as getGlobalAdapter5, log as log4 } from "@cowprotocol/sdk-common";
368
421
  import {
369
- getQuoteAmountsAndCosts as getQuoteAmountsAndCosts2,
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 { quote, tradeParameters, trader, isEthFlow } = params;
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: SLIPPAGE_VOLUME_MULTIPLIER_PERCENT
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
- return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), getDefaultSlippageBps(trader.chainId, isEthFlow));
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 = DEFAULT_QUOTE_VALIDITY,
645
+ validFor,
646
+ validTo,
539
647
  slippageBps,
540
648
  env = "prod"
541
649
  } = tradeParameters;
542
- log3(
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
- log3("Building app data...");
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
- log3(`App data: appDataKeccak256=${appDataKeccak256} fullAppData=${fullAppData}`);
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: PriceQuality.OPTIMAL,
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
- log3("Getting quote...");
687
+ log4("Getting quote...");
576
688
  const quote = await orderBookApi.getQuote(quoteRequest);
577
- const suggestedSlippageBps = suggestSlippageBps({
578
- isEthFlow,
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 > defaultSlippageBps) {
592
- log3(
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
- log3(
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
- log3(
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 = getQuoteAmountsAndCosts2({
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 adapter = getGlobalAdapter5();
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 log4 } from "@cowprotocol/sdk-common";
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
- log4(`Limit order ${sellAmount} ${sellToken} for ${buyAmount} ${buyToken} on chain ${chainId}`);
850
+ log5(`Limit order ${sellAmount} ${sellToken} for ${buyAmount} ${buyToken} on chain ${chainId}`);
741
851
  const orderBookApi = _orderBookApi || new OrderBookApi4({ chainId, env: params.env });
742
- log4("Building app data...");
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/getPreSignTransaction.ts
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
- async function getPreSignTransaction(signer, chainId, account, orderId) {
759
- const contract = ContractFactory2.createSettlementContract(account, signer);
760
- const settlementContractAddress = COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS[chainId];
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: settlementContractAddress,
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 { setGlobalAdapter } from "@cowprotocol/sdk-common";
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 = traderParams.signer ? adapter.createSigner(traderParams.signer) : adapter.signer;
879
- return getPreSignTransaction(signer, traderParams.chainId, params.account, params.orderId);
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.2-beta.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.5-beta.0",
33
- "@cowprotocol/sdk-ethers-v6-adapter": "0.2.5-beta.0",
34
- "@cowprotocol/sdk-viem-adapter": "0.3.1-beta.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.5.0-beta.0",
39
- "@cowprotocol/sdk-config": "0.3.3-beta.0",
40
- "@cowprotocol/sdk-app-data": "4.1.7-beta.0",
41
- "@cowprotocol/sdk-order-book": "0.3.1-beta.0",
42
- "@cowprotocol/sdk-contracts-ts": "2.3.0-beta.0",
43
- "@cowprotocol/sdk-order-signing": "0.2.8-beta.0"
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",