@cowprotocol/sdk-order-book 0.6.5 → 1.0.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.d.mts CHANGED
@@ -1049,18 +1049,22 @@ interface Costs<T> {
1049
1049
  /**
1050
1050
  * Details about costs and amounts, costs and fees of a quote.
1051
1051
  *
1052
- * CoW Protocol quote has amounts (sell/buy) and costs (network fee), there is also partner fees.
1053
- * Besides that, CoW Protocol supports both sell and buy orders and the fees and costs are calculated differently.
1052
+ * CoW Protocol quote has amounts (sell/buy), network fee, and protocol fee.
1053
+ * On the client side (after /quote response) we add partner fee and slippage.
1054
+ * CoW Protocol supports both sell and buy orders and the fees and costs are calculated differently.
1054
1055
  *
1055
1056
  * The order of adding fees and costs is as follows:
1056
- * 1. Network fee is always added to the sell amount
1057
- * 2. Partner fee is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1058
- * 3. Protocol fee is already baked into the quoted amounts:
1057
+ * 1. Protocol fee is already baked into the quoted amounts:
1059
1058
  * - for SELL orders it has been deducted from the buy amount
1060
- * - for BUY orders it has been added on top of the sell amount.
1059
+ * - for BUY orders it has been added on top of the sell amount
1060
+ * 2. Network fee:
1061
+ * - for SELL orders it has been deducted from the sell amount
1062
+ * - for BUY orders it's not added to any amount, and provided separately as `feeAmount`
1063
+ * 3. Partner fee is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1064
+ * 4. Slippage is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1061
1065
  *
1062
- * For sell-orders the partner fee is subtracted from the buy amount after network costs.
1063
- * For buy-orders the partner fee is added on top of the sell amount after network costs.
1066
+ * For sell-orders the partner fee and slippage are subtracted from the buy amount after network costs.
1067
+ * For buy-orders the partner fee and slippage are added on top of the sell amount after network costs.
1064
1068
  */
1065
1069
  interface QuoteAmountsAndCosts<T = bigint> {
1066
1070
  /**
@@ -1077,6 +1081,9 @@ interface QuoteAmountsAndCosts<T = bigint> {
1077
1081
  * so UIs can decide how to show it to the user.
1078
1082
  */
1079
1083
  costs: Costs<T>;
1084
+ /**
1085
+ * Before all the fees and costs. Spot price amounts
1086
+ */
1080
1087
  beforeAllFees: Amounts<T>;
1081
1088
  /**
1082
1089
  * Amounts before network costs. This amount could be shown to the user to reflect how much they are expected to get
@@ -1084,17 +1091,22 @@ interface QuoteAmountsAndCosts<T = bigint> {
1084
1091
  */
1085
1092
  beforeNetworkCosts: Amounts<T>;
1086
1093
  /**
1087
- * Amounts after including network costs.
1094
+ * 1. Same with beforeNetworkCosts.
1095
+ * `beforeNetworkCosts` was here even before protocol fee existed, and we keep it for backward compatibility
1096
+ */
1097
+ afterProtocolFees: Amounts<T>;
1098
+ /**
1099
+ * 2. Amounts after including network costs.
1088
1100
  */
1089
1101
  afterNetworkCosts: Amounts<T>;
1090
1102
  /**
1091
- * Amounts after including partner fees (if any).
1103
+ * 3. Amounts after including partner fees (if any).
1092
1104
  *
1093
1105
  * This amount could be shown to the user, as the expected to receive amount already including any fees or costs.
1094
1106
  */
1095
1107
  afterPartnerFees: Amounts<T>;
1096
1108
  /**
1097
- * Amounts after including the slippage tolerance.
1109
+ * 4. Amounts after including the slippage tolerance.
1098
1110
  *
1099
1111
  * This is the minimum that the user will receive and the amount they will sign.
1100
1112
  *
@@ -1102,6 +1114,10 @@ interface QuoteAmountsAndCosts<T = bigint> {
1102
1114
  * event of the buy token appreciating.
1103
1115
  */
1104
1116
  afterSlippage: Amounts<T>;
1117
+ /**
1118
+ * Amounts that supposed to be signed as part of order
1119
+ */
1120
+ amountsToSign: Amounts<T>;
1105
1121
  }
1106
1122
 
1107
1123
  /**
@@ -1390,39 +1406,130 @@ interface FetchParams {
1390
1406
  */
1391
1407
  declare function request<T>(baseUrl: string, { path, query, method, body }: FetchParams, rateLimiter: RateLimiter, backoffOpts: BackoffOptions): Promise<T>;
1392
1408
 
1393
- interface QuoteAmountsAndCostsParams {
1394
- orderParams: OrderParameters;
1409
+ type OrderAmountsBig = {
1410
+ sellAmount: bigint;
1411
+ buyAmount: bigint;
1412
+ };
1413
+ interface QuoteParameters {
1395
1414
  sellDecimals: number;
1396
1415
  buyDecimals: number;
1397
- slippagePercentBps: number;
1398
- partnerFeeBps: number | undefined;
1416
+ orderParams: OrderParameters;
1399
1417
  protocolFeeBps: number | undefined;
1400
1418
  }
1401
- declare function getQuoteAmountsWithCosts(params: {
1402
- sellDecimals: number;
1403
- buyDecimals: number;
1419
+ interface QuoteAmountsAndCostsParams {
1404
1420
  orderParams: OrderParameters;
1405
- protocolFeeBps?: number;
1406
- }): {
1421
+ protocolFeeBps: number | undefined;
1422
+ partnerFeeBps: number | undefined;
1423
+ slippagePercentBps: number;
1424
+ }
1425
+ interface QuotePriceParams {
1426
+ numerator: bigint;
1427
+ denominator: bigint;
1428
+ }
1429
+ interface QuoteAmountsWithNetworkCosts {
1407
1430
  isSell: boolean;
1408
- quotePrice: number;
1409
- sellAmountAfterNetworkCosts: bigint;
1410
- buyAmountAfterNetworkCosts: bigint;
1411
- buyAmountBeforeNetworkCosts: bigint;
1431
+ quotePriceParams: QuotePriceParams;
1412
1432
  networkCostAmount: bigint;
1413
1433
  sellAmountBeforeNetworkCosts: bigint;
1414
- };
1434
+ buyAmountAfterNetworkCosts: bigint;
1435
+ sellAmountAfterNetworkCosts: bigint;
1436
+ buyAmountBeforeNetworkCosts: bigint;
1437
+ }
1438
+
1439
+ /**
1440
+ * Calculates all quote amount stages and costs from a `/quote` API response.
1441
+ *
1442
+ * Takes the raw order parameters (where protocol fee and network costs are already baked in)
1443
+ * and reconstructs every intermediate amount stage: before all fees, after protocol fees,
1444
+ * after network costs, after partner fees, and after slippage.
1445
+ *
1446
+ * The returned {@link QuoteAmountsAndCosts} includes `amountsToSign` — the final sell/buy
1447
+ * amounts that should be used when signing the order.
1448
+ *
1449
+ * @see {@link ./README.md} for a detailed explanation of the fee application order.
1450
+ *
1451
+ * @param params - Quote parameters including order params, fee BPS values, and slippage.
1452
+ * @returns All amount stages, cost breakdowns, and the amounts to sign.
1453
+ */
1415
1454
  declare function getQuoteAmountsAndCosts(params: QuoteAmountsAndCostsParams): QuoteAmountsAndCosts;
1416
- type BigNumber = {
1417
- big: bigint;
1418
- num: number;
1419
- };
1455
+
1456
+ interface QuoteAmountsAfterPartnerFeeParams {
1457
+ afterNetworkCosts: Amounts<bigint>;
1458
+ beforeAllFees: Amounts<bigint>;
1459
+ isSell: boolean;
1460
+ partnerFeeBps: number;
1461
+ }
1462
+ interface QuoteAmountsAfterPartnerFee {
1463
+ partnerFeeAmount: bigint;
1464
+ afterPartnerFees: OrderAmountsBig;
1465
+ }
1420
1466
  /**
1421
- * BigInt works well with subtraction and addition, but it's not very good with multiplication and division
1422
- * To multiply/divide token amounts we have to convert them to numbers, but we have to be careful with precision
1423
- * @param value
1424
- * @param decimals
1467
+ * Calculates the partner fee amount and adjusts quote amounts accordingly.
1468
+ *
1469
+ * The partner fee is computed relative to the spot price (`beforeAllFees`) to ensure
1470
+ * it reflects the full trade volume, not the volume already reduced by protocol fee.
1471
+ *
1472
+ * - **SELL orders:** partner fee is subtracted from `buyAmount` (user receives less)
1473
+ * - **BUY orders:** partner fee is added to `sellAmount` (user pays more)
1474
+ *
1475
+ * @param params.afterNetworkCosts - Amounts after network costs, used as the base for adjustment.
1476
+ * @param params.beforeAllFees - Spot price amounts used to calculate the fee percentage.
1477
+ * @param params.isSell - Whether this is a sell order.
1478
+ * @param params.partnerFeeBps - Partner fee in basis points (0 = no partner fee).
1479
+ * @returns The partner fee amount and the adjusted amounts after partner fees.
1480
+ */
1481
+ declare function getQuoteAmountsAfterPartnerFee(params: QuoteAmountsAfterPartnerFeeParams): QuoteAmountsAfterPartnerFee;
1482
+
1483
+ interface QuoteAmountsAfterSlippageParams {
1484
+ afterPartnerFees: OrderAmountsBig;
1485
+ isSell: boolean;
1486
+ slippageBps: number;
1487
+ }
1488
+ interface QuoteAmountsAfterSlippage {
1489
+ afterSlippage: OrderAmountsBig;
1490
+ }
1491
+ /**
1492
+ * Applies slippage tolerance to the quote amounts after all fees have been applied.
1493
+ *
1494
+ * Slippage protects the user from price movements between quoting and execution.
1495
+ * It is always applied to the non-fixed (surplus) side of the order:
1496
+ *
1497
+ * - **SELL orders:** slippage reduces `buyAmount` (user accepts receiving less)
1498
+ * - **BUY orders:** slippage increases `sellAmount` (user accepts paying more)
1499
+ *
1500
+ * @param params.afterPartnerFees - Amounts after partner fees have been applied.
1501
+ * @param params.isSell - Whether this is a sell order.
1502
+ * @param params.slippageBps - Slippage tolerance in basis points.
1503
+ * @returns The adjusted amounts after slippage tolerance.
1504
+ */
1505
+ declare function getQuoteAmountsAfterSlippage(params: QuoteAmountsAfterSlippageParams): QuoteAmountsAfterSlippage;
1506
+
1507
+ interface ProtocolFeeAmountParams {
1508
+ orderParams: OrderParameters;
1509
+ protocolFeeBps: number;
1510
+ }
1511
+ /**
1512
+ * /quote API returns `OrderParameters` where protocol fee is already included in the amounts
1513
+ * From the quote response we only know:
1514
+ * - protocol fee percent (in BPS)
1515
+ * - quote amount after protocol fee
1516
+ *
1517
+ * To get the protocol fee amount, we need to derive the quote amount BEFORE the protocol fee first
1518
+ * On the API side `quoteAmountAfterProtocolFee` is calculated like that:
1519
+ *
1520
+ * protocolFeePercent = 0.02
1521
+ * quoteAmountBeforeProtocolFee = 100_000
1522
+ * protocolFeeAmount = 100_000 * 0.02 / 100 = 20
1523
+ * quoteAmountAfterProtocolFee = 100_000 - 20 = 99_980
1524
+ *
1525
+ * On the client side, we don't know `quoteAmountBeforeProtocolFee`, so we have to reverse it from `quoteAmountAfterProtocolFee`
1526
+ *
1527
+ * quoteAmountBeforeProtocolFee = 99_980 / (1 - 0.02 / 100) = 100_000
1528
+ *
1529
+ * Note: the example above is for SELL orders, for BUY orders the protocol fee is added to sellAmount instead of substracting from buyAmount
1530
+ *
1531
+ * @param params
1425
1532
  */
1426
- declare function getBigNumber(value: string | bigint | number, decimals: number): BigNumber;
1533
+ declare function getProtocolFeeAmount(params: ProtocolFeeAmountParams): bigint;
1427
1534
 
1428
- export { type Address, type Amounts, type AppData, type AppDataHash, type AppDataObject, type Auction, type AuctionOrder, type AuctionPrices, type BigUint, BuyTokenDestination, type CallData, type CompetitionAuction, CompetitionOrderStatus, type Costs, DEFAULT_BACKOFF_OPTIONS, DEFAULT_LIMITER_OPTIONS, type EcdsaSignature, EcdsaSigningScheme, type EnrichedOrder, type EthflowData, type ExecutedAmounts, type ExecutedProtocolFee, type FeePolicy, type FetchParams, type GetOrdersRequest, type GetTradesRequest, type InteractionData, type NativePriceResponse, ORDER_BOOK_PROD_CONFIG, ORDER_BOOK_STAGING_CONFIG, OnchainOrderData, type Order, OrderBookApi, OrderBookApiError, type OrderCancellation, OrderCancellationError, type OrderCancellations, OrderClass, type OrderCreation, OrderKind, type OrderMetaData, type OrderParameters, OrderPostError, type OrderQuoteRequest, type OrderQuoteResponse, type OrderQuoteSide, OrderQuoteSideKindBuy, OrderQuoteSideKindSell, type OrderQuoteValidity, OrderStatus, type PreSignature, PriceEstimationError, type PriceImprovement, PriceQuality, type Quote, type QuoteAmountsAndCosts, type QuoteAmountsAndCostsParams, SellTokenSource, type Signature, SigningScheme, type SolverCompetitionResponse, type SolverSettlement, type Surplus, type TokenAmount, type TotalSurplus, type Trade, type TransactionHash, type UID, type Volume, getBigNumber, getQuoteAmountsAndCosts, getQuoteAmountsWithCosts, request };
1535
+ export { type Address, type Amounts, type AppData, type AppDataHash, type AppDataObject, type Auction, type AuctionOrder, type AuctionPrices, type BigUint, BuyTokenDestination, type CallData, type CompetitionAuction, CompetitionOrderStatus, type Costs, DEFAULT_BACKOFF_OPTIONS, DEFAULT_LIMITER_OPTIONS, type EcdsaSignature, EcdsaSigningScheme, type EnrichedOrder, type EthflowData, type ExecutedAmounts, type ExecutedProtocolFee, type FeePolicy, type FetchParams, type GetOrdersRequest, type GetTradesRequest, type InteractionData, type NativePriceResponse, ORDER_BOOK_PROD_CONFIG, ORDER_BOOK_STAGING_CONFIG, OnchainOrderData, type Order, type OrderAmountsBig, OrderBookApi, OrderBookApiError, type OrderCancellation, OrderCancellationError, type OrderCancellations, OrderClass, type OrderCreation, OrderKind, type OrderMetaData, type OrderParameters, OrderPostError, type OrderQuoteRequest, type OrderQuoteResponse, type OrderQuoteSide, OrderQuoteSideKindBuy, OrderQuoteSideKindSell, type OrderQuoteValidity, OrderStatus, type PreSignature, PriceEstimationError, type PriceImprovement, PriceQuality, type ProtocolFeeAmountParams, type Quote, type QuoteAmountsAfterSlippage, type QuoteAmountsAfterSlippageParams, type QuoteAmountsAndCosts, type QuoteAmountsAndCostsParams, type QuoteAmountsWithNetworkCosts, type QuoteParameters, type QuotePriceParams, SellTokenSource, type Signature, SigningScheme, type SolverCompetitionResponse, type SolverSettlement, type Surplus, type TokenAmount, type TotalSurplus, type Trade, type TransactionHash, type UID, type Volume, getProtocolFeeAmount, getQuoteAmountsAfterPartnerFee, getQuoteAmountsAfterSlippage, getQuoteAmountsAndCosts, request };
package/dist/index.d.ts CHANGED
@@ -1049,18 +1049,22 @@ interface Costs<T> {
1049
1049
  /**
1050
1050
  * Details about costs and amounts, costs and fees of a quote.
1051
1051
  *
1052
- * CoW Protocol quote has amounts (sell/buy) and costs (network fee), there is also partner fees.
1053
- * Besides that, CoW Protocol supports both sell and buy orders and the fees and costs are calculated differently.
1052
+ * CoW Protocol quote has amounts (sell/buy), network fee, and protocol fee.
1053
+ * On the client side (after /quote response) we add partner fee and slippage.
1054
+ * CoW Protocol supports both sell and buy orders and the fees and costs are calculated differently.
1054
1055
  *
1055
1056
  * The order of adding fees and costs is as follows:
1056
- * 1. Network fee is always added to the sell amount
1057
- * 2. Partner fee is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1058
- * 3. Protocol fee is already baked into the quoted amounts:
1057
+ * 1. Protocol fee is already baked into the quoted amounts:
1059
1058
  * - for SELL orders it has been deducted from the buy amount
1060
- * - for BUY orders it has been added on top of the sell amount.
1059
+ * - for BUY orders it has been added on top of the sell amount
1060
+ * 2. Network fee:
1061
+ * - for SELL orders it has been deducted from the sell amount
1062
+ * - for BUY orders it's not added to any amount, and provided separately as `feeAmount`
1063
+ * 3. Partner fee is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1064
+ * 4. Slippage is added to the surplus amount (sell amount for sell-orders, buy amount for buy-orders)
1061
1065
  *
1062
- * For sell-orders the partner fee is subtracted from the buy amount after network costs.
1063
- * For buy-orders the partner fee is added on top of the sell amount after network costs.
1066
+ * For sell-orders the partner fee and slippage are subtracted from the buy amount after network costs.
1067
+ * For buy-orders the partner fee and slippage are added on top of the sell amount after network costs.
1064
1068
  */
1065
1069
  interface QuoteAmountsAndCosts<T = bigint> {
1066
1070
  /**
@@ -1077,6 +1081,9 @@ interface QuoteAmountsAndCosts<T = bigint> {
1077
1081
  * so UIs can decide how to show it to the user.
1078
1082
  */
1079
1083
  costs: Costs<T>;
1084
+ /**
1085
+ * Before all the fees and costs. Spot price amounts
1086
+ */
1080
1087
  beforeAllFees: Amounts<T>;
1081
1088
  /**
1082
1089
  * Amounts before network costs. This amount could be shown to the user to reflect how much they are expected to get
@@ -1084,17 +1091,22 @@ interface QuoteAmountsAndCosts<T = bigint> {
1084
1091
  */
1085
1092
  beforeNetworkCosts: Amounts<T>;
1086
1093
  /**
1087
- * Amounts after including network costs.
1094
+ * 1. Same with beforeNetworkCosts.
1095
+ * `beforeNetworkCosts` was here even before protocol fee existed, and we keep it for backward compatibility
1096
+ */
1097
+ afterProtocolFees: Amounts<T>;
1098
+ /**
1099
+ * 2. Amounts after including network costs.
1088
1100
  */
1089
1101
  afterNetworkCosts: Amounts<T>;
1090
1102
  /**
1091
- * Amounts after including partner fees (if any).
1103
+ * 3. Amounts after including partner fees (if any).
1092
1104
  *
1093
1105
  * This amount could be shown to the user, as the expected to receive amount already including any fees or costs.
1094
1106
  */
1095
1107
  afterPartnerFees: Amounts<T>;
1096
1108
  /**
1097
- * Amounts after including the slippage tolerance.
1109
+ * 4. Amounts after including the slippage tolerance.
1098
1110
  *
1099
1111
  * This is the minimum that the user will receive and the amount they will sign.
1100
1112
  *
@@ -1102,6 +1114,10 @@ interface QuoteAmountsAndCosts<T = bigint> {
1102
1114
  * event of the buy token appreciating.
1103
1115
  */
1104
1116
  afterSlippage: Amounts<T>;
1117
+ /**
1118
+ * Amounts that supposed to be signed as part of order
1119
+ */
1120
+ amountsToSign: Amounts<T>;
1105
1121
  }
1106
1122
 
1107
1123
  /**
@@ -1390,39 +1406,130 @@ interface FetchParams {
1390
1406
  */
1391
1407
  declare function request<T>(baseUrl: string, { path, query, method, body }: FetchParams, rateLimiter: RateLimiter, backoffOpts: BackoffOptions): Promise<T>;
1392
1408
 
1393
- interface QuoteAmountsAndCostsParams {
1394
- orderParams: OrderParameters;
1409
+ type OrderAmountsBig = {
1410
+ sellAmount: bigint;
1411
+ buyAmount: bigint;
1412
+ };
1413
+ interface QuoteParameters {
1395
1414
  sellDecimals: number;
1396
1415
  buyDecimals: number;
1397
- slippagePercentBps: number;
1398
- partnerFeeBps: number | undefined;
1416
+ orderParams: OrderParameters;
1399
1417
  protocolFeeBps: number | undefined;
1400
1418
  }
1401
- declare function getQuoteAmountsWithCosts(params: {
1402
- sellDecimals: number;
1403
- buyDecimals: number;
1419
+ interface QuoteAmountsAndCostsParams {
1404
1420
  orderParams: OrderParameters;
1405
- protocolFeeBps?: number;
1406
- }): {
1421
+ protocolFeeBps: number | undefined;
1422
+ partnerFeeBps: number | undefined;
1423
+ slippagePercentBps: number;
1424
+ }
1425
+ interface QuotePriceParams {
1426
+ numerator: bigint;
1427
+ denominator: bigint;
1428
+ }
1429
+ interface QuoteAmountsWithNetworkCosts {
1407
1430
  isSell: boolean;
1408
- quotePrice: number;
1409
- sellAmountAfterNetworkCosts: bigint;
1410
- buyAmountAfterNetworkCosts: bigint;
1411
- buyAmountBeforeNetworkCosts: bigint;
1431
+ quotePriceParams: QuotePriceParams;
1412
1432
  networkCostAmount: bigint;
1413
1433
  sellAmountBeforeNetworkCosts: bigint;
1414
- };
1434
+ buyAmountAfterNetworkCosts: bigint;
1435
+ sellAmountAfterNetworkCosts: bigint;
1436
+ buyAmountBeforeNetworkCosts: bigint;
1437
+ }
1438
+
1439
+ /**
1440
+ * Calculates all quote amount stages and costs from a `/quote` API response.
1441
+ *
1442
+ * Takes the raw order parameters (where protocol fee and network costs are already baked in)
1443
+ * and reconstructs every intermediate amount stage: before all fees, after protocol fees,
1444
+ * after network costs, after partner fees, and after slippage.
1445
+ *
1446
+ * The returned {@link QuoteAmountsAndCosts} includes `amountsToSign` — the final sell/buy
1447
+ * amounts that should be used when signing the order.
1448
+ *
1449
+ * @see {@link ./README.md} for a detailed explanation of the fee application order.
1450
+ *
1451
+ * @param params - Quote parameters including order params, fee BPS values, and slippage.
1452
+ * @returns All amount stages, cost breakdowns, and the amounts to sign.
1453
+ */
1415
1454
  declare function getQuoteAmountsAndCosts(params: QuoteAmountsAndCostsParams): QuoteAmountsAndCosts;
1416
- type BigNumber = {
1417
- big: bigint;
1418
- num: number;
1419
- };
1455
+
1456
+ interface QuoteAmountsAfterPartnerFeeParams {
1457
+ afterNetworkCosts: Amounts<bigint>;
1458
+ beforeAllFees: Amounts<bigint>;
1459
+ isSell: boolean;
1460
+ partnerFeeBps: number;
1461
+ }
1462
+ interface QuoteAmountsAfterPartnerFee {
1463
+ partnerFeeAmount: bigint;
1464
+ afterPartnerFees: OrderAmountsBig;
1465
+ }
1420
1466
  /**
1421
- * BigInt works well with subtraction and addition, but it's not very good with multiplication and division
1422
- * To multiply/divide token amounts we have to convert them to numbers, but we have to be careful with precision
1423
- * @param value
1424
- * @param decimals
1467
+ * Calculates the partner fee amount and adjusts quote amounts accordingly.
1468
+ *
1469
+ * The partner fee is computed relative to the spot price (`beforeAllFees`) to ensure
1470
+ * it reflects the full trade volume, not the volume already reduced by protocol fee.
1471
+ *
1472
+ * - **SELL orders:** partner fee is subtracted from `buyAmount` (user receives less)
1473
+ * - **BUY orders:** partner fee is added to `sellAmount` (user pays more)
1474
+ *
1475
+ * @param params.afterNetworkCosts - Amounts after network costs, used as the base for adjustment.
1476
+ * @param params.beforeAllFees - Spot price amounts used to calculate the fee percentage.
1477
+ * @param params.isSell - Whether this is a sell order.
1478
+ * @param params.partnerFeeBps - Partner fee in basis points (0 = no partner fee).
1479
+ * @returns The partner fee amount and the adjusted amounts after partner fees.
1480
+ */
1481
+ declare function getQuoteAmountsAfterPartnerFee(params: QuoteAmountsAfterPartnerFeeParams): QuoteAmountsAfterPartnerFee;
1482
+
1483
+ interface QuoteAmountsAfterSlippageParams {
1484
+ afterPartnerFees: OrderAmountsBig;
1485
+ isSell: boolean;
1486
+ slippageBps: number;
1487
+ }
1488
+ interface QuoteAmountsAfterSlippage {
1489
+ afterSlippage: OrderAmountsBig;
1490
+ }
1491
+ /**
1492
+ * Applies slippage tolerance to the quote amounts after all fees have been applied.
1493
+ *
1494
+ * Slippage protects the user from price movements between quoting and execution.
1495
+ * It is always applied to the non-fixed (surplus) side of the order:
1496
+ *
1497
+ * - **SELL orders:** slippage reduces `buyAmount` (user accepts receiving less)
1498
+ * - **BUY orders:** slippage increases `sellAmount` (user accepts paying more)
1499
+ *
1500
+ * @param params.afterPartnerFees - Amounts after partner fees have been applied.
1501
+ * @param params.isSell - Whether this is a sell order.
1502
+ * @param params.slippageBps - Slippage tolerance in basis points.
1503
+ * @returns The adjusted amounts after slippage tolerance.
1504
+ */
1505
+ declare function getQuoteAmountsAfterSlippage(params: QuoteAmountsAfterSlippageParams): QuoteAmountsAfterSlippage;
1506
+
1507
+ interface ProtocolFeeAmountParams {
1508
+ orderParams: OrderParameters;
1509
+ protocolFeeBps: number;
1510
+ }
1511
+ /**
1512
+ * /quote API returns `OrderParameters` where protocol fee is already included in the amounts
1513
+ * From the quote response we only know:
1514
+ * - protocol fee percent (in BPS)
1515
+ * - quote amount after protocol fee
1516
+ *
1517
+ * To get the protocol fee amount, we need to derive the quote amount BEFORE the protocol fee first
1518
+ * On the API side `quoteAmountAfterProtocolFee` is calculated like that:
1519
+ *
1520
+ * protocolFeePercent = 0.02
1521
+ * quoteAmountBeforeProtocolFee = 100_000
1522
+ * protocolFeeAmount = 100_000 * 0.02 / 100 = 20
1523
+ * quoteAmountAfterProtocolFee = 100_000 - 20 = 99_980
1524
+ *
1525
+ * On the client side, we don't know `quoteAmountBeforeProtocolFee`, so we have to reverse it from `quoteAmountAfterProtocolFee`
1526
+ *
1527
+ * quoteAmountBeforeProtocolFee = 99_980 / (1 - 0.02 / 100) = 100_000
1528
+ *
1529
+ * Note: the example above is for SELL orders, for BUY orders the protocol fee is added to sellAmount instead of substracting from buyAmount
1530
+ *
1531
+ * @param params
1425
1532
  */
1426
- declare function getBigNumber(value: string | bigint | number, decimals: number): BigNumber;
1533
+ declare function getProtocolFeeAmount(params: ProtocolFeeAmountParams): bigint;
1427
1534
 
1428
- export { type Address, type Amounts, type AppData, type AppDataHash, type AppDataObject, type Auction, type AuctionOrder, type AuctionPrices, type BigUint, BuyTokenDestination, type CallData, type CompetitionAuction, CompetitionOrderStatus, type Costs, DEFAULT_BACKOFF_OPTIONS, DEFAULT_LIMITER_OPTIONS, type EcdsaSignature, EcdsaSigningScheme, type EnrichedOrder, type EthflowData, type ExecutedAmounts, type ExecutedProtocolFee, type FeePolicy, type FetchParams, type GetOrdersRequest, type GetTradesRequest, type InteractionData, type NativePriceResponse, ORDER_BOOK_PROD_CONFIG, ORDER_BOOK_STAGING_CONFIG, OnchainOrderData, type Order, OrderBookApi, OrderBookApiError, type OrderCancellation, OrderCancellationError, type OrderCancellations, OrderClass, type OrderCreation, OrderKind, type OrderMetaData, type OrderParameters, OrderPostError, type OrderQuoteRequest, type OrderQuoteResponse, type OrderQuoteSide, OrderQuoteSideKindBuy, OrderQuoteSideKindSell, type OrderQuoteValidity, OrderStatus, type PreSignature, PriceEstimationError, type PriceImprovement, PriceQuality, type Quote, type QuoteAmountsAndCosts, type QuoteAmountsAndCostsParams, SellTokenSource, type Signature, SigningScheme, type SolverCompetitionResponse, type SolverSettlement, type Surplus, type TokenAmount, type TotalSurplus, type Trade, type TransactionHash, type UID, type Volume, getBigNumber, getQuoteAmountsAndCosts, getQuoteAmountsWithCosts, request };
1535
+ export { type Address, type Amounts, type AppData, type AppDataHash, type AppDataObject, type Auction, type AuctionOrder, type AuctionPrices, type BigUint, BuyTokenDestination, type CallData, type CompetitionAuction, CompetitionOrderStatus, type Costs, DEFAULT_BACKOFF_OPTIONS, DEFAULT_LIMITER_OPTIONS, type EcdsaSignature, EcdsaSigningScheme, type EnrichedOrder, type EthflowData, type ExecutedAmounts, type ExecutedProtocolFee, type FeePolicy, type FetchParams, type GetOrdersRequest, type GetTradesRequest, type InteractionData, type NativePriceResponse, ORDER_BOOK_PROD_CONFIG, ORDER_BOOK_STAGING_CONFIG, OnchainOrderData, type Order, type OrderAmountsBig, OrderBookApi, OrderBookApiError, type OrderCancellation, OrderCancellationError, type OrderCancellations, OrderClass, type OrderCreation, OrderKind, type OrderMetaData, type OrderParameters, OrderPostError, type OrderQuoteRequest, type OrderQuoteResponse, type OrderQuoteSide, OrderQuoteSideKindBuy, OrderQuoteSideKindSell, type OrderQuoteValidity, OrderStatus, type PreSignature, PriceEstimationError, type PriceImprovement, PriceQuality, type ProtocolFeeAmountParams, type Quote, type QuoteAmountsAfterSlippage, type QuoteAmountsAfterSlippageParams, type QuoteAmountsAndCosts, type QuoteAmountsAndCostsParams, type QuoteAmountsWithNetworkCosts, type QuoteParameters, type QuotePriceParams, SellTokenSource, type Signature, SigningScheme, type SolverCompetitionResponse, type SolverSettlement, type Surplus, type TokenAmount, type TotalSurplus, type Trade, type TransactionHash, type UID, type Volume, getProtocolFeeAmount, getQuoteAmountsAfterPartnerFee, getQuoteAmountsAfterSlippage, getQuoteAmountsAndCosts, request };
package/dist/index.js CHANGED
@@ -41,9 +41,10 @@ __export(src_exports, {
41
41
  PriceQuality: () => PriceQuality,
42
42
  SellTokenSource: () => SellTokenSource,
43
43
  SigningScheme: () => SigningScheme,
44
- getBigNumber: () => getBigNumber,
44
+ getProtocolFeeAmount: () => getProtocolFeeAmount,
45
+ getQuoteAmountsAfterPartnerFee: () => getQuoteAmountsAfterPartnerFee,
46
+ getQuoteAmountsAfterSlippage: () => getQuoteAmountsAfterSlippage,
45
47
  getQuoteAmountsAndCosts: () => getQuoteAmountsAndCosts,
46
- getQuoteAmountsWithCosts: () => getQuoteAmountsWithCosts,
47
48
  request: () => request
48
49
  });
49
50
  module.exports = __toCommonJS(src_exports);
@@ -629,90 +630,14 @@ var SigningScheme = /* @__PURE__ */ ((SigningScheme2) => {
629
630
  return SigningScheme2;
630
631
  })(SigningScheme || {});
631
632
 
632
- // src/quoteAmountsAndCostsUtils.ts
633
+ // src/quoteAmountsAndCosts/quoteAmountsAndCosts.const.ts
633
634
  var HUNDRED_THOUSANDS = 1e5;
634
635
  var ONE_HUNDRED_BPS = BigInt(100 * 100);
635
- function getQuoteAmountsWithCosts(params) {
636
- const { sellDecimals, buyDecimals, orderParams, protocolFeeBps = 0 } = params;
637
- const isSell = orderParams.kind === "sell" /* SELL */;
638
- const protocolFeeAmount = getProtocolFeeAmount({ orderParams, isSell, protocolFeeBps });
639
- const protocolFeeAmountDecimals = isSell ? buyDecimals : sellDecimals;
640
- const {
641
- sellAmountAfterNetworkCosts,
642
- buyAmountAfterNetworkCosts,
643
- buyAmountBeforeNetworkCosts,
644
- networkCostAmount,
645
- quotePrice,
646
- sellAmountBeforeNetworkCosts
647
- } = _getQuoteAmountsWithCosts({
648
- sellDecimals,
649
- buyDecimals,
650
- orderParams,
651
- protocolFeeAmount: getBigNumber(protocolFeeAmount, protocolFeeAmountDecimals),
652
- isSell
653
- });
654
- return {
655
- isSell,
656
- quotePrice,
657
- sellAmountAfterNetworkCosts: sellAmountAfterNetworkCosts.big,
658
- buyAmountAfterNetworkCosts: buyAmountAfterNetworkCosts.big,
659
- buyAmountBeforeNetworkCosts: buyAmountBeforeNetworkCosts.big,
660
- networkCostAmount: networkCostAmount.big,
661
- sellAmountBeforeNetworkCosts: sellAmountBeforeNetworkCosts.big
662
- };
663
- }
664
- function _getQuoteAmountsWithCosts(params) {
665
- const { sellDecimals, buyDecimals, orderParams, isSell, protocolFeeAmount } = params;
666
- const networkCostAmount = getBigNumber(orderParams.feeAmount, sellDecimals);
667
- const sellAmountBeforeNetworkCosts = getBigNumber(orderParams.sellAmount, sellDecimals);
668
- const buyAmountAfterNetworkCosts = getBigNumber(orderParams.buyAmount, buyDecimals);
669
- const quotePrice = isSell ? (
670
- // For SELL order is already deducting protocol fees from buyAmount, so we need to add it back to get the actual price
671
- (buyAmountAfterNetworkCosts.num + protocolFeeAmount.num) / sellAmountBeforeNetworkCosts.num
672
- ) : (
673
- // For BUY order is already adding protocol fees to sellAmount, so we need to subtract it to get the actual price
674
- buyAmountAfterNetworkCosts.num / (sellAmountBeforeNetworkCosts.num - protocolFeeAmount.num)
675
- );
676
- const sellAmountAfterNetworkCosts = getBigNumber(
677
- sellAmountBeforeNetworkCosts.big + networkCostAmount.big,
678
- sellDecimals
679
- );
680
- const buyAmountBeforeNetworkCosts = getBigNumber(quotePrice * sellAmountAfterNetworkCosts.num, buyDecimals);
681
- return {
682
- isSell,
683
- quotePrice,
684
- networkCostAmount,
685
- sellAmountBeforeNetworkCosts,
686
- buyAmountAfterNetworkCosts,
687
- sellAmountAfterNetworkCosts,
688
- buyAmountBeforeNetworkCosts
689
- };
690
- }
691
- function getQuoteAmountsWithPartnerFee(params) {
692
- const {
693
- sellAmountAfterNetworkCosts,
694
- buyAmountAfterNetworkCosts,
695
- buyAmountBeforeProtocolFee,
696
- sellAmountBeforeProtocolFee,
697
- isSell,
698
- partnerFeeBps
699
- } = params;
700
- const surplusAmountForPartnerFee = isSell ? buyAmountBeforeProtocolFee : sellAmountBeforeProtocolFee;
701
- const partnerFeeAmount = partnerFeeBps > 0 ? surplusAmountForPartnerFee * BigInt(partnerFeeBps) / ONE_HUNDRED_BPS : BigInt(0);
702
- const afterPartnerFees = isSell ? {
703
- sellAmount: sellAmountAfterNetworkCosts,
704
- buyAmount: buyAmountAfterNetworkCosts - partnerFeeAmount
705
- } : {
706
- sellAmount: sellAmountAfterNetworkCosts + partnerFeeAmount,
707
- buyAmount: buyAmountAfterNetworkCosts
708
- };
709
- return {
710
- partnerFeeAmount,
711
- afterPartnerFees
712
- };
713
- }
636
+
637
+ // src/quoteAmountsAndCosts/getProtocolFeeAmount.ts
714
638
  function getProtocolFeeAmount(params) {
715
- const { orderParams, protocolFeeBps, isSell } = params;
639
+ const { orderParams, protocolFeeBps } = params;
640
+ const isSell = orderParams.kind === "sell" /* SELL */;
716
641
  if (protocolFeeBps <= 0) {
717
642
  return 0n;
718
643
  }
@@ -730,9 +655,29 @@ function getProtocolFeeAmount(params) {
730
655
  return (sellAmount + feeAmount) * protocolFeeBpsBig / denominator;
731
656
  }
732
657
  }
733
- function getQuoteAmountsWithSlippage(params) {
734
- const { afterPartnerFees, isSell, slippagePercentBps } = params;
735
- const getSlippageAmount = (amount) => amount * BigInt(slippagePercentBps) / ONE_HUNDRED_BPS;
658
+
659
+ // src/quoteAmountsAndCosts/getQuoteAmountsAfterPartnerFee.ts
660
+ function getQuoteAmountsAfterPartnerFee(params) {
661
+ const { afterNetworkCosts, beforeAllFees, isSell, partnerFeeBps } = params;
662
+ const surplusAmountForPartnerFee = isSell ? beforeAllFees.buyAmount : beforeAllFees.sellAmount;
663
+ const partnerFeeAmount = partnerFeeBps > 0 ? surplusAmountForPartnerFee * BigInt(partnerFeeBps) / ONE_HUNDRED_BPS : BigInt(0);
664
+ const afterPartnerFees = isSell ? {
665
+ sellAmount: afterNetworkCosts.sellAmount,
666
+ buyAmount: afterNetworkCosts.buyAmount - partnerFeeAmount
667
+ } : {
668
+ sellAmount: afterNetworkCosts.sellAmount + partnerFeeAmount,
669
+ buyAmount: afterNetworkCosts.buyAmount
670
+ };
671
+ return {
672
+ partnerFeeAmount,
673
+ afterPartnerFees
674
+ };
675
+ }
676
+
677
+ // src/quoteAmountsAndCosts/getQuoteAmountsAfterSlippage.ts
678
+ function getQuoteAmountsAfterSlippage(params) {
679
+ const { afterPartnerFees, isSell, slippageBps } = params;
680
+ const getSlippageAmount = (amount) => amount * BigInt(slippageBps) / ONE_HUNDRED_BPS;
736
681
  const afterSlippage = isSell ? {
737
682
  sellAmount: afterPartnerFees.sellAmount,
738
683
  buyAmount: afterPartnerFees.buyAmount - getSlippageAmount(afterPartnerFees.buyAmount)
@@ -744,66 +689,76 @@ function getQuoteAmountsWithSlippage(params) {
744
689
  afterSlippage
745
690
  };
746
691
  }
692
+
693
+ // src/quoteAmountsAndCosts/getQuoteAmountsAndCosts.ts
747
694
  function getQuoteAmountsAndCosts(params) {
748
- const { orderParams, sellDecimals, buyDecimals, slippagePercentBps } = params;
695
+ const { orderParams, slippagePercentBps } = params;
749
696
  const partnerFeeBps = params.partnerFeeBps ?? 0;
750
697
  const protocolFeeBps = params.protocolFeeBps ?? 0;
751
698
  const isSell = orderParams.kind === "sell" /* SELL */;
699
+ const sellAmount = BigInt(orderParams.sellAmount);
700
+ const buyAmount = BigInt(orderParams.buyAmount);
701
+ const networkCostAmount = BigInt(orderParams.feeAmount);
702
+ const networkCostAmountInBuyCurrency = buyAmount * networkCostAmount / sellAmount;
752
703
  const protocolFeeAmount = getProtocolFeeAmount({
753
704
  orderParams,
754
- isSell,
755
705
  protocolFeeBps
756
706
  });
757
- const protocolFeeAmountDecimals = isSell ? buyDecimals : sellDecimals;
758
- const {
759
- networkCostAmount,
760
- sellAmountBeforeNetworkCosts,
761
- buyAmountAfterNetworkCosts,
762
- sellAmountAfterNetworkCosts,
763
- buyAmountBeforeNetworkCosts,
764
- quotePrice
765
- } = _getQuoteAmountsWithCosts({
766
- sellDecimals,
767
- buyDecimals,
768
- orderParams,
769
- isSell,
770
- protocolFeeAmount: getBigNumber(protocolFeeAmount, protocolFeeAmountDecimals)
771
- });
772
- const buyAmountBeforeProtocolFee = isSell ? protocolFeeBps > 0 ? buyAmountAfterNetworkCosts.big + protocolFeeAmount : buyAmountBeforeNetworkCosts.big : buyAmountAfterNetworkCosts.big;
773
- const sellAmountBeforeProtocolFee = isSell ? sellAmountAfterNetworkCosts.big : protocolFeeBps > 0 ? sellAmountAfterNetworkCosts.big - protocolFeeAmount : sellAmountBeforeNetworkCosts.big;
774
- const { afterPartnerFees, partnerFeeAmount } = getQuoteAmountsWithPartnerFee({
775
- sellAmountAfterNetworkCosts: sellAmountAfterNetworkCosts.big,
776
- buyAmountAfterNetworkCosts: buyAmountAfterNetworkCosts.big,
777
- buyAmountBeforeProtocolFee,
778
- sellAmountBeforeProtocolFee,
707
+ const beforeAllFees = isSell ? {
708
+ // Only in case of SELL order, network costs are already added to sellAmount which comes from /quote API
709
+ sellAmount: sellAmount + networkCostAmount,
710
+ /**
711
+ * Important!
712
+ * For SELL orders, /quote API returns sellAmount AFTER network costs
713
+ * buyAmount is correlated to that sellAmount, hence, it doesn't include network costs as well
714
+ * Because of that, we add network costs here as well to have both amounts consistent
715
+ */
716
+ buyAmount: buyAmount + networkCostAmountInBuyCurrency + protocolFeeAmount
717
+ } : {
718
+ sellAmount: sellAmount - protocolFeeAmount,
719
+ buyAmount
720
+ };
721
+ const afterProtocolFees = isSell ? {
722
+ sellAmount: beforeAllFees.sellAmount,
723
+ buyAmount: beforeAllFees.buyAmount - protocolFeeAmount
724
+ } : {
725
+ sellAmount,
726
+ buyAmount: beforeAllFees.buyAmount
727
+ };
728
+ const afterNetworkCosts = isSell ? {
729
+ // For SELL order, the /quote API response sellAmount is already after network costs
730
+ // buyAmount is relative to sellAmount, hence it's also after network costs
731
+ sellAmount,
732
+ buyAmount
733
+ } : {
734
+ // For BUY order, the /quote API response sellAmount is only after protocolFee, so we need to add networks costs to the amount
735
+ sellAmount: sellAmount + networkCostAmount,
736
+ buyAmount: afterProtocolFees.buyAmount
737
+ };
738
+ const { afterPartnerFees, partnerFeeAmount } = getQuoteAmountsAfterPartnerFee({
739
+ afterNetworkCosts,
740
+ beforeAllFees,
779
741
  isSell,
780
742
  partnerFeeBps
781
743
  });
782
- const { afterSlippage } = getQuoteAmountsWithSlippage({
744
+ const { afterSlippage } = getQuoteAmountsAfterSlippage({
783
745
  afterPartnerFees,
784
746
  isSell,
785
- slippagePercentBps
747
+ slippageBps: slippagePercentBps
786
748
  });
787
- const beforeNetworkCosts = isSell ? {
788
- sellAmount: sellAmountBeforeNetworkCosts.big,
789
- buyAmount: buyAmountBeforeProtocolFee
749
+ const amountsToSign = isSell ? {
750
+ sellAmount: beforeAllFees.sellAmount,
751
+ buyAmount: afterSlippage.buyAmount
790
752
  } : {
791
- sellAmount: sellAmountBeforeProtocolFee,
792
- buyAmount: buyAmountBeforeNetworkCosts.big
793
- };
794
- const beforeAllFees = isSell ? {
795
- sellAmount: sellAmountBeforeNetworkCosts.big,
796
- buyAmount: buyAmountBeforeNetworkCosts.big
797
- } : {
798
- sellAmount: sellAmountBeforeNetworkCosts.big - protocolFeeAmount,
799
- buyAmount: buyAmountBeforeNetworkCosts.big
753
+ sellAmount: afterSlippage.sellAmount,
754
+ buyAmount: beforeAllFees.buyAmount
800
755
  };
801
756
  return {
802
757
  isSell,
803
758
  costs: {
804
759
  networkFee: {
805
- amountInSellCurrency: networkCostAmount.big,
806
- amountInBuyCurrency: getBigNumber(quotePrice * networkCostAmount.num, buyDecimals).big
760
+ amountInSellCurrency: networkCostAmount,
761
+ amountInBuyCurrency: networkCostAmountInBuyCurrency
807
762
  },
808
763
  partnerFee: {
809
764
  amount: partnerFeeAmount,
@@ -814,27 +769,15 @@ function getQuoteAmountsAndCosts(params) {
814
769
  bps: protocolFeeBps
815
770
  }
816
771
  },
817
- beforeNetworkCosts,
818
772
  beforeAllFees,
819
- afterNetworkCosts: {
820
- sellAmount: sellAmountAfterNetworkCosts.big,
821
- buyAmount: buyAmountAfterNetworkCosts.big
822
- },
773
+ beforeNetworkCosts: afterProtocolFees,
774
+ afterProtocolFees,
775
+ afterNetworkCosts,
823
776
  afterPartnerFees,
824
- afterSlippage
777
+ afterSlippage,
778
+ amountsToSign
825
779
  };
826
780
  }
827
- function getBigNumber(value, decimals) {
828
- if (typeof value === "number") {
829
- const bigAsNumber = value * 10 ** decimals;
830
- const bigAsNumberString = bigAsNumber.toFixed();
831
- const big2 = BigInt(bigAsNumberString.includes("e") ? bigAsNumber : bigAsNumberString);
832
- return { big: big2, num: value };
833
- }
834
- const big = BigInt(value);
835
- const num = Number(big) / 10 ** decimals;
836
- return { big, num };
837
- }
838
781
  // Annotate the CommonJS export names for ESM import in node:
839
782
  0 && (module.exports = {
840
783
  BuyTokenDestination,
@@ -858,8 +801,9 @@ function getBigNumber(value, decimals) {
858
801
  PriceQuality,
859
802
  SellTokenSource,
860
803
  SigningScheme,
861
- getBigNumber,
804
+ getProtocolFeeAmount,
805
+ getQuoteAmountsAfterPartnerFee,
806
+ getQuoteAmountsAfterSlippage,
862
807
  getQuoteAmountsAndCosts,
863
- getQuoteAmountsWithCosts,
864
808
  request
865
809
  });
package/dist/index.mjs CHANGED
@@ -583,90 +583,14 @@ var SigningScheme = /* @__PURE__ */ ((SigningScheme2) => {
583
583
  return SigningScheme2;
584
584
  })(SigningScheme || {});
585
585
 
586
- // src/quoteAmountsAndCostsUtils.ts
586
+ // src/quoteAmountsAndCosts/quoteAmountsAndCosts.const.ts
587
587
  var HUNDRED_THOUSANDS = 1e5;
588
588
  var ONE_HUNDRED_BPS = BigInt(100 * 100);
589
- function getQuoteAmountsWithCosts(params) {
590
- const { sellDecimals, buyDecimals, orderParams, protocolFeeBps = 0 } = params;
591
- const isSell = orderParams.kind === "sell" /* SELL */;
592
- const protocolFeeAmount = getProtocolFeeAmount({ orderParams, isSell, protocolFeeBps });
593
- const protocolFeeAmountDecimals = isSell ? buyDecimals : sellDecimals;
594
- const {
595
- sellAmountAfterNetworkCosts,
596
- buyAmountAfterNetworkCosts,
597
- buyAmountBeforeNetworkCosts,
598
- networkCostAmount,
599
- quotePrice,
600
- sellAmountBeforeNetworkCosts
601
- } = _getQuoteAmountsWithCosts({
602
- sellDecimals,
603
- buyDecimals,
604
- orderParams,
605
- protocolFeeAmount: getBigNumber(protocolFeeAmount, protocolFeeAmountDecimals),
606
- isSell
607
- });
608
- return {
609
- isSell,
610
- quotePrice,
611
- sellAmountAfterNetworkCosts: sellAmountAfterNetworkCosts.big,
612
- buyAmountAfterNetworkCosts: buyAmountAfterNetworkCosts.big,
613
- buyAmountBeforeNetworkCosts: buyAmountBeforeNetworkCosts.big,
614
- networkCostAmount: networkCostAmount.big,
615
- sellAmountBeforeNetworkCosts: sellAmountBeforeNetworkCosts.big
616
- };
617
- }
618
- function _getQuoteAmountsWithCosts(params) {
619
- const { sellDecimals, buyDecimals, orderParams, isSell, protocolFeeAmount } = params;
620
- const networkCostAmount = getBigNumber(orderParams.feeAmount, sellDecimals);
621
- const sellAmountBeforeNetworkCosts = getBigNumber(orderParams.sellAmount, sellDecimals);
622
- const buyAmountAfterNetworkCosts = getBigNumber(orderParams.buyAmount, buyDecimals);
623
- const quotePrice = isSell ? (
624
- // For SELL order is already deducting protocol fees from buyAmount, so we need to add it back to get the actual price
625
- (buyAmountAfterNetworkCosts.num + protocolFeeAmount.num) / sellAmountBeforeNetworkCosts.num
626
- ) : (
627
- // For BUY order is already adding protocol fees to sellAmount, so we need to subtract it to get the actual price
628
- buyAmountAfterNetworkCosts.num / (sellAmountBeforeNetworkCosts.num - protocolFeeAmount.num)
629
- );
630
- const sellAmountAfterNetworkCosts = getBigNumber(
631
- sellAmountBeforeNetworkCosts.big + networkCostAmount.big,
632
- sellDecimals
633
- );
634
- const buyAmountBeforeNetworkCosts = getBigNumber(quotePrice * sellAmountAfterNetworkCosts.num, buyDecimals);
635
- return {
636
- isSell,
637
- quotePrice,
638
- networkCostAmount,
639
- sellAmountBeforeNetworkCosts,
640
- buyAmountAfterNetworkCosts,
641
- sellAmountAfterNetworkCosts,
642
- buyAmountBeforeNetworkCosts
643
- };
644
- }
645
- function getQuoteAmountsWithPartnerFee(params) {
646
- const {
647
- sellAmountAfterNetworkCosts,
648
- buyAmountAfterNetworkCosts,
649
- buyAmountBeforeProtocolFee,
650
- sellAmountBeforeProtocolFee,
651
- isSell,
652
- partnerFeeBps
653
- } = params;
654
- const surplusAmountForPartnerFee = isSell ? buyAmountBeforeProtocolFee : sellAmountBeforeProtocolFee;
655
- const partnerFeeAmount = partnerFeeBps > 0 ? surplusAmountForPartnerFee * BigInt(partnerFeeBps) / ONE_HUNDRED_BPS : BigInt(0);
656
- const afterPartnerFees = isSell ? {
657
- sellAmount: sellAmountAfterNetworkCosts,
658
- buyAmount: buyAmountAfterNetworkCosts - partnerFeeAmount
659
- } : {
660
- sellAmount: sellAmountAfterNetworkCosts + partnerFeeAmount,
661
- buyAmount: buyAmountAfterNetworkCosts
662
- };
663
- return {
664
- partnerFeeAmount,
665
- afterPartnerFees
666
- };
667
- }
589
+
590
+ // src/quoteAmountsAndCosts/getProtocolFeeAmount.ts
668
591
  function getProtocolFeeAmount(params) {
669
- const { orderParams, protocolFeeBps, isSell } = params;
592
+ const { orderParams, protocolFeeBps } = params;
593
+ const isSell = orderParams.kind === "sell" /* SELL */;
670
594
  if (protocolFeeBps <= 0) {
671
595
  return 0n;
672
596
  }
@@ -684,9 +608,29 @@ function getProtocolFeeAmount(params) {
684
608
  return (sellAmount + feeAmount) * protocolFeeBpsBig / denominator;
685
609
  }
686
610
  }
687
- function getQuoteAmountsWithSlippage(params) {
688
- const { afterPartnerFees, isSell, slippagePercentBps } = params;
689
- const getSlippageAmount = (amount) => amount * BigInt(slippagePercentBps) / ONE_HUNDRED_BPS;
611
+
612
+ // src/quoteAmountsAndCosts/getQuoteAmountsAfterPartnerFee.ts
613
+ function getQuoteAmountsAfterPartnerFee(params) {
614
+ const { afterNetworkCosts, beforeAllFees, isSell, partnerFeeBps } = params;
615
+ const surplusAmountForPartnerFee = isSell ? beforeAllFees.buyAmount : beforeAllFees.sellAmount;
616
+ const partnerFeeAmount = partnerFeeBps > 0 ? surplusAmountForPartnerFee * BigInt(partnerFeeBps) / ONE_HUNDRED_BPS : BigInt(0);
617
+ const afterPartnerFees = isSell ? {
618
+ sellAmount: afterNetworkCosts.sellAmount,
619
+ buyAmount: afterNetworkCosts.buyAmount - partnerFeeAmount
620
+ } : {
621
+ sellAmount: afterNetworkCosts.sellAmount + partnerFeeAmount,
622
+ buyAmount: afterNetworkCosts.buyAmount
623
+ };
624
+ return {
625
+ partnerFeeAmount,
626
+ afterPartnerFees
627
+ };
628
+ }
629
+
630
+ // src/quoteAmountsAndCosts/getQuoteAmountsAfterSlippage.ts
631
+ function getQuoteAmountsAfterSlippage(params) {
632
+ const { afterPartnerFees, isSell, slippageBps } = params;
633
+ const getSlippageAmount = (amount) => amount * BigInt(slippageBps) / ONE_HUNDRED_BPS;
690
634
  const afterSlippage = isSell ? {
691
635
  sellAmount: afterPartnerFees.sellAmount,
692
636
  buyAmount: afterPartnerFees.buyAmount - getSlippageAmount(afterPartnerFees.buyAmount)
@@ -698,66 +642,76 @@ function getQuoteAmountsWithSlippage(params) {
698
642
  afterSlippage
699
643
  };
700
644
  }
645
+
646
+ // src/quoteAmountsAndCosts/getQuoteAmountsAndCosts.ts
701
647
  function getQuoteAmountsAndCosts(params) {
702
- const { orderParams, sellDecimals, buyDecimals, slippagePercentBps } = params;
648
+ const { orderParams, slippagePercentBps } = params;
703
649
  const partnerFeeBps = params.partnerFeeBps ?? 0;
704
650
  const protocolFeeBps = params.protocolFeeBps ?? 0;
705
651
  const isSell = orderParams.kind === "sell" /* SELL */;
652
+ const sellAmount = BigInt(orderParams.sellAmount);
653
+ const buyAmount = BigInt(orderParams.buyAmount);
654
+ const networkCostAmount = BigInt(orderParams.feeAmount);
655
+ const networkCostAmountInBuyCurrency = buyAmount * networkCostAmount / sellAmount;
706
656
  const protocolFeeAmount = getProtocolFeeAmount({
707
657
  orderParams,
708
- isSell,
709
658
  protocolFeeBps
710
659
  });
711
- const protocolFeeAmountDecimals = isSell ? buyDecimals : sellDecimals;
712
- const {
713
- networkCostAmount,
714
- sellAmountBeforeNetworkCosts,
715
- buyAmountAfterNetworkCosts,
716
- sellAmountAfterNetworkCosts,
717
- buyAmountBeforeNetworkCosts,
718
- quotePrice
719
- } = _getQuoteAmountsWithCosts({
720
- sellDecimals,
721
- buyDecimals,
722
- orderParams,
723
- isSell,
724
- protocolFeeAmount: getBigNumber(protocolFeeAmount, protocolFeeAmountDecimals)
725
- });
726
- const buyAmountBeforeProtocolFee = isSell ? protocolFeeBps > 0 ? buyAmountAfterNetworkCosts.big + protocolFeeAmount : buyAmountBeforeNetworkCosts.big : buyAmountAfterNetworkCosts.big;
727
- const sellAmountBeforeProtocolFee = isSell ? sellAmountAfterNetworkCosts.big : protocolFeeBps > 0 ? sellAmountAfterNetworkCosts.big - protocolFeeAmount : sellAmountBeforeNetworkCosts.big;
728
- const { afterPartnerFees, partnerFeeAmount } = getQuoteAmountsWithPartnerFee({
729
- sellAmountAfterNetworkCosts: sellAmountAfterNetworkCosts.big,
730
- buyAmountAfterNetworkCosts: buyAmountAfterNetworkCosts.big,
731
- buyAmountBeforeProtocolFee,
732
- sellAmountBeforeProtocolFee,
660
+ const beforeAllFees = isSell ? {
661
+ // Only in case of SELL order, network costs are already added to sellAmount which comes from /quote API
662
+ sellAmount: sellAmount + networkCostAmount,
663
+ /**
664
+ * Important!
665
+ * For SELL orders, /quote API returns sellAmount AFTER network costs
666
+ * buyAmount is correlated to that sellAmount, hence, it doesn't include network costs as well
667
+ * Because of that, we add network costs here as well to have both amounts consistent
668
+ */
669
+ buyAmount: buyAmount + networkCostAmountInBuyCurrency + protocolFeeAmount
670
+ } : {
671
+ sellAmount: sellAmount - protocolFeeAmount,
672
+ buyAmount
673
+ };
674
+ const afterProtocolFees = isSell ? {
675
+ sellAmount: beforeAllFees.sellAmount,
676
+ buyAmount: beforeAllFees.buyAmount - protocolFeeAmount
677
+ } : {
678
+ sellAmount,
679
+ buyAmount: beforeAllFees.buyAmount
680
+ };
681
+ const afterNetworkCosts = isSell ? {
682
+ // For SELL order, the /quote API response sellAmount is already after network costs
683
+ // buyAmount is relative to sellAmount, hence it's also after network costs
684
+ sellAmount,
685
+ buyAmount
686
+ } : {
687
+ // For BUY order, the /quote API response sellAmount is only after protocolFee, so we need to add networks costs to the amount
688
+ sellAmount: sellAmount + networkCostAmount,
689
+ buyAmount: afterProtocolFees.buyAmount
690
+ };
691
+ const { afterPartnerFees, partnerFeeAmount } = getQuoteAmountsAfterPartnerFee({
692
+ afterNetworkCosts,
693
+ beforeAllFees,
733
694
  isSell,
734
695
  partnerFeeBps
735
696
  });
736
- const { afterSlippage } = getQuoteAmountsWithSlippage({
697
+ const { afterSlippage } = getQuoteAmountsAfterSlippage({
737
698
  afterPartnerFees,
738
699
  isSell,
739
- slippagePercentBps
700
+ slippageBps: slippagePercentBps
740
701
  });
741
- const beforeNetworkCosts = isSell ? {
742
- sellAmount: sellAmountBeforeNetworkCosts.big,
743
- buyAmount: buyAmountBeforeProtocolFee
702
+ const amountsToSign = isSell ? {
703
+ sellAmount: beforeAllFees.sellAmount,
704
+ buyAmount: afterSlippage.buyAmount
744
705
  } : {
745
- sellAmount: sellAmountBeforeProtocolFee,
746
- buyAmount: buyAmountBeforeNetworkCosts.big
747
- };
748
- const beforeAllFees = isSell ? {
749
- sellAmount: sellAmountBeforeNetworkCosts.big,
750
- buyAmount: buyAmountBeforeNetworkCosts.big
751
- } : {
752
- sellAmount: sellAmountBeforeNetworkCosts.big - protocolFeeAmount,
753
- buyAmount: buyAmountBeforeNetworkCosts.big
706
+ sellAmount: afterSlippage.sellAmount,
707
+ buyAmount: beforeAllFees.buyAmount
754
708
  };
755
709
  return {
756
710
  isSell,
757
711
  costs: {
758
712
  networkFee: {
759
- amountInSellCurrency: networkCostAmount.big,
760
- amountInBuyCurrency: getBigNumber(quotePrice * networkCostAmount.num, buyDecimals).big
713
+ amountInSellCurrency: networkCostAmount,
714
+ amountInBuyCurrency: networkCostAmountInBuyCurrency
761
715
  },
762
716
  partnerFee: {
763
717
  amount: partnerFeeAmount,
@@ -768,27 +722,15 @@ function getQuoteAmountsAndCosts(params) {
768
722
  bps: protocolFeeBps
769
723
  }
770
724
  },
771
- beforeNetworkCosts,
772
725
  beforeAllFees,
773
- afterNetworkCosts: {
774
- sellAmount: sellAmountAfterNetworkCosts.big,
775
- buyAmount: buyAmountAfterNetworkCosts.big
776
- },
726
+ beforeNetworkCosts: afterProtocolFees,
727
+ afterProtocolFees,
728
+ afterNetworkCosts,
777
729
  afterPartnerFees,
778
- afterSlippage
730
+ afterSlippage,
731
+ amountsToSign
779
732
  };
780
733
  }
781
- function getBigNumber(value, decimals) {
782
- if (typeof value === "number") {
783
- const bigAsNumber = value * 10 ** decimals;
784
- const bigAsNumberString = bigAsNumber.toFixed();
785
- const big2 = BigInt(bigAsNumberString.includes("e") ? bigAsNumber : bigAsNumberString);
786
- return { big: big2, num: value };
787
- }
788
- const big = BigInt(value);
789
- const num = Number(big) / 10 ** decimals;
790
- return { big, num };
791
- }
792
734
  export {
793
735
  BuyTokenDestination,
794
736
  CompetitionOrderStatus,
@@ -811,8 +753,9 @@ export {
811
753
  PriceQuality,
812
754
  SellTokenSource,
813
755
  SigningScheme,
814
- getBigNumber,
756
+ getProtocolFeeAmount,
757
+ getQuoteAmountsAfterPartnerFee,
758
+ getQuoteAmountsAfterSlippage,
815
759
  getQuoteAmountsAndCosts,
816
- getQuoteAmountsWithCosts,
817
760
  request
818
761
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/sdk-order-book",
3
- "version": "0.6.5",
3
+ "version": "1.0.0",
4
4
  "description": "CowProtocol Order Book package",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -31,8 +31,8 @@
31
31
  "cross-fetch": "^3.2.0",
32
32
  "exponential-backoff": "^3.1.2",
33
33
  "limiter": "^3.0.0",
34
- "@cowprotocol/sdk-common": "0.6.1",
35
- "@cowprotocol/sdk-config": "0.8.0"
34
+ "@cowprotocol/sdk-config": "0.8.1",
35
+ "@cowprotocol/sdk-common": "0.6.2"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsup src/index.ts --format esm,cjs --dts",