@shapeshiftoss/swapper 17.7.3 → 17.8.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 +35 -26
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.js +12 -4
- package/dist/cjs/swappers/BebopSwapper/getBebopSolanaTradeRate/getBebopSolanaTradeRate.js +9 -5
- package/dist/cjs/swappers/BebopSwapper/getBebopTradeQuote/getBebopTradeQuote.js +1 -9
- package/dist/cjs/swappers/BebopSwapper/getBebopTradeRate/getBebopTradeRate.js +9 -13
- package/dist/cjs/swappers/BebopSwapper/types.d.ts +64 -78
- package/dist/cjs/swappers/BebopSwapper/utils/fetchFromBebop.d.ts +0 -16
- package/dist/cjs/swappers/BebopSwapper/utils/fetchFromBebop.js +49 -82
- package/dist/cjs/swappers/BobGatewaySwapper/BobGatewaySwapper.d.ts +2 -0
- package/dist/cjs/swappers/BobGatewaySwapper/BobGatewaySwapper.js +8 -0
- package/dist/cjs/swappers/BobGatewaySwapper/endpoints.d.ts +2 -0
- package/dist/cjs/swappers/BobGatewaySwapper/endpoints.js +143 -0
- package/dist/cjs/swappers/BobGatewaySwapper/index.d.ts +3 -0
- package/dist/cjs/swappers/BobGatewaySwapper/index.js +22 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.d.ts +3 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +90 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeRate.d.ts +3 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeRate.js +73 -0
- package/dist/cjs/swappers/BobGatewaySwapper/types.d.ts +20 -0
- package/dist/cjs/swappers/BobGatewaySwapper/types.js +2 -0
- package/dist/cjs/swappers/BobGatewaySwapper/utils/constants.d.ts +13 -0
- package/dist/cjs/swappers/BobGatewaySwapper/utils/constants.js +31 -0
- package/dist/cjs/swappers/BobGatewaySwapper/utils/helpers.d.ts +49 -0
- package/dist/cjs/swappers/BobGatewaySwapper/utils/helpers.js +314 -0
- package/dist/cjs/swappers/ChainflipSwapper/ChainflipSwapper.js +1 -0
- package/dist/cjs/swappers/ChainflipSwapper/constants.d.ts +1 -1
- package/dist/cjs/swappers/ChainflipSwapper/constants.js +3 -0
- package/dist/cjs/swappers/ChainflipSwapper/endpoints.js +20 -0
- package/dist/cjs/swappers/ChainflipSwapper/types.d.ts +2 -1
- package/dist/cjs/swappers/ChainflipSwapper/types.js +1 -0
- package/dist/cjs/swappers/ChainflipSwapper/utils/getQuoteOrRate.js +23 -3
- package/dist/cjs/swappers/ChainflipSwapper/utils/helpers.d.ts +2 -2
- package/dist/cjs/swappers/ChainflipSwapper/utils/helpers.js +2 -1
- package/dist/cjs/swappers/CowSwapper/utils/helpers/helpers.test.js +3 -3
- package/dist/cjs/swappers/RelaySwapper/constant.js +1 -1
- package/dist/cjs/swappers/SunioSwapper/endpoints.js +19 -36
- package/dist/cjs/swappers/SunioSwapper/utils/buildSwapContractCall.d.ts +6 -0
- package/dist/cjs/swappers/SunioSwapper/utils/buildSwapContractCall.js +33 -0
- package/dist/cjs/swappers/SunioSwapper/utils/buildSwapRouteParameters.js +6 -6
- package/dist/cjs/swappers/SunioSwapper/utils/constants.d.ts +2 -0
- package/dist/cjs/swappers/SunioSwapper/utils/constants.js +7 -1
- package/dist/cjs/swappers/SunioSwapper/utils/estimateSunioNetworkFee.d.ts +12 -0
- package/dist/cjs/swappers/SunioSwapper/utils/estimateSunioNetworkFee.js +78 -0
- package/dist/cjs/swappers/SunioSwapper/utils/getQuoteOrRate.js +16 -74
- package/dist/cjs/swappers/SunioSwapper/utils/getSunioTransactionFees.d.ts +2 -0
- package/dist/cjs/swappers/SunioSwapper/utils/getSunioTransactionFees.js +36 -0
- package/dist/cjs/swappers/utils/helpers/helpers.js +1 -0
- package/dist/cjs/thorchain-utils/getL1RateOrQuote.js +5 -2
- package/dist/cjs/thorchain-utils/getQuote.js +27 -29
- package/dist/cjs/thorchain-utils/tron/getTronTransactionFees.js +8 -5
- package/dist/cjs/thorchain-utils/types.d.ts +1 -1
- package/dist/cjs/types.d.ts +10 -3
- package/dist/cjs/types.js +5 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/constants.js +9 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/swappers/ArbitrumBridgeSwapper/getTradeQuote/getTradeQuote.test.js +12 -4
- package/dist/esm/swappers/BebopSwapper/getBebopSolanaTradeRate/getBebopSolanaTradeRate.js +10 -6
- package/dist/esm/swappers/BebopSwapper/getBebopTradeQuote/getBebopTradeQuote.js +1 -9
- package/dist/esm/swappers/BebopSwapper/getBebopTradeRate/getBebopTradeRate.js +10 -14
- package/dist/esm/swappers/BebopSwapper/types.d.ts +64 -78
- package/dist/esm/swappers/BebopSwapper/utils/fetchFromBebop.d.ts +0 -16
- package/dist/esm/swappers/BebopSwapper/utils/fetchFromBebop.js +45 -76
- package/dist/esm/swappers/BobGatewaySwapper/BobGatewaySwapper.d.ts +2 -0
- package/dist/esm/swappers/BobGatewaySwapper/BobGatewaySwapper.js +5 -0
- package/dist/esm/swappers/BobGatewaySwapper/endpoints.d.ts +2 -0
- package/dist/esm/swappers/BobGatewaySwapper/endpoints.js +140 -0
- package/dist/esm/swappers/BobGatewaySwapper/index.d.ts +3 -0
- package/dist/esm/swappers/BobGatewaySwapper/index.js +3 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.d.ts +3 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +86 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeRate.d.ts +3 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeRate.js +69 -0
- package/dist/esm/swappers/BobGatewaySwapper/types.d.ts +20 -0
- package/dist/esm/swappers/BobGatewaySwapper/utils/constants.d.ts +13 -0
- package/dist/esm/swappers/BobGatewaySwapper/utils/constants.js +27 -0
- package/dist/esm/swappers/BobGatewaySwapper/utils/helpers.d.ts +49 -0
- package/dist/esm/swappers/BobGatewaySwapper/utils/helpers.js +299 -0
- package/dist/esm/swappers/ChainflipSwapper/ChainflipSwapper.js +2 -1
- package/dist/esm/swappers/ChainflipSwapper/constants.d.ts +1 -1
- package/dist/esm/swappers/ChainflipSwapper/constants.js +4 -1
- package/dist/esm/swappers/ChainflipSwapper/endpoints.js +20 -0
- package/dist/esm/swappers/ChainflipSwapper/types.d.ts +2 -1
- package/dist/esm/swappers/ChainflipSwapper/types.js +1 -0
- package/dist/esm/swappers/ChainflipSwapper/utils/getQuoteOrRate.js +24 -4
- package/dist/esm/swappers/ChainflipSwapper/utils/helpers.d.ts +2 -2
- package/dist/esm/swappers/ChainflipSwapper/utils/helpers.js +2 -1
- package/dist/esm/swappers/CowSwapper/utils/helpers/helpers.test.js +3 -3
- package/dist/esm/swappers/RelaySwapper/constant.js +1 -1
- package/dist/esm/swappers/SunioSwapper/endpoints.js +19 -36
- package/dist/esm/swappers/SunioSwapper/utils/buildSwapContractCall.d.ts +6 -0
- package/dist/esm/swappers/SunioSwapper/utils/buildSwapContractCall.js +29 -0
- package/dist/esm/swappers/SunioSwapper/utils/buildSwapRouteParameters.js +6 -6
- package/dist/esm/swappers/SunioSwapper/utils/constants.d.ts +2 -0
- package/dist/esm/swappers/SunioSwapper/utils/constants.js +6 -0
- package/dist/esm/swappers/SunioSwapper/utils/estimateSunioNetworkFee.d.ts +12 -0
- package/dist/esm/swappers/SunioSwapper/utils/estimateSunioNetworkFee.js +74 -0
- package/dist/esm/swappers/SunioSwapper/utils/getQuoteOrRate.js +16 -74
- package/dist/esm/swappers/SunioSwapper/utils/getSunioTransactionFees.d.ts +2 -0
- package/dist/esm/swappers/SunioSwapper/utils/getSunioTransactionFees.js +32 -0
- package/dist/esm/swappers/utils/helpers/helpers.js +2 -1
- package/dist/esm/thorchain-utils/getL1RateOrQuote.js +5 -2
- package/dist/esm/thorchain-utils/getQuote.js +27 -29
- package/dist/esm/thorchain-utils/tron/getTronTransactionFees.js +8 -5
- package/dist/esm/thorchain-utils/types.d.ts +1 -1
- package/dist/esm/types.d.ts +10 -3
- package/dist/esm/types.js +5 -0
- package/package.json +8 -7
- package/dist/cjs/swappers/SunioSwapper/utils/buildSwapTransaction.d.ts +0 -11
- package/dist/cjs/swappers/SunioSwapper/utils/buildSwapTransaction.js +0 -57
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.d.ts +0 -12
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.js +0 -47
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.js +0 -100
- package/dist/esm/swappers/SunioSwapper/utils/buildSwapTransaction.d.ts +0 -11
- package/dist/esm/swappers/SunioSwapper/utils/buildSwapTransaction.js +0 -53
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.d.ts +0 -12
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.js +0 -41
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.d.ts +0 -1
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.js +0 -98
- /package/dist/{cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.d.ts → esm/swappers/BobGatewaySwapper/types.js} +0 -0
package/dist/esm/constants.js
CHANGED
|
@@ -7,6 +7,8 @@ import { avnuSwapper } from './swappers/AvnuSwapper/AvnuSwapper.js';
|
|
|
7
7
|
import { avnuApi } from './swappers/AvnuSwapper/endpoints.js';
|
|
8
8
|
import { bebopSwapper } from './swappers/BebopSwapper/BebopSwapper.js';
|
|
9
9
|
import { bebopApi } from './swappers/BebopSwapper/endpoints.js';
|
|
10
|
+
import { bobGatewaySwapper } from './swappers/BobGatewaySwapper/BobGatewaySwapper.js';
|
|
11
|
+
import { bobGatewayApi } from './swappers/BobGatewaySwapper/endpoints.js';
|
|
10
12
|
import { butterSwap } from './swappers/ButterSwap/ButterSwap.js';
|
|
11
13
|
import { butterSwapApi } from './swappers/ButterSwap/endpoints.js';
|
|
12
14
|
import { cetusSwapper } from './swappers/CetusSwapper/CetusSwapper.js';
|
|
@@ -111,6 +113,10 @@ export const swappers = {
|
|
|
111
113
|
...debridgeSwapper,
|
|
112
114
|
...debridgeApi,
|
|
113
115
|
},
|
|
116
|
+
[SwapperName.BobGateway]: {
|
|
117
|
+
...bobGatewaySwapper,
|
|
118
|
+
...bobGatewayApi,
|
|
119
|
+
},
|
|
114
120
|
[SwapperName.Test]: undefined,
|
|
115
121
|
};
|
|
116
122
|
const DEFAULT_SLIPPAGE_DECIMAL_PERCENTAGE = '0.002';
|
|
@@ -129,6 +135,7 @@ const DEFAULT_AVNU_SLIPPAGE_DECIMAL_PERCENTAGE = '0.02';
|
|
|
129
135
|
const DEFAULT_STONFI_SLIPPAGE_DECIMAL_PERCENTAGE = '0.01';
|
|
130
136
|
// deBridge API off-chain simulation overestimates output on some chains (e.g. SEI ~2.4%), so auto slippage (1%) is insufficient
|
|
131
137
|
const DEFAULT_DEBRIDGE_SLIPPAGE_DECIMAL_PERCENTAGE = '0.03';
|
|
138
|
+
const DEFAULT_BOB_GATEWAY_SLIPPAGE_DECIMAL_PERCENTAGE = '0.03';
|
|
132
139
|
export const getDefaultSlippageDecimalPercentageForSwapper = (swapperName) => {
|
|
133
140
|
if (swapperName === undefined)
|
|
134
141
|
return DEFAULT_SLIPPAGE_DECIMAL_PERCENTAGE;
|
|
@@ -167,6 +174,8 @@ export const getDefaultSlippageDecimalPercentageForSwapper = (swapperName) => {
|
|
|
167
174
|
return DEFAULT_AVNU_SLIPPAGE_DECIMAL_PERCENTAGE;
|
|
168
175
|
case SwapperName.Stonfi:
|
|
169
176
|
return DEFAULT_STONFI_SLIPPAGE_DECIMAL_PERCENTAGE;
|
|
177
|
+
case SwapperName.BobGateway:
|
|
178
|
+
return DEFAULT_BOB_GATEWAY_SLIPPAGE_DECIMAL_PERCENTAGE;
|
|
170
179
|
default:
|
|
171
180
|
return assertUnreachable(swapperName);
|
|
172
181
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './cowswap-utils/index.js';
|
|
|
3
3
|
export * from './safe-utils/index.js';
|
|
4
4
|
export * from './swapper.js';
|
|
5
5
|
export * from './swappers/ArbitrumBridgeSwapper/index.js';
|
|
6
|
+
export * from './swappers/BobGatewaySwapper/index.js';
|
|
6
7
|
export * from './swappers/AvnuSwapper/index.js';
|
|
7
8
|
export * from './swappers/BebopSwapper/index.js';
|
|
8
9
|
export * from './swappers/CetusSwapper/index.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export * from './cowswap-utils/index.js';
|
|
|
3
3
|
export * from './safe-utils/index.js';
|
|
4
4
|
export * from './swapper.js';
|
|
5
5
|
export * from './swappers/ArbitrumBridgeSwapper/index.js';
|
|
6
|
+
export * from './swappers/BobGatewaySwapper/index.js';
|
|
6
7
|
export * from './swappers/AvnuSwapper/index.js';
|
|
7
8
|
export * from './swappers/BebopSwapper/index.js';
|
|
8
9
|
export * from './swappers/CetusSwapper/index.js';
|
|
@@ -51,7 +51,9 @@ describe('getTradeQuote', () => {
|
|
|
51
51
|
},
|
|
52
52
|
}),
|
|
53
53
|
};
|
|
54
|
-
vi.mocked(EthBridger).
|
|
54
|
+
vi.mocked(EthBridger).mockImplementation(function () {
|
|
55
|
+
return ethBridgerMock;
|
|
56
|
+
});
|
|
55
57
|
const maybeQuote = await getTradeQuote(commonInput, {
|
|
56
58
|
assertGetEvmChainAdapter,
|
|
57
59
|
getEthersV5Provider: vi.fn(),
|
|
@@ -74,7 +76,9 @@ describe('getTradeQuote', () => {
|
|
|
74
76
|
},
|
|
75
77
|
}),
|
|
76
78
|
};
|
|
77
|
-
vi.mocked(EthBridger).
|
|
79
|
+
vi.mocked(EthBridger).mockImplementation(function () {
|
|
80
|
+
return ethBridgerMock;
|
|
81
|
+
});
|
|
78
82
|
const withdrawInput = {
|
|
79
83
|
...commonInput,
|
|
80
84
|
sellAsset: ETH_ARBITRUM,
|
|
@@ -109,7 +113,9 @@ describe('getTradeQuote', () => {
|
|
|
109
113
|
.fn()
|
|
110
114
|
.mockResolvedValue('0x0c66f315542fdec1d312c415b14eef614b0910ef'),
|
|
111
115
|
};
|
|
112
|
-
vi.mocked(Erc20Bridger).
|
|
116
|
+
vi.mocked(Erc20Bridger).mockImplementation(function () {
|
|
117
|
+
return Erc20BridgerMock;
|
|
118
|
+
});
|
|
113
119
|
const erc20DepositInput = {
|
|
114
120
|
...commonInput,
|
|
115
121
|
sellAsset: FOX_MAINNET,
|
|
@@ -144,7 +150,9 @@ describe('getTradeQuote', () => {
|
|
|
144
150
|
.fn()
|
|
145
151
|
.mockResolvedValue('0x0c66f315542fdec1d312c415b14eef614b0910ef'),
|
|
146
152
|
};
|
|
147
|
-
vi.mocked(Erc20Bridger).
|
|
153
|
+
vi.mocked(Erc20Bridger).mockImplementation(function () {
|
|
154
|
+
return Erc20BridgerMock;
|
|
155
|
+
});
|
|
148
156
|
const erc20WithdrawInput = {
|
|
149
157
|
...commonInput,
|
|
150
158
|
sellAsset: FOX_ARBITRUM,
|
|
@@ -3,7 +3,8 @@ import { v4 as uuid } from 'uuid';
|
|
|
3
3
|
import { getDefaultSlippageDecimalPercentageForSwapper } from '../../../constants.js';
|
|
4
4
|
import { SwapperName, TradeQuoteError } from '../../../types.js';
|
|
5
5
|
import { makeSwapErrorRight } from '../../../utils.js';
|
|
6
|
-
import {
|
|
6
|
+
import { BEBOP_SOLANA_DUMMY_ADDRESS } from '../types.js';
|
|
7
|
+
import { fetchBebopSolanaQuote } from '../utils/fetchFromBebop.js';
|
|
7
8
|
import { assertValidTrade, calculateRate, isBebopSolanaTxSafe } from '../utils/helpers/helpers.js';
|
|
8
9
|
export async function getBebopSolanaTradeRate(input, _assetsById, apiKey) {
|
|
9
10
|
const { sellAsset, buyAsset, accountNumber, receiveAddress, affiliateBps, sellAmountIncludingProtocolFeesCryptoBaseUnit, } = input;
|
|
@@ -12,17 +13,20 @@ export async function getBebopSolanaTradeRate(input, _assetsById, apiKey) {
|
|
|
12
13
|
return Err(assertion.unwrapErr());
|
|
13
14
|
const slippageTolerancePercentageDecimal = input.slippageTolerancePercentageDecimal ??
|
|
14
15
|
getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Bebop);
|
|
15
|
-
const
|
|
16
|
+
const address = receiveAddress ?? BEBOP_SOLANA_DUMMY_ADDRESS;
|
|
17
|
+
const maybeBebopQuoteResponse = await fetchBebopSolanaQuote({
|
|
16
18
|
buyAsset,
|
|
17
19
|
sellAsset,
|
|
18
20
|
sellAmountIncludingProtocolFeesCryptoBaseUnit,
|
|
19
|
-
|
|
21
|
+
takerAddress: address,
|
|
22
|
+
receiverAddress: address,
|
|
23
|
+
slippageTolerancePercentageDecimal,
|
|
20
24
|
affiliateBps,
|
|
21
25
|
apiKey,
|
|
22
26
|
});
|
|
23
|
-
if (
|
|
24
|
-
return Err(
|
|
25
|
-
const bebopPriceResponse =
|
|
27
|
+
if (maybeBebopQuoteResponse.isErr())
|
|
28
|
+
return Err(maybeBebopQuoteResponse.unwrapErr());
|
|
29
|
+
const bebopPriceResponse = maybeBebopQuoteResponse.unwrap();
|
|
26
30
|
const sellTokenAddress = Object.keys(bebopPriceResponse.sellTokens)[0];
|
|
27
31
|
const buyTokenAddress = Object.keys(bebopPriceResponse.buyTokens)[0];
|
|
28
32
|
if (!sellTokenAddress || !buyTokenAddress) {
|
|
@@ -37,15 +37,7 @@ export async function getBebopTradeQuote(input, assertGetEvmChainAdapter, _asset
|
|
|
37
37
|
});
|
|
38
38
|
if (maybeBebopQuoteResponse.isErr())
|
|
39
39
|
return Err(maybeBebopQuoteResponse.unwrapErr());
|
|
40
|
-
const
|
|
41
|
-
const bestRoute = bebopQuoteResponse.routes.find(r => r.type === bebopQuoteResponse.bestPrice);
|
|
42
|
-
if (!bestRoute || !bestRoute.quote) {
|
|
43
|
-
return Err(makeSwapErrorRight({
|
|
44
|
-
message: 'No best route found',
|
|
45
|
-
code: TradeQuoteError.NoRouteFound,
|
|
46
|
-
}));
|
|
47
|
-
}
|
|
48
|
-
const quote = bestRoute.quote;
|
|
40
|
+
const quote = maybeBebopQuoteResponse.unwrap();
|
|
49
41
|
const sellTokenAddress = Object.keys(quote.sellTokens)[0];
|
|
50
42
|
const buyTokenAddress = Object.keys(quote.buyTokens)[0];
|
|
51
43
|
if (!isAddress(sellTokenAddress) || !isAddress(buyTokenAddress)) {
|
|
@@ -8,7 +8,8 @@ import { SwapperName, TradeQuoteError } from '../../../types.js';
|
|
|
8
8
|
import { makeSwapErrorRight } from '../../../utils.js';
|
|
9
9
|
import { buildAffiliateFee } from '../../utils/affiliateFee.js';
|
|
10
10
|
import { isNativeEvmAsset } from '../../utils/helpers/helpers.js';
|
|
11
|
-
import {
|
|
11
|
+
import { BEBOP_DUMMY_ADDRESS } from '../types.js';
|
|
12
|
+
import { fetchBebopQuote } from '../utils/fetchFromBebop.js';
|
|
12
13
|
import { assertValidTrade, calculateRate } from '../utils/helpers/helpers.js';
|
|
13
14
|
export async function getBebopTradeRate(input, assertGetEvmChainAdapter, _assetsById, apiKey) {
|
|
14
15
|
const { sellAsset, buyAsset, accountNumber, receiveAddress, affiliateBps, sellAmountIncludingProtocolFeesCryptoBaseUnit, } = input;
|
|
@@ -17,25 +18,20 @@ export async function getBebopTradeRate(input, assertGetEvmChainAdapter, _assets
|
|
|
17
18
|
return Err(assertion.unwrapErr());
|
|
18
19
|
const slippageTolerancePercentageDecimal = input.slippageTolerancePercentageDecimal ??
|
|
19
20
|
getDefaultSlippageDecimalPercentageForSwapper(SwapperName.Bebop);
|
|
20
|
-
const
|
|
21
|
+
const address = receiveAddress ?? BEBOP_DUMMY_ADDRESS;
|
|
22
|
+
const maybeBebopQuoteResponse = await fetchBebopQuote({
|
|
21
23
|
buyAsset,
|
|
22
24
|
sellAsset,
|
|
23
25
|
sellAmountIncludingProtocolFeesCryptoBaseUnit,
|
|
24
|
-
|
|
26
|
+
takerAddress: address,
|
|
27
|
+
receiverAddress: address,
|
|
28
|
+
slippageTolerancePercentageDecimal,
|
|
25
29
|
affiliateBps,
|
|
26
30
|
apiKey,
|
|
27
31
|
});
|
|
28
|
-
if (
|
|
29
|
-
return Err(
|
|
30
|
-
const
|
|
31
|
-
const bestRoute = bebopPriceResponse.routes.find(r => r.type === bebopPriceResponse.bestPrice);
|
|
32
|
-
if (!bestRoute || !bestRoute.quote) {
|
|
33
|
-
return Err(makeSwapErrorRight({
|
|
34
|
-
message: 'No best route found',
|
|
35
|
-
code: TradeQuoteError.NoRouteFound,
|
|
36
|
-
}));
|
|
37
|
-
}
|
|
38
|
-
const quote = bestRoute.quote;
|
|
32
|
+
if (maybeBebopQuoteResponse.isErr())
|
|
33
|
+
return Err(maybeBebopQuoteResponse.unwrapErr());
|
|
34
|
+
const quote = maybeBebopQuoteResponse.unwrap();
|
|
39
35
|
const sellTokenAddress = Object.keys(quote.sellTokens)[0];
|
|
40
36
|
const buyTokenAddress = Object.keys(quote.buyTokens)[0];
|
|
41
37
|
if (!isAddress(sellTokenAddress) || !isAddress(buyTokenAddress)) {
|
|
@@ -3,87 +3,73 @@ import type { Address, Hex } from 'viem';
|
|
|
3
3
|
export declare const bebopSupportedEvmChainIds: readonly [KnownChainIds.EthereumMainnet, KnownChainIds.PolygonMainnet, KnownChainIds.ArbitrumMainnet, KnownChainIds.BaseMainnet, KnownChainIds.AvalancheMainnet, KnownChainIds.OptimismMainnet, KnownChainIds.BnbSmartChainMainnet];
|
|
4
4
|
export declare const bebopSupportedChainIds: readonly [KnownChainIds.EthereumMainnet, KnownChainIds.PolygonMainnet, KnownChainIds.ArbitrumMainnet, KnownChainIds.BaseMainnet, KnownChainIds.AvalancheMainnet, KnownChainIds.OptimismMainnet, KnownChainIds.BnbSmartChainMainnet, KnownChainIds.SolanaMainnet];
|
|
5
5
|
export type BebopSupportedChainId = (typeof bebopSupportedChainIds)[number];
|
|
6
|
-
export type
|
|
6
|
+
export type BebopQuoteResponse = {
|
|
7
|
+
requestId: string;
|
|
7
8
|
type: string;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
status: string;
|
|
10
|
+
quoteId: string;
|
|
11
|
+
chainId: number;
|
|
12
|
+
approvalType: 'Standard' | 'Permit' | 'Permit2';
|
|
13
|
+
nativeToken: string;
|
|
14
|
+
taker: Address;
|
|
15
|
+
receiver: Address;
|
|
16
|
+
expiry: number;
|
|
17
|
+
slippage: number;
|
|
18
|
+
gasFee: {
|
|
19
|
+
native: string;
|
|
20
|
+
usd: number;
|
|
21
|
+
};
|
|
22
|
+
buyTokens: Record<Address, {
|
|
23
|
+
amount: string;
|
|
24
|
+
decimals: number;
|
|
25
|
+
priceUsd: number;
|
|
26
|
+
symbol: string;
|
|
27
|
+
minimumAmount: string;
|
|
28
|
+
price: number;
|
|
29
|
+
priceBeforeFee: number;
|
|
30
|
+
amountBeforeFee: string;
|
|
31
|
+
deltaFromExpected: number;
|
|
32
|
+
}>;
|
|
33
|
+
sellTokens: Record<Address, {
|
|
34
|
+
amount: string;
|
|
35
|
+
decimals: number;
|
|
36
|
+
priceUsd: number;
|
|
37
|
+
symbol: string;
|
|
38
|
+
price: number;
|
|
39
|
+
priceBeforeFee: number;
|
|
40
|
+
}>;
|
|
41
|
+
settlementAddress: Address;
|
|
42
|
+
approvalTarget: Address;
|
|
43
|
+
requiredSignatures: string[];
|
|
44
|
+
priceImpact: number;
|
|
45
|
+
warnings: string[];
|
|
46
|
+
toSign: {
|
|
47
|
+
partner_id: number;
|
|
18
48
|
expiry: number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
symbol: string;
|
|
29
|
-
minimumAmount: string;
|
|
30
|
-
price: number;
|
|
31
|
-
priceBeforeFee: number;
|
|
32
|
-
amountBeforeFee: string;
|
|
33
|
-
deltaFromExpected: number;
|
|
34
|
-
}>;
|
|
35
|
-
sellTokens: Record<Address, {
|
|
36
|
-
amount: string;
|
|
37
|
-
decimals: number;
|
|
38
|
-
priceUsd: number;
|
|
39
|
-
symbol: string;
|
|
40
|
-
price: number;
|
|
41
|
-
priceBeforeFee: number;
|
|
42
|
-
}>;
|
|
43
|
-
settlementAddress: Address;
|
|
44
|
-
approvalTarget: Address;
|
|
45
|
-
requiredSignatures: string[];
|
|
46
|
-
priceImpact: number;
|
|
47
|
-
warnings: string[];
|
|
48
|
-
toSign: {
|
|
49
|
-
partner_id: number;
|
|
50
|
-
expiry: number;
|
|
51
|
-
taker_address: Address;
|
|
52
|
-
maker_address: Address;
|
|
53
|
-
maker_nonce: string;
|
|
54
|
-
taker_token: Address;
|
|
55
|
-
maker_token: Address;
|
|
56
|
-
taker_amount: string;
|
|
57
|
-
maker_amount: string;
|
|
58
|
-
receiver: Address;
|
|
59
|
-
packed_commands: string;
|
|
60
|
-
};
|
|
61
|
-
onchainOrderType?: string;
|
|
62
|
-
solver?: string;
|
|
63
|
-
makers?: string[];
|
|
64
|
-
partialFillOffset?: number;
|
|
65
|
-
tx: {
|
|
66
|
-
to: Address;
|
|
67
|
-
from: Address;
|
|
68
|
-
data: Hex;
|
|
69
|
-
value: Hex;
|
|
70
|
-
gas?: number;
|
|
71
|
-
gasPrice?: number;
|
|
72
|
-
};
|
|
73
|
-
partnerFee?: Record<Address, string>;
|
|
74
|
-
protocolFee?: Record<Address, string>;
|
|
49
|
+
taker_address: Address;
|
|
50
|
+
maker_address: Address;
|
|
51
|
+
maker_nonce: string;
|
|
52
|
+
taker_token: Address;
|
|
53
|
+
maker_token: Address;
|
|
54
|
+
taker_amount: string;
|
|
55
|
+
maker_amount: string;
|
|
56
|
+
receiver: Address;
|
|
57
|
+
packed_commands: string;
|
|
75
58
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
59
|
+
onchainOrderType?: string;
|
|
60
|
+
solver?: string;
|
|
61
|
+
makers?: string[];
|
|
62
|
+
partialFillOffset?: number;
|
|
63
|
+
tx: {
|
|
64
|
+
to: Address;
|
|
65
|
+
from: Address;
|
|
66
|
+
data: Hex;
|
|
67
|
+
value: Hex;
|
|
68
|
+
gas?: number;
|
|
69
|
+
gasPrice?: number;
|
|
70
|
+
};
|
|
71
|
+
partnerFee?: Record<Address, string>;
|
|
72
|
+
protocolFee?: Record<Address, string>;
|
|
87
73
|
};
|
|
88
74
|
export declare const chainIdToBebopChain: Record<BebopSupportedChainId, string>;
|
|
89
75
|
export declare const BEBOP_NATIVE_MARKER = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
@@ -13,14 +13,6 @@ export declare const fetchBebopQuote: ({ buyAsset, sellAsset, sellAmountIncludin
|
|
|
13
13
|
affiliateBps?: string | undefined;
|
|
14
14
|
apiKey: string;
|
|
15
15
|
}) => Promise<Result<BebopQuoteResponse, SwapErrorRight>>;
|
|
16
|
-
export declare const fetchBebopPrice: ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, receiveAddress, affiliateBps, apiKey, }: {
|
|
17
|
-
buyAsset: Asset;
|
|
18
|
-
sellAsset: Asset;
|
|
19
|
-
sellAmountIncludingProtocolFeesCryptoBaseUnit: string;
|
|
20
|
-
receiveAddress: string | undefined;
|
|
21
|
-
affiliateBps?: string | undefined;
|
|
22
|
-
apiKey: string;
|
|
23
|
-
}) => Promise<Result<BebopQuoteResponse, SwapErrorRight>>;
|
|
24
16
|
export declare const fetchBebopSolanaQuote: ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, takerAddress, receiverAddress, slippageTolerancePercentageDecimal, affiliateBps, apiKey, }: {
|
|
25
17
|
buyAsset: Asset;
|
|
26
18
|
sellAsset: Asset;
|
|
@@ -31,11 +23,3 @@ export declare const fetchBebopSolanaQuote: ({ buyAsset, sellAsset, sellAmountIn
|
|
|
31
23
|
affiliateBps?: string | undefined;
|
|
32
24
|
apiKey: string;
|
|
33
25
|
}) => Promise<Result<BebopSolanaQuoteResponse, SwapErrorRight>>;
|
|
34
|
-
export declare const fetchBebopSolanaPrice: ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, receiveAddress, affiliateBps, apiKey, }: {
|
|
35
|
-
buyAsset: Asset;
|
|
36
|
-
sellAsset: Asset;
|
|
37
|
-
sellAmountIncludingProtocolFeesCryptoBaseUnit: string;
|
|
38
|
-
receiveAddress: string | undefined;
|
|
39
|
-
affiliateBps?: string | undefined;
|
|
40
|
-
apiKey: string;
|
|
41
|
-
}) => Promise<Result<BebopSolanaQuoteResponse, SwapErrorRight>>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { solAssetId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { bn, bnOrZero } from '@shapeshiftoss/utils';
|
|
2
3
|
import { Err, Ok } from '@sniptt/monads';
|
|
3
4
|
import { getAddress } from 'viem';
|
|
4
5
|
import { TradeQuoteError } from '../../../types.js';
|
|
5
6
|
import { makeSwapErrorRight } from '../../../utils.js';
|
|
6
|
-
import {
|
|
7
|
+
import { getTreasuryAddressFromChainId } from '../../utils/helpers/helpers.js';
|
|
8
|
+
import { chainIdToBebopChain } from '../types.js';
|
|
7
9
|
import { bebopServiceFactory } from './bebopService.js';
|
|
8
10
|
import { assetIdToBebopSolanaToken, assetIdToBebopToken } from './helpers/helpers.js';
|
|
9
11
|
export const fetchBebopQuote = async ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, takerAddress, receiverAddress, slippageTolerancePercentageDecimal, affiliateBps, apiKey, }) => {
|
|
@@ -14,14 +16,8 @@ export const fetchBebopQuote = async ({ buyAsset, sellAsset, sellAmountIncluding
|
|
|
14
16
|
const checksummedReceiverAddress = getAddress(receiverAddress);
|
|
15
17
|
const chainName = chainIdToBebopChain[sellAsset.chainId];
|
|
16
18
|
const sellAmountFormatted = bn(sellAmountIncludingProtocolFeesCryptoBaseUnit).toFixed(0);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// See: https://api.bebop.xyz/pmm/ethereum/docs#/v3/quote_v3_quote_get
|
|
20
|
-
const slippagePercentage = bn(slippageTolerancePercentageDecimal ?? 0.003)
|
|
21
|
-
.times(100)
|
|
22
|
-
.toNumber();
|
|
23
|
-
const url = `https://api.bebop.xyz/router/${chainName}/v1/quote`;
|
|
24
|
-
const params = new URLSearchParams({
|
|
19
|
+
const slippagePercentage = bn(slippageTolerancePercentageDecimal).times(100).toNumber();
|
|
20
|
+
const baseParams = {
|
|
25
21
|
sell_tokens: sellToken,
|
|
26
22
|
buy_tokens: buyToken,
|
|
27
23
|
sell_amounts: sellAmountFormatted,
|
|
@@ -32,38 +28,46 @@ export const fetchBebopQuote = async ({ buyAsset, sellAsset, sellAmountIncluding
|
|
|
32
28
|
skip_validation: 'true',
|
|
33
29
|
gasless: 'false',
|
|
34
30
|
source: 'shapeshift',
|
|
35
|
-
}
|
|
31
|
+
};
|
|
32
|
+
const jamParams = new URLSearchParams(baseParams);
|
|
33
|
+
const pmmParams = new URLSearchParams(baseParams);
|
|
36
34
|
if (affiliateBps && affiliateBps !== '0') {
|
|
37
|
-
|
|
35
|
+
// JAM collects the fee on-chain and requires a recipient
|
|
36
|
+
jamParams.set('fee', affiliateBps);
|
|
37
|
+
jamParams.set('fee_recipient', getAddress(getTreasuryAddressFromChainId(buyAsset.chainId)));
|
|
38
|
+
// PMM attributes the fee off-chain via source
|
|
39
|
+
pmmParams.set('fee', affiliateBps);
|
|
38
40
|
}
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
41
|
+
const service = bebopServiceFactory({ apiKey });
|
|
42
|
+
const [maybeJam, maybePmm] = await Promise.all([
|
|
43
|
+
service.get(`https://api.bebop.xyz/jam/${chainName}/v2/quote`, {
|
|
44
|
+
params: jamParams,
|
|
45
|
+
}),
|
|
46
|
+
service.get(`https://api.bebop.xyz/pmm/${chainName}/v3/quote`, {
|
|
47
|
+
params: pmmParams,
|
|
48
|
+
}),
|
|
49
|
+
]);
|
|
50
|
+
const maybeResponses = [maybeJam, maybePmm];
|
|
51
|
+
if (maybeResponses.every(maybeResponse => maybeResponse.isErr())) {
|
|
42
52
|
return Err(makeSwapErrorRight({
|
|
43
53
|
message: 'Failed to fetch quote from Bebop',
|
|
44
|
-
cause:
|
|
54
|
+
cause: maybeResponses[0].unwrapErr().cause,
|
|
45
55
|
code: TradeQuoteError.QueryFailed,
|
|
46
56
|
}));
|
|
47
57
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// Validate response has routes - only fail if there are NO valid routes
|
|
54
|
-
if (!response.data.routes || response.data.routes.length === 0) {
|
|
58
|
+
const quotes = maybeResponses
|
|
59
|
+
.filter(maybeResponse => maybeResponse.isOk())
|
|
60
|
+
.map(maybeResponse => maybeResponse.unwrap().data)
|
|
61
|
+
.filter(quote => Boolean(quote.tx?.data));
|
|
62
|
+
if (!quotes.length) {
|
|
55
63
|
return Err(makeSwapErrorRight({
|
|
56
|
-
message: 'No
|
|
64
|
+
message: 'No route available',
|
|
57
65
|
code: TradeQuoteError.NoRouteFound,
|
|
58
66
|
}));
|
|
59
67
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
code: TradeQuoteError.InvalidResponse,
|
|
64
|
-
}));
|
|
65
|
-
}
|
|
66
|
-
return Ok(response.data);
|
|
68
|
+
const getBuyAmount = (quote) => bnOrZero(Object.values(quote.buyTokens)[0]?.amount);
|
|
69
|
+
const bestQuote = quotes.reduce((best, quote) => getBuyAmount(quote).gt(getBuyAmount(best)) ? quote : best);
|
|
70
|
+
return Ok(bestQuote);
|
|
67
71
|
}
|
|
68
72
|
catch (error) {
|
|
69
73
|
return Err(makeSwapErrorRight({
|
|
@@ -73,28 +77,20 @@ export const fetchBebopQuote = async ({ buyAsset, sellAsset, sellAmountIncluding
|
|
|
73
77
|
}));
|
|
74
78
|
}
|
|
75
79
|
};
|
|
76
|
-
export const fetchBebopPrice = ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, receiveAddress, affiliateBps, apiKey, }) => {
|
|
77
|
-
const address = receiveAddress || BEBOP_DUMMY_ADDRESS;
|
|
78
|
-
return fetchBebopQuote({
|
|
79
|
-
buyAsset,
|
|
80
|
-
sellAsset,
|
|
81
|
-
sellAmountIncludingProtocolFeesCryptoBaseUnit,
|
|
82
|
-
takerAddress: address,
|
|
83
|
-
receiverAddress: address,
|
|
84
|
-
slippageTolerancePercentageDecimal: '0.01',
|
|
85
|
-
affiliateBps,
|
|
86
|
-
apiKey,
|
|
87
|
-
});
|
|
88
|
-
};
|
|
89
80
|
export const fetchBebopSolanaQuote = async ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, takerAddress, receiverAddress, slippageTolerancePercentageDecimal, affiliateBps, apiKey, }) => {
|
|
90
81
|
try {
|
|
82
|
+
// Bebop's Solana routes don't wrap native SOL on the input side, so selling native SOL
|
|
83
|
+
// always fails on-chain. Reject up front instead of returning an unexecutable quote.
|
|
84
|
+
if (sellAsset.assetId === solAssetId) {
|
|
85
|
+
return Err(makeSwapErrorRight({
|
|
86
|
+
message: 'Bebop Solana cannot sell native SOL',
|
|
87
|
+
code: TradeQuoteError.NoRouteFound,
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
91
90
|
const sellToken = assetIdToBebopSolanaToken(sellAsset.assetId);
|
|
92
91
|
const buyToken = assetIdToBebopSolanaToken(buyAsset.assetId);
|
|
93
92
|
const sellAmountFormatted = bn(sellAmountIncludingProtocolFeesCryptoBaseUnit).toFixed(0);
|
|
94
|
-
const slippagePercentage = bn(slippageTolerancePercentageDecimal
|
|
95
|
-
.times(100)
|
|
96
|
-
.toNumber();
|
|
97
|
-
const url = 'https://api.bebop.xyz/pmm/solana/v3/quote';
|
|
93
|
+
const slippagePercentage = bn(slippageTolerancePercentageDecimal).times(100).toNumber();
|
|
98
94
|
const params = new URLSearchParams({
|
|
99
95
|
sell_tokens: sellToken,
|
|
100
96
|
buy_tokens: buyToken,
|
|
@@ -110,8 +106,7 @@ export const fetchBebopSolanaQuote = async ({ buyAsset, sellAsset, sellAmountInc
|
|
|
110
106
|
if (affiliateBps && affiliateBps !== '0') {
|
|
111
107
|
params.set('fee', affiliateBps);
|
|
112
108
|
}
|
|
113
|
-
const
|
|
114
|
-
const maybeResponse = await bebopService.get(`${url}?${params}`);
|
|
109
|
+
const maybeResponse = await bebopServiceFactory({ apiKey }).get('https://api.bebop.xyz/pmm/solana/v3/quote', { params });
|
|
115
110
|
if (maybeResponse.isErr()) {
|
|
116
111
|
const err = maybeResponse.unwrapErr();
|
|
117
112
|
return Err(makeSwapErrorRight({
|
|
@@ -133,19 +128,6 @@ export const fetchBebopSolanaQuote = async ({ buyAsset, sellAsset, sellAmountInc
|
|
|
133
128
|
code: TradeQuoteError.InvalidResponse,
|
|
134
129
|
}));
|
|
135
130
|
}
|
|
136
|
-
// Reject routes containing ANY AMM/CLMM makers - these produce malformed txs
|
|
137
|
-
// (wrong signature count in wire format) and require pre-existing ATAs that
|
|
138
|
-
// Bebop's gasless co-signed flow can't create. This includes mixed routes
|
|
139
|
-
// like ["raydium clmm-rfqm", "🦊"] where Bebop serializes the tx with fewer
|
|
140
|
-
// signature slots than the message header requires.
|
|
141
|
-
// When rejected, other swappers like Jupiter will handle these pairs instead.
|
|
142
|
-
const hasAmmRoute = response.data.makers.some(maker => maker.toLowerCase().includes('clmm') || maker.toLowerCase().includes('amm'));
|
|
143
|
-
if (hasAmmRoute) {
|
|
144
|
-
return Err(makeSwapErrorRight({
|
|
145
|
-
message: `Bebop Solana quote contains AMM routing (${response.data.makers.join(', ')}), which produces malformed txs`,
|
|
146
|
-
code: TradeQuoteError.NoRouteFound,
|
|
147
|
-
}));
|
|
148
|
-
}
|
|
149
131
|
return Ok(response.data);
|
|
150
132
|
}
|
|
151
133
|
catch (error) {
|
|
@@ -156,16 +138,3 @@ export const fetchBebopSolanaQuote = async ({ buyAsset, sellAsset, sellAmountInc
|
|
|
156
138
|
}));
|
|
157
139
|
}
|
|
158
140
|
};
|
|
159
|
-
export const fetchBebopSolanaPrice = ({ buyAsset, sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit, receiveAddress, affiliateBps, apiKey, }) => {
|
|
160
|
-
const address = receiveAddress || BEBOP_SOLANA_DUMMY_ADDRESS;
|
|
161
|
-
return fetchBebopSolanaQuote({
|
|
162
|
-
buyAsset,
|
|
163
|
-
sellAsset,
|
|
164
|
-
sellAmountIncludingProtocolFeesCryptoBaseUnit,
|
|
165
|
-
takerAddress: address,
|
|
166
|
-
receiverAddress: address,
|
|
167
|
-
slippageTolerancePercentageDecimal: '0.01',
|
|
168
|
-
affiliateBps,
|
|
169
|
-
apiKey,
|
|
170
|
-
});
|
|
171
|
-
};
|