@shapeshiftoss/swapper 20.3.0 → 20.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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/constants.js +15 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.js +0 -2
- package/dist/cjs/swappers/AvnuSwapper/swapperApi/getTradeQuote.js +1 -2
- package/dist/cjs/swappers/BebopSwapper/utils/fetchFromBebop.d.ts +2 -1
- package/dist/cjs/swappers/BebopSwapper/utils/fetchFromBebop.js +21 -15
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopSolanaTradeContext.js +1 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +0 -2
- package/dist/cjs/swappers/ButterSwap/swapperApi/getTradeQuote.js +0 -2
- package/dist/cjs/swappers/CetusSwapper/swapperApi/getTradeQuote.js +0 -2
- package/dist/cjs/swappers/ChainflipSwapper/swapperApi/getTradeQuote.js +1 -2
- package/dist/cjs/swappers/ChainflipSwapper/types.d.ts +1 -0
- package/dist/cjs/swappers/DebridgeSwapper/getTradeQuote/getTradeQuote.js +0 -2
- package/dist/cjs/swappers/FyndSwapper/FyndSwapper.d.ts +2 -0
- package/dist/cjs/swappers/FyndSwapper/FyndSwapper.js +5 -0
- package/dist/cjs/swappers/FyndSwapper/endpoints.d.ts +2 -0
- package/dist/cjs/swappers/FyndSwapper/endpoints.js +14 -0
- package/dist/cjs/swappers/FyndSwapper/getTradeQuote/getTradeQuote.d.ts +4 -0
- package/dist/cjs/swappers/FyndSwapper/getTradeQuote/getTradeQuote.js +43 -0
- package/dist/cjs/swappers/FyndSwapper/getTradeRate/getTradeRate.d.ts +4 -0
- package/dist/cjs/swappers/FyndSwapper/getTradeRate/getTradeRate.js +34 -0
- package/dist/cjs/swappers/FyndSwapper/index.d.ts +2 -0
- package/dist/cjs/swappers/FyndSwapper/index.js +7 -0
- package/dist/cjs/swappers/FyndSwapper/types.d.ts +41 -0
- package/dist/cjs/swappers/FyndSwapper/types.js +2 -0
- package/dist/cjs/swappers/FyndSwapper/utils/constants.d.ts +33 -0
- package/dist/cjs/swappers/FyndSwapper/utils/constants.js +38 -0
- package/dist/cjs/swappers/FyndSwapper/utils/fetchFromFynd.d.ts +13 -0
- package/dist/cjs/swappers/FyndSwapper/utils/fetchFromFynd.js +42 -0
- package/dist/cjs/swappers/FyndSwapper/utils/fyndService.d.ts +5 -0
- package/dist/cjs/swappers/FyndSwapper/utils/fyndService.js +9 -0
- package/dist/cjs/swappers/FyndSwapper/utils/getFyndStepData.d.ts +25 -0
- package/dist/cjs/swappers/FyndSwapper/utils/getFyndStepData.js +48 -0
- package/dist/cjs/swappers/FyndSwapper/utils/getFyndTradeContext.d.ts +18 -0
- package/dist/cjs/swappers/FyndSwapper/utils/getFyndTradeContext.js +94 -0
- package/dist/cjs/swappers/FyndSwapper/utils/helpers.d.ts +24 -0
- package/dist/cjs/swappers/FyndSwapper/utils/helpers.js +174 -0
- package/dist/cjs/swappers/FyndSwapper/utils/helpers.test.d.ts +1 -0
- package/dist/cjs/swappers/FyndSwapper/utils/helpers.test.js +101 -0
- package/dist/cjs/swappers/MayachainSwapper/generated/generatedTradableAssetMap.json +0 -1
- package/dist/cjs/swappers/PortalsSwapper/endpoints.js +4 -1
- package/dist/cjs/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +1 -1
- package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +2 -3
- package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +1 -0
- package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.js +4 -0
- package/dist/cjs/swappers/RelaySwapper/utils/relayStatus.js +3 -3
- package/dist/cjs/swappers/RelaySwapper/utils/types.d.ts +9 -4
- package/dist/cjs/swappers/SymbiosisSwapper/SymbiosisSwapper.d.ts +2 -0
- package/dist/cjs/swappers/SymbiosisSwapper/SymbiosisSwapper.js +8 -0
- package/dist/cjs/swappers/SymbiosisSwapper/endpoints.d.ts +2 -0
- package/dist/cjs/swappers/SymbiosisSwapper/endpoints.js +66 -0
- package/dist/cjs/swappers/SymbiosisSwapper/getTradeQuote/getTradeQuote.d.ts +4 -0
- package/dist/cjs/swappers/SymbiosisSwapper/getTradeQuote/getTradeQuote.js +42 -0
- package/dist/cjs/swappers/SymbiosisSwapper/getTradeRate/getTradeRate.d.ts +4 -0
- package/dist/cjs/swappers/SymbiosisSwapper/getTradeRate/getTradeRate.js +34 -0
- package/dist/cjs/swappers/SymbiosisSwapper/index.d.ts +2 -0
- package/dist/cjs/swappers/SymbiosisSwapper/index.js +7 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/constants.d.ts +19 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/constants.js +64 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.d.ts +26 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.js +106 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.test.d.ts +1 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.test.js +161 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisTradeContext.d.ts +17 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/getSymbiosisTradeContext.js +146 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/helpers.d.ts +38 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/helpers.js +172 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/helpers.test.d.ts +1 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/helpers.test.js +151 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/symbiosisService.d.ts +5 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/symbiosisService.js +18 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/types.d.ts +83 -0
- package/dist/cjs/swappers/SymbiosisSwapper/utils/types.js +11 -0
- package/dist/cjs/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +1 -0
- package/dist/cjs/swappers/ThorchainSwapper/generated/generatedTradableAssetMap.json +1 -0
- package/dist/cjs/swappers/ThorchainSwapper/utils/getLongtailQuote.js +1 -1
- package/dist/cjs/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.js +24 -1
- package/dist/cjs/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.d.ts +1 -0
- package/dist/cjs/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.js +110 -0
- package/dist/cjs/swappers/ZrxSwapper/types.d.ts +2 -1
- package/dist/cjs/swappers/ZrxSwapper/utils/getZrxNativeCheckDeadline.d.ts +1 -0
- package/dist/cjs/swappers/ZrxSwapper/utils/getZrxNativeCheckDeadline.js +26 -0
- package/dist/cjs/types.d.ts +6 -5
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/utils/helpers.d.ts +1 -2
- package/dist/cjs/utils/helpers.js +8 -32
- package/dist/cjs/utils/helpers.test.js +6 -2
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/constants.js +15 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.js +0 -2
- package/dist/esm/swappers/AvnuSwapper/swapperApi/getTradeQuote.js +1 -2
- package/dist/esm/swappers/BebopSwapper/utils/fetchFromBebop.d.ts +2 -1
- package/dist/esm/swappers/BebopSwapper/utils/fetchFromBebop.js +21 -15
- package/dist/esm/swappers/BebopSwapper/utils/getBebopSolanaTradeContext.js +1 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +0 -2
- package/dist/esm/swappers/ButterSwap/swapperApi/getTradeQuote.js +0 -2
- package/dist/esm/swappers/CetusSwapper/swapperApi/getTradeQuote.js +0 -2
- package/dist/esm/swappers/ChainflipSwapper/swapperApi/getTradeQuote.js +1 -2
- package/dist/esm/swappers/ChainflipSwapper/types.d.ts +1 -0
- package/dist/esm/swappers/DebridgeSwapper/getTradeQuote/getTradeQuote.js +0 -2
- package/dist/esm/swappers/FyndSwapper/FyndSwapper.d.ts +2 -0
- package/dist/esm/swappers/FyndSwapper/FyndSwapper.js +2 -0
- package/dist/esm/swappers/FyndSwapper/endpoints.d.ts +2 -0
- package/dist/esm/swappers/FyndSwapper/endpoints.js +11 -0
- package/dist/esm/swappers/FyndSwapper/getTradeQuote/getTradeQuote.d.ts +4 -0
- package/dist/esm/swappers/FyndSwapper/getTradeQuote/getTradeQuote.js +39 -0
- package/dist/esm/swappers/FyndSwapper/getTradeRate/getTradeRate.d.ts +4 -0
- package/dist/esm/swappers/FyndSwapper/getTradeRate/getTradeRate.js +30 -0
- package/dist/esm/swappers/FyndSwapper/index.d.ts +2 -0
- package/dist/esm/swappers/FyndSwapper/index.js +2 -0
- package/dist/esm/swappers/FyndSwapper/types.d.ts +41 -0
- package/dist/esm/swappers/FyndSwapper/types.js +1 -0
- package/dist/esm/swappers/FyndSwapper/utils/constants.d.ts +33 -0
- package/dist/esm/swappers/FyndSwapper/utils/constants.js +35 -0
- package/dist/esm/swappers/FyndSwapper/utils/fetchFromFynd.d.ts +13 -0
- package/dist/esm/swappers/FyndSwapper/utils/fetchFromFynd.js +38 -0
- package/dist/esm/swappers/FyndSwapper/utils/fyndService.d.ts +5 -0
- package/dist/esm/swappers/FyndSwapper/utils/fyndService.js +3 -0
- package/dist/esm/swappers/FyndSwapper/utils/getFyndStepData.d.ts +25 -0
- package/dist/esm/swappers/FyndSwapper/utils/getFyndStepData.js +44 -0
- package/dist/esm/swappers/FyndSwapper/utils/getFyndTradeContext.d.ts +18 -0
- package/dist/esm/swappers/FyndSwapper/utils/getFyndTradeContext.js +90 -0
- package/dist/esm/swappers/FyndSwapper/utils/helpers.d.ts +24 -0
- package/dist/esm/swappers/FyndSwapper/utils/helpers.js +162 -0
- package/dist/esm/swappers/FyndSwapper/utils/helpers.test.d.ts +1 -0
- package/dist/esm/swappers/FyndSwapper/utils/helpers.test.js +99 -0
- package/dist/esm/swappers/MayachainSwapper/generated/generatedTradableAssetMap.json +0 -1
- package/dist/esm/swappers/PortalsSwapper/endpoints.js +4 -1
- package/dist/esm/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +2 -2
- package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +2 -3
- package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +1 -0
- package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.js +5 -1
- package/dist/esm/swappers/RelaySwapper/utils/relayStatus.js +3 -3
- package/dist/esm/swappers/RelaySwapper/utils/types.d.ts +9 -4
- package/dist/esm/swappers/SymbiosisSwapper/SymbiosisSwapper.d.ts +2 -0
- package/dist/esm/swappers/SymbiosisSwapper/SymbiosisSwapper.js +5 -0
- package/dist/esm/swappers/SymbiosisSwapper/endpoints.d.ts +2 -0
- package/dist/esm/swappers/SymbiosisSwapper/endpoints.js +63 -0
- package/dist/esm/swappers/SymbiosisSwapper/getTradeQuote/getTradeQuote.d.ts +4 -0
- package/dist/esm/swappers/SymbiosisSwapper/getTradeQuote/getTradeQuote.js +38 -0
- package/dist/esm/swappers/SymbiosisSwapper/getTradeRate/getTradeRate.d.ts +4 -0
- package/dist/esm/swappers/SymbiosisSwapper/getTradeRate/getTradeRate.js +30 -0
- package/dist/esm/swappers/SymbiosisSwapper/index.d.ts +2 -0
- package/dist/esm/swappers/SymbiosisSwapper/index.js +2 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/constants.d.ts +19 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/constants.js +61 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.d.ts +26 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.js +102 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.test.d.ts +1 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisStepData.test.js +159 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisTradeContext.d.ts +17 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/getSymbiosisTradeContext.js +139 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/helpers.d.ts +38 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/helpers.js +156 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/helpers.test.d.ts +1 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/helpers.test.js +149 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/symbiosisService.d.ts +5 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/symbiosisService.js +12 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/types.d.ts +83 -0
- package/dist/esm/swappers/SymbiosisSwapper/utils/types.js +8 -0
- package/dist/esm/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +1 -0
- package/dist/esm/swappers/ThorchainSwapper/generated/generatedTradableAssetMap.json +1 -0
- package/dist/esm/swappers/ThorchainSwapper/utils/getLongtailQuote.js +1 -1
- package/dist/esm/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.js +25 -2
- package/dist/esm/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.d.ts +1 -0
- package/dist/esm/swappers/ZrxSwapper/getZrxTradeQuote/getZrxTradeQuote.test.js +108 -0
- package/dist/esm/swappers/ZrxSwapper/types.d.ts +2 -1
- package/dist/esm/swappers/ZrxSwapper/utils/getZrxNativeCheckDeadline.d.ts +1 -0
- package/dist/esm/swappers/ZrxSwapper/utils/getZrxNativeCheckDeadline.js +22 -0
- package/dist/esm/types.d.ts +6 -5
- package/dist/esm/types.js +2 -0
- package/dist/esm/utils/helpers.d.ts +1 -2
- package/dist/esm/utils/helpers.js +9 -33
- package/dist/esm/utils/helpers.test.js +6 -2
- package/package.json +7 -7
|
@@ -2,11 +2,13 @@ import { Err, Ok } from '@sniptt/monads';
|
|
|
2
2
|
import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants.js';
|
|
3
3
|
import { SwapperName, TradeQuoteError } from '../../../types.js';
|
|
4
4
|
import { assertQuoteAddresses, makeSwapErrorRight } from '../../../utils/index.js';
|
|
5
|
-
import {
|
|
5
|
+
import { isNativeEvmAsset } from '../../../utils/helpers.js';
|
|
6
6
|
import { fetchZrxQuote } from '../utils/fetchFromZrx.js';
|
|
7
|
+
import { getZrxNativeCheckDeadline } from '../utils/getZrxNativeCheckDeadline.js';
|
|
7
8
|
import { getZrxStepData } from '../utils/getZrxStepData.js';
|
|
8
9
|
import { getZrxTradeContext } from '../utils/getZrxTradeContext.js';
|
|
9
10
|
import { assertValidTrade, isWrappedNativeSell } from '../utils/helpers.js';
|
|
11
|
+
const isValidDeadlineSeconds = (deadline) => Number.isSafeInteger(deadline) && deadline > 0 && Number.isSafeInteger(deadline * 1000);
|
|
10
12
|
export const getZrxTradeQuote = async (input, deps) => {
|
|
11
13
|
const { sellAsset, buyAsset, accountNumber, affiliateBps, sellAmountIncludingProtocolFeesCryptoBaseUnit, } = input;
|
|
12
14
|
const maybeAddresses = assertQuoteAddresses(input);
|
|
@@ -39,6 +41,16 @@ export const getZrxTradeQuote = async (input, deps) => {
|
|
|
39
41
|
return Err(maybeZrxQuoteResponse.unwrapErr());
|
|
40
42
|
const { sellAmount, buyAmount, fees, permit2, transaction, route } = maybeZrxQuoteResponse.unwrap();
|
|
41
43
|
const permit2Eip712 = permit2?.eip712;
|
|
44
|
+
const permit2Deadline = permit2Eip712 ? Number(permit2Eip712.message.deadline) : undefined;
|
|
45
|
+
if (permit2Deadline !== undefined &&
|
|
46
|
+
((typeof permit2Eip712?.message.deadline !== 'string' &&
|
|
47
|
+
typeof permit2Eip712?.message.deadline !== 'number') ||
|
|
48
|
+
!isValidDeadlineSeconds(permit2Deadline))) {
|
|
49
|
+
return Err(makeSwapErrorRight({
|
|
50
|
+
message: 'Invalid Permit2 deadline from 0x response',
|
|
51
|
+
code: TradeQuoteError.InvalidResponse,
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
42
54
|
if (!isNativeEvmAsset(sellAsset.assetId) && !isWrappedNativeSell(route) && !permit2Eip712) {
|
|
43
55
|
return Err(makeSwapErrorRight({
|
|
44
56
|
message: 'Missing required Permit2 metadata from 0x response',
|
|
@@ -53,6 +65,17 @@ export const getZrxTradeQuote = async (input, deps) => {
|
|
|
53
65
|
details: { transaction, permit2Eip712 },
|
|
54
66
|
}));
|
|
55
67
|
}
|
|
68
|
+
// Permit2 calldata is not decodable until the signature is spliced in, so only native sells are read
|
|
69
|
+
const nativeCheckDeadline = permit2Eip712
|
|
70
|
+
? undefined
|
|
71
|
+
: getZrxNativeCheckDeadline(transaction.data);
|
|
72
|
+
if (nativeCheckDeadline !== undefined && !isValidDeadlineSeconds(nativeCheckDeadline)) {
|
|
73
|
+
return Err(makeSwapErrorRight({
|
|
74
|
+
message: 'Invalid NATIVE_CHECK deadline in 0x calldata',
|
|
75
|
+
code: TradeQuoteError.InvalidResponse,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
const deadlineSeconds = permit2Deadline ?? nativeCheckDeadline;
|
|
56
79
|
const maybeContext = getZrxTradeContext({
|
|
57
80
|
input,
|
|
58
81
|
deps,
|
|
@@ -76,7 +99,7 @@ export const getZrxTradeQuote = async (input, deps) => {
|
|
|
76
99
|
const tradeQuote = {
|
|
77
100
|
...tradeCommon,
|
|
78
101
|
quoteOrRate: 'quote',
|
|
79
|
-
deadline:
|
|
102
|
+
deadline: deadlineSeconds === undefined ? undefined : deadlineSeconds * 1000,
|
|
80
103
|
receiveAddress,
|
|
81
104
|
steps: [
|
|
82
105
|
{
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
2
|
+
import { Ok } from '@sniptt/monads';
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { TradeQuoteError } from '../../../types.js';
|
|
5
|
+
import { ETH, USDC_MAINNET, WETH } from '../../../utils/test-data/assets.js';
|
|
6
|
+
import { fetchZrxQuote } from '../utils/fetchFromZrx.js';
|
|
7
|
+
import { getZrxTradeQuote } from './getZrxTradeQuote.js';
|
|
8
|
+
vi.mock('../utils/fetchFromZrx', () => ({ fetchZrxQuote: vi.fn() }));
|
|
9
|
+
vi.mock('../utils/getZrxStepData', () => ({
|
|
10
|
+
getZrxStepData: vi.fn(({ permit2Eip712 }) => Promise.resolve(Ok({
|
|
11
|
+
transactionData: {
|
|
12
|
+
type: 'evm',
|
|
13
|
+
chainId: 1,
|
|
14
|
+
to: '0x1111111111111111111111111111111111111111',
|
|
15
|
+
data: '0x1234',
|
|
16
|
+
value: '0',
|
|
17
|
+
...(permit2Eip712 && {
|
|
18
|
+
signatureRequired: { type: 'permit2', eip712: permit2Eip712 },
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
networkFeeCryptoBaseUnit: '100000',
|
|
22
|
+
}))),
|
|
23
|
+
}));
|
|
24
|
+
const input = {
|
|
25
|
+
sellAsset: WETH,
|
|
26
|
+
buyAsset: USDC_MAINNET,
|
|
27
|
+
sellAmountIncludingProtocolFeesCryptoBaseUnit: '1000000000000000000',
|
|
28
|
+
sendAddress: '0x1111111111111111111111111111111111111111',
|
|
29
|
+
receiveAddress: '0x1111111111111111111111111111111111111111',
|
|
30
|
+
accountNumber: 0,
|
|
31
|
+
affiliateBps: '0',
|
|
32
|
+
allowMultiHop: false,
|
|
33
|
+
quoteOrRate: 'quote',
|
|
34
|
+
chainId: KnownChainIds.EthereumMainnet,
|
|
35
|
+
supportsEIP1559: true,
|
|
36
|
+
};
|
|
37
|
+
const deps = {
|
|
38
|
+
assetsById: {},
|
|
39
|
+
config: { VITE_ZRX_BASE_URL: 'https://example.com' },
|
|
40
|
+
};
|
|
41
|
+
const typedData = (deadline) => ({
|
|
42
|
+
domain: { name: 'Permit2', chainId: 1 },
|
|
43
|
+
types: { PermitTransferFrom: [{ name: 'deadline', type: 'uint256' }] },
|
|
44
|
+
primaryType: 'PermitTransferFrom',
|
|
45
|
+
message: { deadline },
|
|
46
|
+
});
|
|
47
|
+
// Live Settler calldata for an ETH -> USDC sell, NATIVE_CHECK deadline 1791997786
|
|
48
|
+
const nativeSellCalldata = '0x1fff991f000000000000000000000000ea8eb5ba11a3ea66f417ae29abf70c6fb4ba9626000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000e750ef800000000000000000000000000000000000000000000000000000000000000a0939d83c32b72441d72643cf60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000044bd01c226000000000000000000000000000000000000000000000000000000006acfb75a000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010438c9c147000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000024d0e30db00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e48d68a156000000000000000000000000666fedd4cdd4e890a5ad20e7b60975409435a64a00000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040c02aaa39b223fe8d0a0e5c4f27ead9083c756cc201000064fffd8963efd1fc6a506488495d951d5263988d25a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008434ee90ca000000000000000000000000f5c4f3dc02c3fb9279495a8fef7b0741da956157000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000e9a9ab900000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000';
|
|
49
|
+
const quoteResponse = (eip712, data = '0x1234') => ({
|
|
50
|
+
blockNumber: '1',
|
|
51
|
+
buyAmount: '1000000',
|
|
52
|
+
buyToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
53
|
+
sellAmount: input.sellAmountIncludingProtocolFeesCryptoBaseUnit,
|
|
54
|
+
sellToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
|
|
55
|
+
fees: { integratorFee: null, zeroExFee: null, gasFee: null },
|
|
56
|
+
issues: { allowance: null, balance: null, simulationIncomplete: false, invalidSourcesPassed: [] },
|
|
57
|
+
liquidityAvailable: true,
|
|
58
|
+
minBuyAmount: '990000',
|
|
59
|
+
route: { fills: [], tokens: [] },
|
|
60
|
+
tokenMetadata: {
|
|
61
|
+
buyToken: { buyTaxBps: null, sellTaxBps: null },
|
|
62
|
+
sellToken: { buyTaxBps: null, sellTaxBps: null },
|
|
63
|
+
},
|
|
64
|
+
totalNetworkFee: null,
|
|
65
|
+
zid: 'test',
|
|
66
|
+
permit2: eip712 ? { type: 'Permit2', hash: '0x1234', eip712 } : null,
|
|
67
|
+
transaction: {
|
|
68
|
+
to: '0x1111111111111111111111111111111111111111',
|
|
69
|
+
data,
|
|
70
|
+
gas: '100000',
|
|
71
|
+
gasPrice: '1000000000',
|
|
72
|
+
value: '0',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
describe('getZrxTradeQuote Permit2 deadline', () => {
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
vi.mocked(fetchZrxQuote).mockResolvedValue(Ok(quoteResponse(typedData('1791934983'))));
|
|
78
|
+
});
|
|
79
|
+
it.each(['1791934983', 1791934983])('uses the provider deadline in milliseconds (%s)', async (deadline) => {
|
|
80
|
+
const eip712 = typedData(deadline);
|
|
81
|
+
vi.mocked(fetchZrxQuote).mockResolvedValue(Ok(quoteResponse(eip712)));
|
|
82
|
+
const result = await getZrxTradeQuote(input, deps);
|
|
83
|
+
expect(result.isOk()).toBe(true);
|
|
84
|
+
const [quote] = result.unwrap();
|
|
85
|
+
expect(quote.deadline).toBe(1791934983000);
|
|
86
|
+
expect(quote.steps[0].transactionData).toMatchObject({
|
|
87
|
+
signatureRequired: { eip712 },
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
it.each([undefined, null, true, '', 'invalid', '-1', '1.5', '9007199254740991'])('rejects an invalid Permit2 deadline (%s)', async (deadline) => {
|
|
91
|
+
vi.mocked(fetchZrxQuote).mockResolvedValue(Ok(quoteResponse(typedData(deadline))));
|
|
92
|
+
const result = await getZrxTradeQuote(input, deps);
|
|
93
|
+
expect(result.isErr()).toBe(true);
|
|
94
|
+
expect(result.unwrapErr().code).toBe(TradeQuoteError.InvalidResponse);
|
|
95
|
+
});
|
|
96
|
+
it('reads the NATIVE_CHECK deadline from native-token sell calldata', async () => {
|
|
97
|
+
vi.mocked(fetchZrxQuote).mockResolvedValue(Ok(quoteResponse(null, nativeSellCalldata)));
|
|
98
|
+
const result = await getZrxTradeQuote({ ...input, sellAsset: ETH }, deps);
|
|
99
|
+
expect(result.isOk()).toBe(true);
|
|
100
|
+
expect(result.unwrap()[0].deadline).toBe(1791997786000);
|
|
101
|
+
});
|
|
102
|
+
it('leaves native-token quotes without a NATIVE_CHECK action free of a fabricated deadline', async () => {
|
|
103
|
+
vi.mocked(fetchZrxQuote).mockResolvedValue(Ok(quoteResponse(null)));
|
|
104
|
+
const result = await getZrxTradeQuote({ ...input, sellAsset: ETH }, deps);
|
|
105
|
+
expect(result.isOk()).toBe(true);
|
|
106
|
+
expect(result.unwrap()[0].deadline).toBeUndefined();
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TypedData } from 'eip-712';
|
|
3
|
+
import type { Address } from 'viem';
|
|
3
4
|
import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput } from '../../types.js';
|
|
4
5
|
export type ZrxTradeQuoteInput = GetEvmTradeQuoteInput;
|
|
5
6
|
export type ZrxTradeRateInput = GetEvmTradeRateInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getZrxNativeCheckDeadline: (data: string) => number | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { decodeFunctionData, parseAbi, toFunctionSelector } from 'viem';
|
|
2
|
+
const settlerAbi = parseAbi([
|
|
3
|
+
'function execute((address recipient, address buyToken, uint256 minAmountOut) slippage, bytes[] actions, bytes32 zid)',
|
|
4
|
+
'function NATIVE_CHECK(uint256 deadline, uint256 msgValue)',
|
|
5
|
+
]);
|
|
6
|
+
const NATIVE_CHECK_SELECTOR = toFunctionSelector('function NATIVE_CHECK(uint256,uint256)');
|
|
7
|
+
// Native sells carry no Permit2, but Settler reverts with SignatureExpired past any NATIVE_CHECK deadline
|
|
8
|
+
export const getZrxNativeCheckDeadline = (data) => {
|
|
9
|
+
try {
|
|
10
|
+
const { functionName, args } = decodeFunctionData({ abi: settlerAbi, data: data });
|
|
11
|
+
if (functionName !== 'execute')
|
|
12
|
+
return undefined;
|
|
13
|
+
const deadlines = args[1]
|
|
14
|
+
.filter(action => action.startsWith(NATIVE_CHECK_SELECTOR))
|
|
15
|
+
.map(action => decodeFunctionData({ abi: settlerAbi, data: action }))
|
|
16
|
+
.flatMap(decoded => decoded.functionName === 'NATIVE_CHECK' ? [Number(decoded.args[0])] : []);
|
|
17
|
+
return deadlines.length ? Math.min(...deadlines) : undefined;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
};
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export type SwapperConfig = {
|
|
|
43
43
|
VITE_COWSWAP_BASE_URL: string;
|
|
44
44
|
VITE_PORTALS_BASE_URL: string;
|
|
45
45
|
VITE_ZRX_BASE_URL: string;
|
|
46
|
+
VITE_FYND_BASE_URL: string;
|
|
46
47
|
VITE_CHAINFLIP_API_KEY: string;
|
|
47
48
|
VITE_CHAINFLIP_API_URL: string;
|
|
48
49
|
VITE_FEATURE_CHAINFLIP_SWAP_DCA: boolean;
|
|
@@ -56,6 +57,7 @@ export type SwapperConfig = {
|
|
|
56
57
|
VITE_ACROSS_API_KEY: string;
|
|
57
58
|
VITE_DEBRIDGE_API_URL: string;
|
|
58
59
|
VITE_BOB_GATEWAY_API_KEY: string;
|
|
60
|
+
VITE_SYMBIOSIS_API_URL: string;
|
|
59
61
|
};
|
|
60
62
|
export declare enum SwapperName {
|
|
61
63
|
Thorchain = "THORChain",
|
|
@@ -76,7 +78,9 @@ export declare enum SwapperName {
|
|
|
76
78
|
Stonfi = "STON.fi",
|
|
77
79
|
Across = "Across",
|
|
78
80
|
Debridge = "deBridge",
|
|
79
|
-
BobGateway = "BOB Gateway"
|
|
81
|
+
BobGateway = "BOB Gateway",
|
|
82
|
+
Symbiosis = "Symbiosis",
|
|
83
|
+
Fynd = "Fynd"
|
|
80
84
|
}
|
|
81
85
|
export type SwapSource = SwapperName | `${SwapperName} • ${string}`;
|
|
82
86
|
export type SwapErrorRight = {
|
|
@@ -343,9 +347,6 @@ export type TradeStepCommon = {
|
|
|
343
347
|
estimatedExecutionTimeMs: number | undefined;
|
|
344
348
|
swapperMetadata?: SwapperMetadata;
|
|
345
349
|
stonfiTransactionData?: StonfiTransactionData;
|
|
346
|
-
chainflipSpecific?: {
|
|
347
|
-
depositAddress?: string;
|
|
348
|
-
};
|
|
349
350
|
affiliateFee?: AffiliateFee;
|
|
350
351
|
};
|
|
351
352
|
export type TradeQuoteStep = TradeStepCommon & {
|
|
@@ -452,7 +453,7 @@ export type TradeQuote = TradeQuoteBase & {
|
|
|
452
453
|
} & {
|
|
453
454
|
quoteOrRate: 'quote';
|
|
454
455
|
receiveAddress: string;
|
|
455
|
-
deadline
|
|
456
|
+
deadline?: number;
|
|
456
457
|
};
|
|
457
458
|
export type MultiHopTradeQuote = TradeQuote & {
|
|
458
459
|
steps: MultiHopTradeQuoteSteps;
|
package/dist/esm/types.js
CHANGED
|
@@ -19,6 +19,8 @@ export var SwapperName;
|
|
|
19
19
|
SwapperName["Across"] = "Across";
|
|
20
20
|
SwapperName["Debridge"] = "deBridge";
|
|
21
21
|
SwapperName["BobGateway"] = "BOB Gateway";
|
|
22
|
+
SwapperName["Symbiosis"] = "Symbiosis";
|
|
23
|
+
SwapperName["Fynd"] = "Fynd";
|
|
22
24
|
})(SwapperName || (SwapperName = {}));
|
|
23
25
|
export var TradeQuoteError;
|
|
24
26
|
(function (TradeQuoteError) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { AssetId, ChainId } from '@shapeshiftoss/caip';
|
|
2
2
|
import type { TradeAmount, TradeStepCommon } from '../types.js';
|
|
3
3
|
import { SwapperName } from '../types.js';
|
|
4
|
-
export declare const FALLBACK_QUOTE_DEADLINE_MS = 60000;
|
|
5
4
|
export declare const getTradeAmount: (input: {
|
|
6
5
|
sellAmountIncludingProtocolFeesCryptoBaseUnit: string;
|
|
7
6
|
} | {
|
|
@@ -10,5 +9,5 @@ export declare const getTradeAmount: (input: {
|
|
|
10
9
|
export declare const normalizeEpochToMs: (value: number) => number;
|
|
11
10
|
export declare const isNativeEvmAsset: (assetId: AssetId) => boolean;
|
|
12
11
|
export declare const getTreasuryAddressFromChainId: (chainId: ChainId) => string;
|
|
13
|
-
export type DepositAddressStep = Pick<TradeStepCommon, '
|
|
12
|
+
export type DepositAddressStep = Pick<TradeStepCommon, 'swapperMetadata'>;
|
|
14
13
|
export declare const getDepositAddress: (step: DepositAddressStep, swapperName: SwapperName) => string | undefined;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CHAIN_NAMESPACE, fromAssetId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
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_MEGAETH, DAO_TREASURY_MONAD, DAO_TREASURY_OPTIMISM, DAO_TREASURY_PLASMA, DAO_TREASURY_POLYGON, DAO_TREASURY_ROBINHOOD, DAO_TREASURY_SOLANA, DAO_TREASURY_STARKNET, DAO_TREASURY_TON, isTreasuryChainId, } from '@shapeshiftoss/utils';
|
|
3
|
+
import { chainIdToFeeAssetId, 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_MEGAETH, DAO_TREASURY_MONAD, DAO_TREASURY_OPTIMISM, DAO_TREASURY_PLASMA, DAO_TREASURY_POLYGON, DAO_TREASURY_ROBINHOOD, DAO_TREASURY_SOLANA, DAO_TREASURY_STARKNET, DAO_TREASURY_TON, isTreasuryChainId, } from '@shapeshiftoss/utils';
|
|
4
4
|
import { SwapperName } from '../types.js';
|
|
5
|
-
// Deadline for providers without their own expiry - short enough to keep priced amounts honest
|
|
6
|
-
export const FALLBACK_QUOTE_DEADLINE_MS = 60_000;
|
|
7
5
|
export const getTradeAmount = (input) => 'buyAmountCryptoBaseUnit' in input
|
|
8
6
|
? { direction: 'exactOut', cryptoBaseUnit: input.buyAmountCryptoBaseUnit }
|
|
9
7
|
: { direction: 'exactIn', cryptoBaseUnit: input.sellAmountIncludingProtocolFeesCryptoBaseUnit };
|
|
@@ -18,33 +16,8 @@ export const normalizeEpochToMs = (value) => {
|
|
|
18
16
|
return Math.floor(value / 1e6);
|
|
19
17
|
};
|
|
20
18
|
export const isNativeEvmAsset = (assetId) => {
|
|
21
|
-
const { chainId } = fromAssetId(assetId);
|
|
22
|
-
|
|
23
|
-
case KnownChainIds.EthereumMainnet:
|
|
24
|
-
return assetId === ethAssetId;
|
|
25
|
-
case KnownChainIds.AvalancheMainnet:
|
|
26
|
-
return assetId === avalancheAssetId;
|
|
27
|
-
case KnownChainIds.OptimismMainnet:
|
|
28
|
-
return assetId === optimismAssetId;
|
|
29
|
-
case KnownChainIds.BnbSmartChainMainnet:
|
|
30
|
-
return assetId === bscAssetId;
|
|
31
|
-
case KnownChainIds.PolygonMainnet:
|
|
32
|
-
return assetId === polygonAssetId;
|
|
33
|
-
case KnownChainIds.GnosisMainnet:
|
|
34
|
-
return assetId === gnosisAssetId;
|
|
35
|
-
case KnownChainIds.ArbitrumMainnet:
|
|
36
|
-
return assetId === arbitrumAssetId;
|
|
37
|
-
case KnownChainIds.BaseMainnet:
|
|
38
|
-
return assetId === baseAssetId;
|
|
39
|
-
case KnownChainIds.MonadMainnet:
|
|
40
|
-
return assetId === monadAssetId;
|
|
41
|
-
case KnownChainIds.PlasmaMainnet:
|
|
42
|
-
return assetId === plasmaAssetId;
|
|
43
|
-
case KnownChainIds.KatanaMainnet:
|
|
44
|
-
return assetId === katanaAssetId;
|
|
45
|
-
default:
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
19
|
+
const { chainId, chainNamespace } = fromAssetId(assetId);
|
|
20
|
+
return chainNamespace === CHAIN_NAMESPACE.Evm && assetId === chainIdToFeeAssetId(chainId);
|
|
48
21
|
};
|
|
49
22
|
const DAO_TREASURY_BY_CHAIN_ID = {
|
|
50
23
|
[KnownChainIds.EthereumMainnet]: DAO_TREASURY_ETHEREUM_MAINNET,
|
|
@@ -77,8 +50,11 @@ export const getTreasuryAddressFromChainId = (chainId) => {
|
|
|
77
50
|
};
|
|
78
51
|
export const getDepositAddress = (step, swapperName) => {
|
|
79
52
|
switch (swapperName) {
|
|
80
|
-
case SwapperName.Chainflip:
|
|
81
|
-
|
|
53
|
+
case SwapperName.Chainflip: {
|
|
54
|
+
if (step.swapperMetadata?.name !== 'chainflip')
|
|
55
|
+
return;
|
|
56
|
+
return step.swapperMetadata.depositAddress || undefined;
|
|
57
|
+
}
|
|
82
58
|
case SwapperName.NearIntents: {
|
|
83
59
|
if (step.swapperMetadata?.name !== 'nearIntents')
|
|
84
60
|
return;
|
|
@@ -55,7 +55,9 @@ describe('normalizeEpochToMs', () => {
|
|
|
55
55
|
const makeStep = (step) => step;
|
|
56
56
|
describe('getDepositAddress', () => {
|
|
57
57
|
it('reads the chainflip deposit address', () => {
|
|
58
|
-
const step = makeStep({
|
|
58
|
+
const step = makeStep({
|
|
59
|
+
swapperMetadata: { name: 'chainflip', swapId: 1, depositAddress: 'bc1qdeposit' },
|
|
60
|
+
});
|
|
59
61
|
expect(getDepositAddress(step, SwapperName.Chainflip)).toBe('bc1qdeposit');
|
|
60
62
|
});
|
|
61
63
|
it('returns undefined when chainflip has no deposit address', () => {
|
|
@@ -78,7 +80,9 @@ describe('getDepositAddress', () => {
|
|
|
78
80
|
expect(getDepositAddress(step, SwapperName.NearIntents)).toBeUndefined();
|
|
79
81
|
});
|
|
80
82
|
it('returns undefined for swappers that do not use deposit addresses', () => {
|
|
81
|
-
const step = makeStep({
|
|
83
|
+
const step = makeStep({
|
|
84
|
+
swapperMetadata: { name: 'chainflip', swapId: 1, depositAddress: 'bc1qdeposit' },
|
|
85
|
+
});
|
|
82
86
|
expect(getDepositAddress(step, SwapperName.Relay)).toBeUndefined();
|
|
83
87
|
});
|
|
84
88
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swapper",
|
|
3
|
-
"version": "20.
|
|
3
|
+
"version": "20.4.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/
|
|
54
|
-
"@shapeshiftoss/
|
|
55
|
-
"@shapeshiftoss/hdwallet-core": "^1.62.41",
|
|
56
|
-
"@shapeshiftoss/contracts": "^1.1.0",
|
|
53
|
+
"@shapeshiftoss/chain-adapters": "^11.7.0",
|
|
54
|
+
"@shapeshiftoss/caip": "^8.17.2",
|
|
57
55
|
"@shapeshiftoss/types": "^9.1.0",
|
|
58
|
-
"@shapeshiftoss/
|
|
59
|
-
"@shapeshiftoss/
|
|
56
|
+
"@shapeshiftoss/contracts": "^1.1.0",
|
|
57
|
+
"@shapeshiftoss/utils": "^1.4.0",
|
|
58
|
+
"@shapeshiftoss/hdwallet-core": "^1.62.41",
|
|
59
|
+
"@shapeshiftoss/unchained-client": "^10.16.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/lodash": "^4.14.178",
|