@shapeshiftoss/swapper 19.0.0 → 20.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.
Files changed (93) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/exactOutputFiltering.test.d.ts +1 -0
  3. package/dist/cjs/exactOutputFiltering.test.js +70 -0
  4. package/dist/cjs/swapper.d.ts +3 -3
  5. package/dist/cjs/swapper.js +29 -6
  6. package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossStepData.d.ts +1 -0
  7. package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossStepData.js +2 -2
  8. package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +1 -0
  9. package/dist/cjs/swappers/BebopSwapper/utils/getBebopStepData.d.ts +1 -0
  10. package/dist/cjs/swappers/BebopSwapper/utils/getBebopStepData.js +2 -2
  11. package/dist/cjs/swappers/BebopSwapper/utils/getBebopTradeContext.js +1 -0
  12. package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeStepData.d.ts +1 -0
  13. package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeStepData.js +2 -2
  14. package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeTradeContext.js +1 -0
  15. package/dist/cjs/swappers/NearIntentsSwapper/endpoints.js +2 -0
  16. package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +2 -1
  17. package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +14 -9
  18. package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +2 -1
  19. package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +14 -9
  20. package/dist/cjs/swappers/NearIntentsSwapper/types.d.ts +3 -1
  21. package/dist/cjs/swappers/NearIntentsSwapper/utils/exactOutput.test.d.ts +1 -0
  22. package/dist/cjs/swappers/NearIntentsSwapper/utils/exactOutput.test.js +61 -0
  23. package/dist/cjs/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.d.ts +2 -2
  24. package/dist/cjs/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.js +4 -2
  25. package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers.d.ts +3 -3
  26. package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers.js +27 -23
  27. package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.d.ts +1 -0
  28. package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.js +3 -3
  29. package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.d.ts +1 -0
  30. package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.js +7 -1
  31. package/dist/cjs/swappers/RelaySwapper/endpoints.js +6 -0
  32. package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.d.ts +2 -1
  33. package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +5 -2
  34. package/dist/cjs/swappers/RelaySwapper/getTradeRate/getTradeRate.d.ts +2 -1
  35. package/dist/cjs/swappers/RelaySwapper/getTradeRate/getTradeRate.js +5 -2
  36. package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +2 -2
  37. package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.js +22 -10
  38. package/dist/cjs/swappers/RelaySwapper/utils/helpers.d.ts +2 -2
  39. package/dist/cjs/swappers/RelaySwapper/utils/types.d.ts +4 -1
  40. package/dist/cjs/swappers/SunioSwapper/utils/getSunioStepData.d.ts +1 -0
  41. package/dist/cjs/swappers/SunioSwapper/utils/getSunioStepData.js +2 -2
  42. package/dist/cjs/swappers/SunioSwapper/utils/getSunioTradeContext.js +6 -1
  43. package/dist/cjs/types.d.ts +19 -2
  44. package/dist/cjs/types.js +2 -0
  45. package/dist/cjs/utils/helpers.d.ts +6 -0
  46. package/dist/cjs/utils/helpers.js +5 -1
  47. package/dist/esm/.tsbuildinfo +1 -1
  48. package/dist/esm/exactOutputFiltering.test.d.ts +1 -0
  49. package/dist/esm/exactOutputFiltering.test.js +68 -0
  50. package/dist/esm/swapper.d.ts +3 -3
  51. package/dist/esm/swapper.js +29 -6
  52. package/dist/esm/swappers/AcrossSwapper/utils/getAcrossStepData.d.ts +1 -0
  53. package/dist/esm/swappers/AcrossSwapper/utils/getAcrossStepData.js +2 -2
  54. package/dist/esm/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +1 -0
  55. package/dist/esm/swappers/BebopSwapper/utils/getBebopStepData.d.ts +1 -0
  56. package/dist/esm/swappers/BebopSwapper/utils/getBebopStepData.js +2 -2
  57. package/dist/esm/swappers/BebopSwapper/utils/getBebopTradeContext.js +1 -0
  58. package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeStepData.d.ts +1 -0
  59. package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeStepData.js +2 -2
  60. package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeTradeContext.js +1 -0
  61. package/dist/esm/swappers/NearIntentsSwapper/endpoints.js +4 -2
  62. package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +2 -1
  63. package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +7 -3
  64. package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +2 -1
  65. package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +7 -3
  66. package/dist/esm/swappers/NearIntentsSwapper/types.d.ts +3 -1
  67. package/dist/esm/swappers/NearIntentsSwapper/utils/exactOutput.test.d.ts +1 -0
  68. package/dist/esm/swappers/NearIntentsSwapper/utils/exactOutput.test.js +59 -0
  69. package/dist/esm/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.d.ts +2 -2
  70. package/dist/esm/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.js +4 -2
  71. package/dist/esm/swappers/NearIntentsSwapper/utils/helpers.d.ts +3 -3
  72. package/dist/esm/swappers/NearIntentsSwapper/utils/helpers.js +27 -23
  73. package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.d.ts +1 -0
  74. package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.js +3 -3
  75. package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.d.ts +1 -0
  76. package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.js +7 -1
  77. package/dist/esm/swappers/RelaySwapper/endpoints.js +8 -2
  78. package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.d.ts +2 -1
  79. package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +3 -1
  80. package/dist/esm/swappers/RelaySwapper/getTradeRate/getTradeRate.d.ts +2 -1
  81. package/dist/esm/swappers/RelaySwapper/getTradeRate/getTradeRate.js +3 -1
  82. package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +2 -2
  83. package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.js +23 -11
  84. package/dist/esm/swappers/RelaySwapper/utils/helpers.d.ts +2 -2
  85. package/dist/esm/swappers/RelaySwapper/utils/types.d.ts +4 -1
  86. package/dist/esm/swappers/SunioSwapper/utils/getSunioStepData.d.ts +1 -0
  87. package/dist/esm/swappers/SunioSwapper/utils/getSunioStepData.js +2 -2
  88. package/dist/esm/swappers/SunioSwapper/utils/getSunioTradeContext.js +6 -1
  89. package/dist/esm/types.d.ts +19 -2
  90. package/dist/esm/types.js +2 -0
  91. package/dist/esm/utils/helpers.d.ts +6 -0
  92. package/dist/esm/utils/helpers.js +3 -0
  93. package/package.json +5 -5
@@ -6,8 +6,8 @@ import { getUnsignedSolanaTransaction } from '../../utils/solana/getUnsignedSola
6
6
  import { getTronTransactionFees, getUnsignedTronTransaction } from '../../utils/tron/index.js';
7
7
  import { getUnsignedUtxoTransaction, getUtxoTransactionFees } from '../../utils/utxo/index.js';
8
8
  import { chainIdToRelayChainId } from './constant.js';
9
- import { getTradeQuote } from './getTradeQuote/getTradeQuote.js';
10
- import { getTradeRate } from './getTradeRate/getTradeRate.js';
9
+ import { getExactOutputTradeQuote, getTradeQuote } from './getTradeQuote/getTradeQuote.js';
10
+ import { getExactOutputTradeRate, getTradeRate } from './getTradeRate/getTradeRate.js';
11
11
  import { getLatestRelayStatusMessage } from './utils/getLatestRelayStatusMessage.js';
12
12
  import { notifyTransactionIndexing } from './utils/notifyTransactionIndexing.js';
13
13
  import { getRelayRequestConfig, relayService } from './utils/relayService.js';
@@ -20,6 +20,12 @@ export const relayApi = {
20
20
  getTradeRate: (input, deps) => {
21
21
  return getTradeRate(input, deps, chainIdToRelayChainId);
22
22
  },
23
+ getExactOutputTradeQuote: (input, deps) => {
24
+ return getExactOutputTradeQuote(input, deps, chainIdToRelayChainId);
25
+ },
26
+ getExactOutputTradeRate: (input, deps) => {
27
+ return getExactOutputTradeRate(input, deps, chainIdToRelayChainId);
28
+ },
23
29
  getEvmTransactionFees,
24
30
  getUnsignedEvmTransaction,
25
31
  getUnsignedUtxoTransaction,
@@ -1,5 +1,6 @@
1
1
  import type { Result } from '@sniptt/monads';
2
2
  import type { SwapErrorRight, SwapperDeps, TradeQuote } from '../../../types.js';
3
3
  import type { chainIdToRelayChainId as relayChainMapImplementation } from '../constant.js';
4
- import type { RelayTradeQuoteInput } from '../utils/types.js';
4
+ import type { RelayExactOutputTradeQuoteInput, RelayTradeQuoteInput } from '../utils/types.js';
5
5
  export declare const getTradeQuote: (input: RelayTradeQuoteInput, deps: SwapperDeps, relayChainMap: typeof relayChainMapImplementation) => Promise<Result<TradeQuote[], SwapErrorRight>>;
6
+ export declare const getExactOutputTradeQuote: (input: RelayExactOutputTradeQuoteInput, deps: SwapperDeps, relayChainMap: typeof relayChainMapImplementation) => Promise<Result<TradeQuote[], SwapErrorRight>>;
@@ -3,7 +3,7 @@ import { assertQuoteAddresses } from '../../../utils/index.js';
3
3
  import { FALLBACK_QUOTE_DEADLINE_MS } from '../../../utils/helpers.js';
4
4
  import { getRelayStepData } from '../utils/getRelayStepData.js';
5
5
  import { getRelayTradeContext } from '../utils/getRelayTradeContext.js';
6
- export const getTradeQuote = async (input, deps, relayChainMap) => {
6
+ const getQuote = async (input, deps, relayChainMap) => {
7
7
  const { accountNumber } = input;
8
8
  const addresses = assertQuoteAddresses(input);
9
9
  if (addresses.isErr())
@@ -49,3 +49,5 @@ export const getTradeQuote = async (input, deps, relayChainMap) => {
49
49
  };
50
50
  return Ok([tradeQuote]);
51
51
  };
52
+ export const getTradeQuote = (input, deps, relayChainMap) => getQuote(input, deps, relayChainMap);
53
+ export const getExactOutputTradeQuote = (input, deps, relayChainMap) => getQuote(input, deps, relayChainMap);
@@ -1,5 +1,6 @@
1
1
  import type { Result } from '@sniptt/monads';
2
2
  import type { SwapErrorRight, SwapperDeps, TradeRate } from '../../../types.js';
3
3
  import type { chainIdToRelayChainId as relayChainMapImplementation } from '../constant.js';
4
- import type { RelayTradeRateInput } from '../utils/types.js';
4
+ import type { RelayExactOutputTradeRateInput, RelayTradeRateInput } from '../utils/types.js';
5
5
  export declare const getTradeRate: (input: RelayTradeRateInput, deps: SwapperDeps, relayChainMap: typeof relayChainMapImplementation) => Promise<Result<TradeRate[], SwapErrorRight>>;
6
+ export declare const getExactOutputTradeRate: (input: RelayExactOutputTradeRateInput, deps: SwapperDeps, relayChainMap: typeof relayChainMapImplementation) => Promise<Result<TradeRate[], SwapErrorRight>>;
@@ -1,7 +1,7 @@
1
1
  import { Err, Ok } from '@sniptt/monads';
2
2
  import { getRelayStepData } from '../utils/getRelayStepData.js';
3
3
  import { getRelayTradeContext } from '../utils/getRelayTradeContext.js';
4
- export const getTradeRate = async (input, deps, relayChainMap) => {
4
+ const getRate = async (input, deps, relayChainMap) => {
5
5
  const maybeContext = await getRelayTradeContext({ input, deps, relayChainMap });
6
6
  if (maybeContext.isErr())
7
7
  return Err(maybeContext.unwrapErr());
@@ -36,3 +36,5 @@ export const getTradeRate = async (input, deps, relayChainMap) => {
36
36
  };
37
37
  return Ok([tradeRate]);
38
38
  };
39
+ export const getTradeRate = (input, deps, relayChainMap) => getRate(input, deps, relayChainMap);
40
+ export const getExactOutputTradeRate = (input, deps, relayChainMap) => getRate(input, deps, relayChainMap);
@@ -2,7 +2,7 @@ import type { Result } from '@sniptt/monads';
2
2
  import type { QuoteFeeData, SwapErrorRight, SwapperDeps, TradeCommon, TradeStepCommon } from '../../../types.js';
3
3
  import type { chainIdToRelayChainId as relayChainMapImplementation } from '../constant.js';
4
4
  import type { GetRelayStepDataArgs } from './getRelayStepData.js';
5
- import type { RelayQuoteItem, RelayTradeQuoteInput, RelayTradeRateInput } from './types.js';
5
+ import type { RelayExactOutputTradeQuoteInput, RelayExactOutputTradeRateInput, RelayQuoteItem, RelayTradeQuoteInput, RelayTradeRateInput } from './types.js';
6
6
  type RelayTradeContext = {
7
7
  tradeCommon: TradeCommon;
8
8
  stepCommon: Omit<TradeStepCommon, 'feeData' | 'allowanceContract'>;
@@ -15,7 +15,7 @@ type RelayTradeContext = {
15
15
  relayId: string;
16
16
  };
17
17
  export declare const getRelayTradeContext: ({ input, deps, relayChainMap, }: {
18
- input: RelayTradeQuoteInput | RelayTradeRateInput;
18
+ input: RelayTradeQuoteInput | RelayTradeRateInput | RelayExactOutputTradeQuoteInput | RelayExactOutputTradeRateInput;
19
19
  deps: SwapperDeps;
20
20
  relayChainMap: typeof relayChainMapImplementation;
21
21
  }) => Promise<Result<RelayTradeContext, SwapErrorRight>>;
@@ -7,7 +7,7 @@ import { zeroAddress } from 'viem';
7
7
  import { MixPanelEvent, SwapperName, TradeQuoteError } from '../../../types.js';
8
8
  import { getInputOutputRate, makeSwapErrorRight } from '../../../utils/index.js';
9
9
  import { buildAffiliateFee } from '../../../utils/affiliateFee.js';
10
- import { isNativeEvmAsset } from '../../../utils/helpers.js';
10
+ import { getTradeAmount, isNativeEvmAsset } from '../../../utils/helpers.js';
11
11
  import { MAXIMUM_SUPPORTED_RELAY_STEPS, relayErrorCodeToTradeQuoteError } from '../constant.js';
12
12
  import { getRelayAssetAddress } from '../utils/getRelayAssetAddress.js';
13
13
  import { relayTokenToAsset } from '../utils/relayTokenToAsset.js';
@@ -16,7 +16,9 @@ import { fetchRelayTrade } from './fetchRelayTrade.js';
16
16
  import { assertValidTrade, getRelayAllowanceContract, resolveRelayAddresses } from './helpers.js';
17
17
  import { isRelayError } from './types.js';
18
18
  export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
19
- const { sellAsset, buyAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, affiliateBps } = input;
19
+ const { sellAsset, buyAsset, affiliateBps } = input;
20
+ const amount = getTradeAmount(input);
21
+ const isExactOutput = amount.direction === 'exactOut';
20
22
  const xpub = 'xpub' in input ? input.xpub : undefined;
21
23
  const slippageToleranceBps = input.slippageTolerancePercentageDecimal
22
24
  ? convertDecimalPercentageToBasisPoints(input.slippageTolerancePercentageDecimal).toFixed()
@@ -35,8 +37,8 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
35
37
  originCurrency: getRelayAssetAddress(sellAsset),
36
38
  destinationChainId: buyRelayChainId,
37
39
  destinationCurrency: getRelayAssetAddress(buyAsset),
38
- tradeType: 'EXACT_INPUT',
39
- amount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
40
+ tradeType: isExactOutput ? 'EXACT_OUTPUT' : 'EXACT_INPUT',
41
+ amount: amount.cryptoBaseUnit,
40
42
  recipient,
41
43
  user: sendAddress,
42
44
  refundTo,
@@ -78,10 +80,19 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
78
80
  code: TradeQuoteError.UnknownError,
79
81
  }));
80
82
  }
81
- const { slippageTolerance, currencyOut, timeEstimate } = quote.details;
82
- const buyAmountAfterFeesCryptoBaseUnit = currencyOut.amount;
83
+ const { slippageTolerance, currencyIn, currencyOut, timeEstimate } = quote.details;
84
+ const sellAmountCryptoBaseUnit = currencyIn.amount;
85
+ const buyAmountAfterFeesCryptoBaseUnit = isExactOutput
86
+ ? currencyOut.minimumAmount
87
+ : currencyOut.amount;
88
+ if (isExactOutput && !bnOrZero(buyAmountAfterFeesCryptoBaseUnit).eq(amount.cryptoBaseUnit)) {
89
+ return Err(makeSwapErrorRight({
90
+ message: `Relay guarantees ${buyAmountAfterFeesCryptoBaseUnit} against a requested exact output of ${amount.cryptoBaseUnit}`,
91
+ code: TradeQuoteError.InvalidResponse,
92
+ }));
93
+ }
83
94
  const rate = getInputOutputRate({
84
- sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
95
+ sellAmountCryptoBaseUnit,
85
96
  buyAmountCryptoBaseUnit: buyAmountAfterFeesCryptoBaseUnit,
86
97
  sellAsset,
87
98
  buyAsset,
@@ -242,7 +253,7 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
242
253
  })();
243
254
  // Add back relayer service and gas fees (relayer is including both) since they are downsides,
244
255
  // and add appFees — these are quote-level and identical across every step
245
- const buyAmountBeforeFeesCryptoBaseUnit = bnOrZero(currencyOut.amount)
256
+ const buyAmountBeforeFeesCryptoBaseUnit = bnOrZero(buyAmountAfterFeesCryptoBaseUnit)
246
257
  .plus(relayerFeesBuyAssetCryptoBaseUnit)
247
258
  .plus(appFeesBaseUnit)
248
259
  .toFixed();
@@ -256,6 +267,7 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
256
267
  id: relayId,
257
268
  rate,
258
269
  swapperName: SwapperName.Relay,
270
+ isExactOutput,
259
271
  affiliateBps,
260
272
  slippageTolerancePercentageDecimal,
261
273
  },
@@ -263,7 +275,7 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
263
275
  rate,
264
276
  buyAmountBeforeFeesCryptoBaseUnit,
265
277
  buyAmountAfterFeesCryptoBaseUnit,
266
- sellAmountIncludingProtocolFeesCryptoBaseUnit,
278
+ sellAmountIncludingProtocolFeesCryptoBaseUnit: sellAmountCryptoBaseUnit,
267
279
  buyAsset,
268
280
  sellAsset,
269
281
  source: SwapperName.Relay,
@@ -273,7 +285,7 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
273
285
  affiliateBps,
274
286
  sellAsset,
275
287
  buyAsset,
276
- sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
288
+ sellAmountCryptoBaseUnit,
277
289
  buyAmountCryptoBaseUnit: buyAmountAfterFeesCryptoBaseUnit,
278
290
  fixedAssetId: chainIdToFeeAssetId(baseChainId),
279
291
  fixedAsset: deps.assetsById[chainIdToFeeAssetId(baseChainId)],
@@ -291,7 +303,7 @@ export const getRelayTradeContext = async ({ input, deps, relayChainMap, }) => {
291
303
  relayStepInputs,
292
304
  stepDataArgs: {
293
305
  sellAsset,
294
- sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
306
+ sellAmountCryptoBaseUnit,
295
307
  orderId,
296
308
  from: sendAddress,
297
309
  xpub,
@@ -4,7 +4,7 @@ import type { Result } from '@sniptt/monads';
4
4
  import type { TransactionInstruction } from '@solana/web3.js';
5
5
  import type { SwapErrorRight } from '../../../types.js';
6
6
  import type { chainIdToRelayChainId as relayChainMapImplementation } from '../constant.js';
7
- import type { RelayQuoteItem, RelaySolanaInstruction, RelayTradeQuoteInput, RelayTradeRateInput } from './types.js';
7
+ import type { RelayExactOutputTradeQuoteInput, RelayExactOutputTradeRateInput, RelayQuoteItem, RelaySolanaInstruction, RelayTradeQuoteInput, RelayTradeRateInput } from './types.js';
8
8
  export declare const assertValidTrade: ({ sellAsset, buyAsset, relayChainMap, }: {
9
9
  sellAsset: Asset;
10
10
  buyAsset: Asset;
@@ -14,7 +14,7 @@ export declare const assertValidTrade: ({ sellAsset, buyAsset, relayChainMap, }:
14
14
  buyRelayChainId: number;
15
15
  }, SwapErrorRight>;
16
16
  export declare const resolveRelayAddresses: ({ input, sellChainId, buyChainId, }: {
17
- input: RelayTradeQuoteInput | RelayTradeRateInput;
17
+ input: RelayTradeQuoteInput | RelayTradeRateInput | RelayExactOutputTradeQuoteInput | RelayExactOutputTradeRateInput;
18
18
  sellChainId: ChainId;
19
19
  buyChainId: ChainId;
20
20
  }) => {
@@ -1,6 +1,8 @@
1
- import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput, GetSolanaTradeQuoteInput, GetSolanaTradeRateInput, GetTronTradeQuoteInput, GetTronTradeRateInput, GetUtxoTradeQuoteInput, GetUtxoTradeRateInput } from '../../../types.js';
1
+ import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput, GetSolanaTradeQuoteInput, GetSolanaTradeRateInput, GetTronTradeQuoteInput, GetTronTradeRateInput, GetUtxoTradeQuoteInput, GetUtxoTradeRateInput, WithExactBuyAmount } from '../../../types.js';
2
2
  export type RelayTradeQuoteInput = GetEvmTradeQuoteInput | GetUtxoTradeQuoteInput | GetSolanaTradeQuoteInput | GetTronTradeQuoteInput;
3
3
  export type RelayTradeRateInput = GetEvmTradeRateInput | GetUtxoTradeRateInput | GetSolanaTradeRateInput | GetTronTradeRateInput;
4
+ export type RelayExactOutputTradeQuoteInput = WithExactBuyAmount<RelayTradeQuoteInput>;
5
+ export type RelayExactOutputTradeRateInput = WithExactBuyAmount<RelayTradeRateInput>;
4
6
  export type RelayTransactionMetadata = {
5
7
  to?: string;
6
8
  data?: string;
@@ -64,6 +66,7 @@ export type RelayFees = {
64
66
  app: RelayCurrencyData;
65
67
  };
66
68
  export type QuoteDetails = {
69
+ currencyIn: RelayCurrencyData;
67
70
  currencyOut: RelayCurrencyData;
68
71
  rate: string;
69
72
  slippageTolerance: {
@@ -3,6 +3,7 @@ import type { StepDataArgs, SwapErrorRight } from '../../../types.js';
3
3
  import type { SunioRoute, SunioTransactionData } from '../types.js';
4
4
  type BaseArgs = {
5
5
  route: SunioRoute;
6
+ sellAmountCryptoBaseUnit: string;
6
7
  };
7
8
  export type GetSunioStepDataArgs = StepDataArgs<BaseArgs>;
8
9
  type SunioRateStepData = {
@@ -3,12 +3,12 @@ import { Err, Ok } from '@sniptt/monads';
3
3
  import { makeNetworkFeeEstimationFailedErr } from '../../../utils/index.js';
4
4
  import { estimateSunioNetworkFeeCryptoBaseUnit } from './estimateSunioNetworkFee.js';
5
5
  export async function getSunioStepData(args) {
6
- const { type, route, sellAsset, from, input, deps } = args;
6
+ const { type, route, sellAsset, sellAmountCryptoBaseUnit, from, input, deps } = args;
7
7
  const estimateArgs = {
8
8
  rpcUrl: deps.config.VITE_TRON_NODE_URL,
9
9
  apiKey: deps.config.VITE_TRON_GRID_API_KEY,
10
10
  route,
11
- sellAmountCryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit,
11
+ sellAmountCryptoBaseUnit,
12
12
  isSellingNativeTrx: !contractAddressOrUndefined(sellAsset.assetId),
13
13
  address: from,
14
14
  slippageTolerancePercentageDecimal: input.slippageTolerancePercentageDecimal,
@@ -80,7 +80,12 @@ export const getSunioTradeContext = async ({ input, deps, }) => {
80
80
  }),
81
81
  },
82
82
  protocolFees,
83
- stepDataArgs: { deps, sellAsset, route: bestRoute },
83
+ stepDataArgs: {
84
+ deps,
85
+ sellAsset,
86
+ sellAmountCryptoBaseUnit: sellAmountIncludingProtocolFeesCryptoBaseUnit,
87
+ route: bestRoute,
88
+ },
84
89
  });
85
90
  }
86
91
  catch (error) {
@@ -93,6 +93,7 @@ export declare enum TradeQuoteError {
93
93
  NoRouteFound = "NoRouteFound",
94
94
  UnsupportedChain = "UnsupportedChain",
95
95
  CrossChainNotSupported = "CrossChainNotSupported",
96
+ ExactOutputNotSupported = "ExactOutputNotSupported",
96
97
  NetworkFeeEstimationFailed = "NetworkFeeEstimationFailed",
97
98
  TradingHalted = "TradingHalted",
98
99
  SellAmountBelowMinimum = "SellAmountBelowMinimum",
@@ -212,17 +213,30 @@ export type GetUtxoTradeRateInput = CommonTradeRateInput & {
212
213
  export type GetUtxoTradeQuoteInput = GetUtxoTradeQuoteWithWallet;
213
214
  export type GetTradeQuoteInput = GetUtxoTradeQuoteInput | GetEvmTradeQuoteInput | GetCosmosSdkTradeQuoteInput | GetTronTradeQuoteInput | GetNearTradeQuoteInput | GetTonTradeQuoteInput | GetSolanaTradeQuoteInput | GetStarknetTradeQuoteInput | GetSuiTradeQuoteInput;
214
215
  export type GetTradeRateInput = GetEvmTradeRateInput | GetCosmosSdkTradeRateInput | GetUtxoTradeRateInput | GetTronTradeRateInput | GetNearTradeRateInput | GetTonTradeRateInput | GetSolanaTradeRateInput | GetStarknetTradeRateInput | GetSuiTradeRateInput;
216
+ export type WithExactBuyAmount<T extends {
217
+ sellAmountIncludingProtocolFeesCryptoBaseUnit: string;
218
+ }> = T extends unknown ? Omit<T, 'sellAmountIncludingProtocolFeesCryptoBaseUnit'> & {
219
+ buyAmountCryptoBaseUnit: string;
220
+ } : never;
221
+ export type GetExactOutputTradeQuoteInput = WithExactBuyAmount<GetTradeQuoteInput>;
222
+ export type GetExactOutputTradeRateInput = WithExactBuyAmount<GetTradeRateInput>;
223
+ export type TradeAmount = {
224
+ direction: 'exactIn' | 'exactOut';
225
+ cryptoBaseUnit: string;
226
+ };
215
227
  type StepDataBaseArgs = {
216
228
  deps: SwapperDeps;
217
229
  sellAsset: Asset;
218
230
  };
231
+ type StepDataRateInput = GetTradeRateInput | GetExactOutputTradeRateInput;
232
+ type StepDataQuoteInput = GetTradeQuoteInput | GetExactOutputTradeQuoteInput;
219
233
  export type StepDataArgs<Base, Rate = unknown, Quote = unknown> = (StepDataBaseArgs & Base & {
220
234
  type: 'rate';
221
- input: GetTradeRateInput;
235
+ input: StepDataRateInput;
222
236
  from?: string;
223
237
  } & Rate) | (StepDataBaseArgs & Base & {
224
238
  type: 'quote';
225
- input: GetTradeQuoteInput;
239
+ input: StepDataQuoteInput;
226
240
  from: string;
227
241
  } & Quote);
228
242
  export type EvmSwapperDeps = {
@@ -355,6 +369,7 @@ export type TradeCommon = {
355
369
  slippageTolerancePercentageDecimal: string | undefined;
356
370
  isLongtail?: boolean;
357
371
  swapperName: SwapperName;
372
+ isExactOutput?: boolean;
358
373
  };
359
374
  type TradeQuoteBase = TradeCommon & {
360
375
  receiveAddress: string | undefined;
@@ -584,6 +599,8 @@ export type SwapperApi = {
584
599
  checkTradeStatus: (input: CheckTradeStatusInput) => Promise<TradeStatus>;
585
600
  getTradeQuote: (input: GetTradeQuoteInput, deps: SwapperDeps) => Promise<TradeQuoteResult>;
586
601
  getTradeRate: (input: GetTradeRateInput, deps: SwapperDeps) => Promise<TradeRateResult>;
602
+ getExactOutputTradeQuote?: (input: GetExactOutputTradeQuoteInput, deps: SwapperDeps) => Promise<TradeQuoteResult>;
603
+ getExactOutputTradeRate?: (input: GetExactOutputTradeRateInput, deps: SwapperDeps) => Promise<TradeRateResult>;
587
604
  getUnsignedEvmTransaction?: (input: GetUnsignedEvmTransactionArgs) => Promise<SignTx<EvmChainId>>;
588
605
  getUnsignedEvmMessage?: (input: GetUnsignedEvmMessageArgs) => Promise<EvmMessageToSign>;
589
606
  getUnsignedUtxoTransaction?: (input: GetUnsignedUtxoTransactionArgs) => Promise<SignTx<UtxoChainId>>;
package/dist/esm/types.js CHANGED
@@ -30,6 +30,8 @@ export var TradeQuoteError;
30
30
  TradeQuoteError["UnsupportedChain"] = "UnsupportedChain";
31
31
  // the swapper can't swap across chains
32
32
  TradeQuoteError["CrossChainNotSupported"] = "CrossChainNotSupported";
33
+ // the swapper can quote this pair, but can't derive a sell amount from an exact buy amount
34
+ TradeQuoteError["ExactOutputNotSupported"] = "ExactOutputNotSupported";
33
35
  // the swapper wasn't able to get a network fee estimate
34
36
  TradeQuoteError["NetworkFeeEstimationFailed"] = "NetworkFeeEstimationFailed";
35
37
  // trading has been halted upstream
@@ -1,5 +1,11 @@
1
1
  import type { AssetId, ChainId } from '@shapeshiftoss/caip';
2
+ import type { TradeAmount } from '../types.js';
2
3
  export declare const FALLBACK_QUOTE_DEADLINE_MS = 60000;
4
+ export declare const getTradeAmount: (input: {
5
+ sellAmountIncludingProtocolFeesCryptoBaseUnit: string;
6
+ } | {
7
+ buyAmountCryptoBaseUnit: string;
8
+ }) => TradeAmount;
3
9
  export declare const normalizeEpochToMs: (value: number) => number;
4
10
  export declare const isNativeEvmAsset: (assetId: AssetId) => boolean;
5
11
  export declare const getTreasuryAddressFromChainId: (chainId: ChainId) => string;
@@ -3,6 +3,9 @@ import { KnownChainIds } from '@shapeshiftoss/types';
3
3
  import { DAO_TREASURY_ARBITRUM, DAO_TREASURY_AVALANCHE, DAO_TREASURY_BASE, DAO_TREASURY_BITCOIN, DAO_TREASURY_BOB, DAO_TREASURY_BSC, DAO_TREASURY_ETHEREUM_MAINNET, DAO_TREASURY_GNOSIS, DAO_TREASURY_HYPEREVM, DAO_TREASURY_MONAD, DAO_TREASURY_OPTIMISM, DAO_TREASURY_POLYGON, DAO_TREASURY_SOLANA, DAO_TREASURY_STARKNET, DAO_TREASURY_TON, isTreasuryChainId, } from '@shapeshiftoss/utils';
4
4
  // Deadline for providers without their own expiry - short enough to keep priced amounts honest
5
5
  export const FALLBACK_QUOTE_DEADLINE_MS = 60_000;
6
+ export const getTradeAmount = (input) => 'buyAmountCryptoBaseUnit' in input
7
+ ? { direction: 'exactOut', cryptoBaseUnit: input.buyAmountCryptoBaseUnit }
8
+ : { direction: 'exactIn', cryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit };
6
9
  // Bands are unambiguous for any realistic date: unix s land ~2e9, ms ~2e12, µs ~2e15, ns ~2e18
7
10
  export const normalizeEpochToMs = (value) => {
8
11
  if (value < 1e12)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshiftoss/swapper",
3
- "version": "19.0.0",
3
+ "version": "20.0.0",
4
4
  "repository": "https://github.com/shapeshift/web",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -50,13 +50,13 @@
50
50
  "retry-axios": "^2.6.0",
51
51
  "uuid": "^9.0.0",
52
52
  "viem": "2.55.11",
53
- "@shapeshiftoss/caip": "^8.16.10",
53
+ "@shapeshiftoss/chain-adapters": "^11.5.1",
54
54
  "@shapeshiftoss/hdwallet-core": "^1.62.41",
55
- "@shapeshiftoss/types": "^9.0.0",
56
- "@shapeshiftoss/unchained-client": "^10.14.11",
57
55
  "@shapeshiftoss/contracts": "^1.0.7",
56
+ "@shapeshiftoss/caip": "^8.16.10",
57
+ "@shapeshiftoss/unchained-client": "^10.14.11",
58
58
  "@shapeshiftoss/utils": "^1.1.0",
59
- "@shapeshiftoss/chain-adapters": "^11.5.1"
59
+ "@shapeshiftoss/types": "^9.0.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/lodash": "^4.14.178",