@shapeshiftoss/swapper 19.0.0 → 20.1.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/exactOutputFiltering.test.d.ts +1 -0
- package/dist/cjs/exactOutputFiltering.test.js +70 -0
- package/dist/cjs/swapper.d.ts +3 -3
- package/dist/cjs/swapper.js +29 -6
- package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossStepData.d.ts +1 -0
- package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossStepData.js +2 -2
- package/dist/cjs/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +1 -0
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopStepData.d.ts +1 -0
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopStepData.js +2 -2
- package/dist/cjs/swappers/BebopSwapper/utils/getBebopTradeContext.js +1 -0
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +5 -1
- package/dist/cjs/swappers/BobGatewaySwapper/swapperApi/getTradeRate.js +11 -2
- package/dist/cjs/swappers/BobGatewaySwapper/utils/getBobGatewayTradeContext.d.ts +2 -1
- package/dist/cjs/swappers/BobGatewaySwapper/utils/getBobGatewayTradeContext.js +2 -1
- package/dist/cjs/swappers/BobGatewaySwapper/utils/helpers.d.ts +2 -1
- package/dist/cjs/swappers/BobGatewaySwapper/utils/helpers.js +2 -1
- package/dist/cjs/swappers/ChainflipSwapper/ChainflipSwapper.js +1 -0
- package/dist/cjs/swappers/ChainflipSwapper/checkTradeStatus.test.d.ts +1 -0
- package/dist/cjs/swappers/ChainflipSwapper/checkTradeStatus.test.js +48 -0
- package/dist/cjs/swappers/ChainflipSwapper/endpoints.js +5 -2
- package/dist/cjs/swappers/ChainflipSwapper/types.d.ts +3 -0
- package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeStepData.d.ts +1 -0
- package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeStepData.js +2 -2
- package/dist/cjs/swappers/DebridgeSwapper/utils/getDebridgeTradeContext.js +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/NearIntentsSwapper.js +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/checkTradeStatus.test.d.ts +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/checkTradeStatus.test.js +52 -0
- package/dist/cjs/swappers/NearIntentsSwapper/constants.d.ts +1 -1
- package/dist/cjs/swappers/NearIntentsSwapper/constants.js +4 -3
- package/dist/cjs/swappers/NearIntentsSwapper/endpoints.js +4 -1
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +2 -1
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +14 -9
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +2 -1
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +14 -9
- package/dist/cjs/swappers/NearIntentsSwapper/types.d.ts +3 -1
- package/dist/cjs/swappers/NearIntentsSwapper/utils/exactOutput.test.d.ts +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/exactOutput.test.js +61 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.d.ts +2 -2
- package/dist/cjs/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.js +4 -2
- package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers.d.ts +5 -5
- package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers.js +30 -26
- package/dist/cjs/swappers/NearIntentsSwapper/utils/quoteDeadline.test.d.ts +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/utils/quoteDeadline.test.js +28 -0
- package/dist/cjs/swappers/PortalsSwapper/endpoints.js +51 -47
- package/dist/cjs/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +1 -1
- package/dist/cjs/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.js +1 -1
- package/dist/cjs/swappers/PortalsSwapper/utils/fetchAxelarscanStatus.d.ts +0 -1
- package/dist/cjs/swappers/PortalsSwapper/utils/fetchAxelarscanStatus.js +3 -6
- package/dist/cjs/swappers/PortalsSwapper/utils/fetchPortalsTradeOrder.js +6 -3
- package/dist/cjs/swappers/PortalsSwapper/utils/fetchSquidStatus.d.ts +0 -1
- package/dist/cjs/swappers/PortalsSwapper/utils/fetchSquidStatus.js +1 -8
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.d.ts +1 -0
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.js +16 -8
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.test.d.ts +1 -0
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsStepData.test.js +70 -0
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.d.ts +3 -2
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.js +34 -16
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.test.d.ts +1 -0
- package/dist/cjs/swappers/PortalsSwapper/utils/getPortalsTradeContext.test.js +93 -0
- package/dist/cjs/swappers/RelaySwapper/endpoints.js +9 -18
- package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.d.ts +2 -1
- package/dist/cjs/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +5 -2
- package/dist/cjs/swappers/RelaySwapper/getTradeRate/getTradeRate.d.ts +2 -1
- package/dist/cjs/swappers/RelaySwapper/getTradeRate/getTradeRate.js +5 -2
- package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +2 -2
- package/dist/cjs/swappers/RelaySwapper/utils/getRelayTradeContext.js +22 -10
- package/dist/cjs/swappers/RelaySwapper/utils/helpers.d.ts +2 -2
- package/dist/cjs/swappers/RelaySwapper/utils/relayStatus.d.ts +8 -0
- package/dist/cjs/swappers/RelaySwapper/utils/relayStatus.js +39 -0
- package/dist/cjs/swappers/RelaySwapper/utils/types.d.ts +18 -1
- package/dist/cjs/swappers/SunioSwapper/utils/getSunioStepData.d.ts +1 -0
- package/dist/cjs/swappers/SunioSwapper/utils/getSunioStepData.js +2 -2
- package/dist/cjs/swappers/SunioSwapper/utils/getSunioTradeContext.js +6 -1
- package/dist/cjs/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +1 -0
- package/dist/cjs/types.d.ts +21 -2
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/utils/cowswap/index.d.ts +4 -1
- package/dist/cjs/utils/cowswap/index.js +5 -1
- package/dist/cjs/utils/helpers.d.ts +9 -0
- package/dist/cjs/utils/helpers.js +23 -1
- package/dist/cjs/utils/helpers.test.js +41 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/exactOutputFiltering.test.d.ts +1 -0
- package/dist/esm/exactOutputFiltering.test.js +68 -0
- package/dist/esm/swapper.d.ts +3 -3
- package/dist/esm/swapper.js +29 -6
- package/dist/esm/swappers/AcrossSwapper/utils/getAcrossStepData.d.ts +1 -0
- package/dist/esm/swappers/AcrossSwapper/utils/getAcrossStepData.js +2 -2
- package/dist/esm/swappers/AcrossSwapper/utils/getAcrossTradeContext.js +1 -0
- package/dist/esm/swappers/BebopSwapper/utils/getBebopStepData.d.ts +1 -0
- package/dist/esm/swappers/BebopSwapper/utils/getBebopStepData.js +2 -2
- package/dist/esm/swappers/BebopSwapper/utils/getBebopTradeContext.js +1 -0
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeQuote.js +5 -1
- package/dist/esm/swappers/BobGatewaySwapper/swapperApi/getTradeRate.js +11 -2
- package/dist/esm/swappers/BobGatewaySwapper/utils/getBobGatewayTradeContext.d.ts +2 -1
- package/dist/esm/swappers/BobGatewaySwapper/utils/getBobGatewayTradeContext.js +2 -1
- package/dist/esm/swappers/BobGatewaySwapper/utils/helpers.d.ts +2 -1
- package/dist/esm/swappers/BobGatewaySwapper/utils/helpers.js +2 -1
- package/dist/esm/swappers/ChainflipSwapper/ChainflipSwapper.js +1 -0
- package/dist/esm/swappers/ChainflipSwapper/checkTradeStatus.test.d.ts +1 -0
- package/dist/esm/swappers/ChainflipSwapper/checkTradeStatus.test.js +46 -0
- package/dist/esm/swappers/ChainflipSwapper/endpoints.js +5 -2
- package/dist/esm/swappers/ChainflipSwapper/types.d.ts +3 -0
- package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeStepData.d.ts +1 -0
- package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeStepData.js +2 -2
- package/dist/esm/swappers/DebridgeSwapper/utils/getDebridgeTradeContext.js +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/NearIntentsSwapper.js +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/checkTradeStatus.test.d.ts +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/checkTradeStatus.test.js +50 -0
- package/dist/esm/swappers/NearIntentsSwapper/constants.d.ts +1 -1
- package/dist/esm/swappers/NearIntentsSwapper/constants.js +3 -2
- package/dist/esm/swappers/NearIntentsSwapper/endpoints.js +6 -3
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.d.ts +2 -1
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +7 -3
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.d.ts +2 -1
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeRate.js +7 -3
- package/dist/esm/swappers/NearIntentsSwapper/types.d.ts +3 -1
- package/dist/esm/swappers/NearIntentsSwapper/utils/exactOutput.test.d.ts +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/exactOutput.test.js +59 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.d.ts +2 -2
- package/dist/esm/swappers/NearIntentsSwapper/utils/getNearIntentsTradeContext.js +4 -2
- package/dist/esm/swappers/NearIntentsSwapper/utils/helpers.d.ts +5 -5
- package/dist/esm/swappers/NearIntentsSwapper/utils/helpers.js +32 -28
- package/dist/esm/swappers/NearIntentsSwapper/utils/quoteDeadline.test.d.ts +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/utils/quoteDeadline.test.js +26 -0
- package/dist/esm/swappers/PortalsSwapper/endpoints.js +53 -49
- package/dist/esm/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.js +1 -1
- package/dist/esm/swappers/PortalsSwapper/getPortalsTradeRate/getPortalsTradeRate.js +1 -1
- package/dist/esm/swappers/PortalsSwapper/utils/fetchAxelarscanStatus.d.ts +0 -1
- package/dist/esm/swappers/PortalsSwapper/utils/fetchAxelarscanStatus.js +2 -4
- package/dist/esm/swappers/PortalsSwapper/utils/fetchPortalsTradeOrder.js +6 -3
- package/dist/esm/swappers/PortalsSwapper/utils/fetchSquidStatus.d.ts +0 -1
- package/dist/esm/swappers/PortalsSwapper/utils/fetchSquidStatus.js +0 -6
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.d.ts +1 -0
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.js +13 -5
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.test.d.ts +1 -0
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsStepData.test.js +68 -0
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.d.ts +3 -2
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.js +35 -17
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.test.d.ts +1 -0
- package/dist/esm/swappers/PortalsSwapper/utils/getPortalsTradeContext.test.js +91 -0
- package/dist/esm/swappers/RelaySwapper/endpoints.js +11 -20
- package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.d.ts +2 -1
- package/dist/esm/swappers/RelaySwapper/getTradeQuote/getTradeQuote.js +3 -1
- package/dist/esm/swappers/RelaySwapper/getTradeRate/getTradeRate.d.ts +2 -1
- package/dist/esm/swappers/RelaySwapper/getTradeRate/getTradeRate.js +3 -1
- package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.d.ts +2 -2
- package/dist/esm/swappers/RelaySwapper/utils/getRelayTradeContext.js +23 -11
- package/dist/esm/swappers/RelaySwapper/utils/helpers.d.ts +2 -2
- package/dist/esm/swappers/RelaySwapper/utils/relayStatus.d.ts +8 -0
- package/dist/esm/swappers/RelaySwapper/utils/relayStatus.js +32 -0
- package/dist/esm/swappers/RelaySwapper/utils/types.d.ts +18 -1
- package/dist/esm/swappers/SunioSwapper/utils/getSunioStepData.d.ts +1 -0
- package/dist/esm/swappers/SunioSwapper/utils/getSunioStepData.js +2 -2
- package/dist/esm/swappers/SunioSwapper/utils/getSunioTradeContext.js +6 -1
- package/dist/esm/swappers/ThorchainSwapper/generated/generatedThorLongtailTokens.json +1 -0
- package/dist/esm/types.d.ts +21 -2
- package/dist/esm/types.js +2 -0
- package/dist/esm/utils/cowswap/index.d.ts +4 -1
- package/dist/esm/utils/cowswap/index.js +3 -0
- package/dist/esm/utils/helpers.d.ts +9 -0
- package/dist/esm/utils/helpers.js +20 -0
- package/dist/esm/utils/helpers.test.js +42 -1
- package/package.json +6 -6
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Err, Ok } from '@sniptt/monads';
|
|
2
|
+
import { getTradeAmount } from '../../../utils/helpers.js';
|
|
2
3
|
import { QuoteRequest } from '../types.js';
|
|
3
4
|
import { getNearIntentsStepData } from '../utils/getNearIntentsStepData.js';
|
|
4
5
|
import { getNearIntentsTradeContext } from '../utils/getNearIntentsTradeContext.js';
|
|
5
6
|
import { buildNearIntentsQuoteRequest, fetchNearIntentsQuote, getNearIntentsQuoteDeadline, resolveNearIntentsAssets, } from '../utils/helpers.js';
|
|
6
7
|
import { initializeOneClickService } from '../utils/oneClickService.js';
|
|
7
|
-
|
|
8
|
-
const { accountNumber, sellAsset, buyAsset, affiliateBps,
|
|
8
|
+
const getRate = async (input, deps) => {
|
|
9
|
+
const { accountNumber, sellAsset, buyAsset, affiliateBps, receiveAddress, sendAddress } = input;
|
|
9
10
|
initializeOneClickService(deps.config.VITE_NEAR_INTENTS_API_KEY);
|
|
11
|
+
const amount = getTradeAmount(input);
|
|
10
12
|
const maybeAssets = await resolveNearIntentsAssets({ sellAsset, buyAsset });
|
|
11
13
|
if (maybeAssets.isErr())
|
|
12
14
|
return Err(maybeAssets.unwrapErr());
|
|
@@ -14,7 +16,7 @@ export const getTradeRate = async (input, deps) => {
|
|
|
14
16
|
const quoteRequest = buildNearIntentsQuoteRequest({
|
|
15
17
|
originAsset,
|
|
16
18
|
destinationAsset,
|
|
17
|
-
|
|
19
|
+
amount,
|
|
18
20
|
slippageTolerancePercentageDecimal: input.slippageTolerancePercentageDecimal,
|
|
19
21
|
affiliateBps,
|
|
20
22
|
refundTo: sendAddress ?? 'check-price',
|
|
@@ -58,3 +60,5 @@ export const getTradeRate = async (input, deps) => {
|
|
|
58
60
|
};
|
|
59
61
|
return Ok([tradeRate]);
|
|
60
62
|
};
|
|
63
|
+
export const getTradeRate = (input, deps) => getRate(input, deps);
|
|
64
|
+
export const getExactOutputTradeRate = (input, deps) => getRate(input, deps);
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
2
|
-
import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput, GetNearTradeQuoteInput, GetNearTradeRateInput, GetSolanaTradeQuoteInput, GetSolanaTradeRateInput, GetStarknetTradeQuoteInput, GetStarknetTradeRateInput, GetSuiTradeQuoteInput, GetSuiTradeRateInput, GetTonTradeQuoteInput, GetTonTradeRateInput, GetTronTradeQuoteInput, GetTronTradeRateInput, GetUtxoTradeQuoteInput, GetUtxoTradeRateInput } from '../../types.js';
|
|
2
|
+
import type { GetEvmTradeQuoteInput, GetEvmTradeRateInput, GetNearTradeQuoteInput, GetNearTradeRateInput, GetSolanaTradeQuoteInput, GetSolanaTradeRateInput, GetStarknetTradeQuoteInput, GetStarknetTradeRateInput, GetSuiTradeQuoteInput, GetSuiTradeRateInput, GetTonTradeQuoteInput, GetTonTradeRateInput, GetTronTradeQuoteInput, GetTronTradeRateInput, GetUtxoTradeQuoteInput, GetUtxoTradeRateInput, WithExactBuyAmount } from '../../types.js';
|
|
3
3
|
export type NearIntentsTradeQuoteInput = GetEvmTradeQuoteInput | GetUtxoTradeQuoteInput | GetSolanaTradeQuoteInput | GetTronTradeQuoteInput | GetSuiTradeQuoteInput | GetStarknetTradeQuoteInput | GetNearTradeQuoteInput | GetTonTradeQuoteInput;
|
|
4
4
|
export type NearIntentsTradeRateInput = GetEvmTradeRateInput | GetUtxoTradeRateInput | GetSolanaTradeRateInput | GetTronTradeRateInput | GetSuiTradeRateInput | GetStarknetTradeRateInput | GetNearTradeRateInput | GetTonTradeRateInput;
|
|
5
|
+
export type NearIntentsExactOutputTradeQuoteInput = WithExactBuyAmount<NearIntentsTradeQuoteInput>;
|
|
6
|
+
export type NearIntentsExactOutputTradeRateInput = WithExactBuyAmount<NearIntentsTradeRateInput>;
|
|
5
7
|
export type NearIntentsMetadata = {
|
|
6
8
|
name: 'nearIntents';
|
|
7
9
|
depositAddress: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { QuoteRequest } from '../types.js';
|
|
3
|
+
import { buildNearIntentsQuoteRequest } from './helpers.js';
|
|
4
|
+
const BASE_ARGS = {
|
|
5
|
+
originAsset: 'nep141:base-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.omft.near',
|
|
6
|
+
destinationAsset: 'nep141:btc.omft.near',
|
|
7
|
+
amount: { direction: 'exactIn', cryptoBaseUnit: '65000000' },
|
|
8
|
+
slippageTolerancePercentageDecimal: '0.01',
|
|
9
|
+
affiliateBps: '10',
|
|
10
|
+
refundTo: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
|
|
11
|
+
recipient: 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4',
|
|
12
|
+
refundType: QuoteRequest.refundType.ORIGIN_CHAIN,
|
|
13
|
+
recipientType: QuoteRequest.recipientType.DESTINATION_CHAIN,
|
|
14
|
+
deadline: '2026-08-10T23:59:00.000Z',
|
|
15
|
+
};
|
|
16
|
+
const EXACT_OUTPUT_AMOUNT = {
|
|
17
|
+
direction: 'exactOut',
|
|
18
|
+
cryptoBaseUnit: '100000',
|
|
19
|
+
};
|
|
20
|
+
describe('buildNearIntentsQuoteRequest', () => {
|
|
21
|
+
describe('exact input', () => {
|
|
22
|
+
it('requests EXACT_INPUT with the sell amount', () => {
|
|
23
|
+
const request = buildNearIntentsQuoteRequest(BASE_ARGS);
|
|
24
|
+
expect(request.swapType).toEqual(QuoteRequest.swapType.EXACT_INPUT);
|
|
25
|
+
expect(request.amount).toEqual('65000000');
|
|
26
|
+
});
|
|
27
|
+
it('passes the requested slippage through untouched', () => {
|
|
28
|
+
const request = buildNearIntentsQuoteRequest({
|
|
29
|
+
...BASE_ARGS,
|
|
30
|
+
slippageTolerancePercentageDecimal: '0',
|
|
31
|
+
});
|
|
32
|
+
expect(request.slippageTolerance).toEqual(0);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('exact output', () => {
|
|
36
|
+
it('requests EXACT_OUTPUT with the buy amount', () => {
|
|
37
|
+
const request = buildNearIntentsQuoteRequest({ ...BASE_ARGS, amount: EXACT_OUTPUT_AMOUNT });
|
|
38
|
+
expect(request.swapType).toEqual(QuoteRequest.swapType.EXACT_OUTPUT);
|
|
39
|
+
expect(request.amount).toEqual('100000');
|
|
40
|
+
});
|
|
41
|
+
// A tighter band is the user's call - the failure mode is a refund, not a loss
|
|
42
|
+
it('passes a requested zero slippage through untouched, as exact input does', () => {
|
|
43
|
+
const request = buildNearIntentsQuoteRequest({
|
|
44
|
+
...BASE_ARGS,
|
|
45
|
+
amount: EXACT_OUTPUT_AMOUNT,
|
|
46
|
+
slippageTolerancePercentageDecimal: '0',
|
|
47
|
+
});
|
|
48
|
+
expect(request.slippageTolerance).toEqual(0);
|
|
49
|
+
});
|
|
50
|
+
it('honours a requested slippage', () => {
|
|
51
|
+
const request = buildNearIntentsQuoteRequest({
|
|
52
|
+
...BASE_ARGS,
|
|
53
|
+
amount: EXACT_OUTPUT_AMOUNT,
|
|
54
|
+
slippageTolerancePercentageDecimal: '0.05',
|
|
55
|
+
});
|
|
56
|
+
expect(request.slippageTolerance).toEqual(500);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Asset } from '@shapeshiftoss/types';
|
|
2
2
|
import type { Result } from '@sniptt/monads';
|
|
3
3
|
import type { QuoteFeeData, SwapErrorRight, SwapperDeps, TradeCommon, TradeStepCommon } from '../../../types.js';
|
|
4
|
-
import type { NearIntentsTradeQuoteInput, NearIntentsTradeRateInput, QuoteResponse } from '../types.js';
|
|
4
|
+
import type { NearIntentsExactOutputTradeQuoteInput, NearIntentsExactOutputTradeRateInput, NearIntentsTradeQuoteInput, NearIntentsTradeRateInput, QuoteResponse } from '../types.js';
|
|
5
5
|
type NearIntentsTradeContext = {
|
|
6
6
|
tradeCommon: TradeCommon;
|
|
7
7
|
stepCommon: Omit<TradeStepCommon, 'feeData'>;
|
|
@@ -14,7 +14,7 @@ type NearIntentsTradeContext = {
|
|
|
14
14
|
};
|
|
15
15
|
};
|
|
16
16
|
export declare const getNearIntentsTradeContext: ({ input, deps, quote, }: {
|
|
17
|
-
input: NearIntentsTradeQuoteInput | NearIntentsTradeRateInput;
|
|
17
|
+
input: NearIntentsTradeQuoteInput | NearIntentsTradeRateInput | NearIntentsExactOutputTradeQuoteInput | NearIntentsExactOutputTradeRateInput;
|
|
18
18
|
deps: SwapperDeps;
|
|
19
19
|
quote: QuoteResponse['quote'];
|
|
20
20
|
}) => Result<NearIntentsTradeContext, SwapErrorRight>;
|
|
@@ -7,7 +7,7 @@ import { SwapperName } from '../../../types.js';
|
|
|
7
7
|
import { getInputOutputRate, makeTradeStepBuildFailedErr } from '../../../utils/index.js';
|
|
8
8
|
import { buildAffiliateFee } from '../../../utils/affiliateFee.js';
|
|
9
9
|
export const getNearIntentsTradeContext = ({ input, deps, quote, }) => {
|
|
10
|
-
const { sellAsset, buyAsset, affiliateBps,
|
|
10
|
+
const { sellAsset, buyAsset, affiliateBps, slippageTolerancePercentageDecimal } = input;
|
|
11
11
|
if (!quote.depositAddress)
|
|
12
12
|
return Err(makeTradeStepBuildFailedErr('getNearIntentsTradeContext'));
|
|
13
13
|
const rate = getInputOutputRate({
|
|
@@ -16,11 +16,13 @@ export const getNearIntentsTradeContext = ({ input, deps, quote, }) => {
|
|
|
16
16
|
sellAsset,
|
|
17
17
|
buyAsset,
|
|
18
18
|
});
|
|
19
|
+
const isExactOutput = 'buyAmountCryptoBaseUnit' in input;
|
|
19
20
|
return Ok({
|
|
20
21
|
tradeCommon: {
|
|
21
22
|
id: uuid(),
|
|
22
23
|
rate,
|
|
23
24
|
swapperName: SwapperName.NearIntents,
|
|
25
|
+
isExactOutput,
|
|
24
26
|
affiliateBps,
|
|
25
27
|
slippageTolerancePercentageDecimal: slippageTolerancePercentageDecimal ??
|
|
26
28
|
getDefaultSlippageDecimalPercentageForSwapper(SwapperName.NearIntents),
|
|
@@ -51,7 +53,7 @@ export const getNearIntentsTradeContext = ({ input, deps, quote, }) => {
|
|
|
51
53
|
stepDataArgs: {
|
|
52
54
|
deps,
|
|
53
55
|
sellAsset,
|
|
54
|
-
sellAmountCryptoBaseUnit:
|
|
56
|
+
sellAmountCryptoBaseUnit: quote.amountIn,
|
|
55
57
|
depositAddress: quote.depositAddress,
|
|
56
58
|
},
|
|
57
59
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Asset } from '@shapeshiftoss/types';
|
|
2
2
|
import { TxStatus } from '@shapeshiftoss/unchained-client';
|
|
3
3
|
import type { Result } from '@sniptt/monads';
|
|
4
|
-
import type { SwapErrorRight } from '../../../types.js';
|
|
4
|
+
import type { SwapErrorRight, TradeAmount } from '../../../types.js';
|
|
5
5
|
import type { GetExecutionStatusResponse, QuoteResponse } from '../types.js';
|
|
6
6
|
import { QuoteRequest } from '../types.js';
|
|
7
7
|
export declare const getNearIntentsAsset: ({ nearNetwork, contractAddress, }: {
|
|
@@ -17,13 +17,13 @@ export declare const resolveNearIntentsAssets: ({ sellAsset, buyAsset, }: {
|
|
|
17
17
|
destinationAsset: string;
|
|
18
18
|
}, SwapErrorRight>>;
|
|
19
19
|
export declare const getNearIntentsQuoteDeadline: ({ sellAsset, buyAsset, }: {
|
|
20
|
-
sellAsset: Asset
|
|
21
|
-
buyAsset: Asset
|
|
20
|
+
sellAsset: Pick<Asset, 'chainId'>;
|
|
21
|
+
buyAsset: Pick<Asset, 'chainId'>;
|
|
22
22
|
}) => string;
|
|
23
|
-
export declare const buildNearIntentsQuoteRequest: ({ originAsset, destinationAsset,
|
|
23
|
+
export declare const buildNearIntentsQuoteRequest: ({ originAsset, destinationAsset, amount, slippageTolerancePercentageDecimal, affiliateBps, refundTo, recipient, refundType, recipientType, deadline, }: {
|
|
24
24
|
originAsset: string;
|
|
25
25
|
destinationAsset: string;
|
|
26
|
-
|
|
26
|
+
amount: TradeAmount;
|
|
27
27
|
slippageTolerancePercentageDecimal: string | undefined;
|
|
28
28
|
affiliateBps: string;
|
|
29
29
|
refundTo: string;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CHAIN_NAMESPACE, fromAssetId, fromChainId, solanaChainId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { TxStatus } from '@shapeshiftoss/unchained-client';
|
|
3
3
|
import { bnOrZero, DAO_TREASURY_NEAR, isToken } from '@shapeshiftoss/utils';
|
|
4
4
|
import { Err, Ok } from '@sniptt/monads';
|
|
5
5
|
import { zeroAddress } from 'viem';
|
|
6
6
|
import { TradeQuoteError } from '../../../types.js';
|
|
7
7
|
import { createTradeAmountTooSmallErr, makeSwapErrorRight } from '../../../utils/index.js';
|
|
8
|
-
import {
|
|
8
|
+
import { DEFAULT_QUOTE_DEADLINE_MS, DEFAULT_SLIPPAGE_BPS, UTXO_QUOTE_DEADLINE_MS, } from '../constants.js';
|
|
9
9
|
import { chainIdToNearIntentsChain, QuoteRequest } from '../types.js';
|
|
10
10
|
import { ApiError, OneClickService } from './oneClickService.js';
|
|
11
11
|
const getTokensWithRetry = async () => {
|
|
@@ -120,36 +120,40 @@ export const resolveNearIntentsAssets = async ({ sellAsset, buyAsset, }) => {
|
|
|
120
120
|
}));
|
|
121
121
|
}
|
|
122
122
|
};
|
|
123
|
-
|
|
123
|
+
const isUtxoChainId = (chainId) => fromChainId(chainId).chainNamespace === CHAIN_NAMESPACE.Utxo;
|
|
124
124
|
export const getNearIntentsQuoteDeadline = ({ sellAsset, buyAsset, }) => {
|
|
125
|
-
const deadlineMs = sellAsset.chainId
|
|
126
|
-
?
|
|
125
|
+
const deadlineMs = isUtxoChainId(sellAsset.chainId) || isUtxoChainId(buyAsset.chainId)
|
|
126
|
+
? UTXO_QUOTE_DEADLINE_MS
|
|
127
127
|
: DEFAULT_QUOTE_DEADLINE_MS;
|
|
128
128
|
return new Date(Date.now() + deadlineMs).toISOString();
|
|
129
129
|
};
|
|
130
|
-
export const buildNearIntentsQuoteRequest = ({ originAsset, destinationAsset,
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
130
|
+
export const buildNearIntentsQuoteRequest = ({ originAsset, destinationAsset, amount, slippageTolerancePercentageDecimal, affiliateBps, refundTo, recipient, refundType, recipientType, deadline, }) => {
|
|
131
|
+
return {
|
|
132
|
+
dry: false,
|
|
133
|
+
swapType: amount.direction === 'exactOut'
|
|
134
|
+
? QuoteRequest.swapType.EXACT_OUTPUT
|
|
135
|
+
: QuoteRequest.swapType.EXACT_INPUT,
|
|
136
|
+
slippageTolerance: slippageTolerancePercentageDecimal
|
|
137
|
+
? bnOrZero(slippageTolerancePercentageDecimal).times(10000).toNumber()
|
|
138
|
+
: DEFAULT_SLIPPAGE_BPS,
|
|
139
|
+
originAsset,
|
|
140
|
+
destinationAsset,
|
|
141
|
+
amount: amount.cryptoBaseUnit,
|
|
142
|
+
depositType: QuoteRequest.depositType.ORIGIN_CHAIN,
|
|
143
|
+
refundTo,
|
|
144
|
+
refundType,
|
|
145
|
+
recipient,
|
|
146
|
+
recipientType,
|
|
147
|
+
deadline,
|
|
148
|
+
referral: 'shapeshift',
|
|
149
|
+
appFees: [
|
|
150
|
+
{
|
|
151
|
+
recipient: DAO_TREASURY_NEAR,
|
|
152
|
+
fee: Number(affiliateBps),
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
};
|
|
153
157
|
// One retry loop for the SDK's flaky WebSocket transport; maps provider errors to swap errors
|
|
154
158
|
export const fetchNearIntentsQuote = async ({ quoteRequest, sellAsset, }) => {
|
|
155
159
|
const maxRetries = 3;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { btcChainId, dogeChainId, ethChainId, solanaChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { DEFAULT_QUOTE_DEADLINE_MS, UTXO_QUOTE_DEADLINE_MS } from '../constants.js';
|
|
4
|
+
import { getNearIntentsQuoteDeadline } from './helpers.js';
|
|
5
|
+
const asset = (chainId) => ({ chainId });
|
|
6
|
+
describe('getNearIntentsQuoteDeadline', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
vi.useFakeTimers();
|
|
9
|
+
vi.setSystemTime(new Date('2026-09-10T22:00:00.000Z'));
|
|
10
|
+
});
|
|
11
|
+
afterEach(() => {
|
|
12
|
+
vi.useRealTimers();
|
|
13
|
+
});
|
|
14
|
+
it('gives a utxo sell leg the long deadline', () => {
|
|
15
|
+
expect(Date.parse(getNearIntentsQuoteDeadline({ sellAsset: asset(btcChainId), buyAsset: asset(ethChainId) }))).toBe(Date.now() + UTXO_QUOTE_DEADLINE_MS);
|
|
16
|
+
});
|
|
17
|
+
it('gives a utxo buy leg the long deadline, on any utxo chain', () => {
|
|
18
|
+
expect(Date.parse(getNearIntentsQuoteDeadline({ sellAsset: asset(ethChainId), buyAsset: asset(dogeChainId) }))).toBe(Date.now() + UTXO_QUOTE_DEADLINE_MS);
|
|
19
|
+
});
|
|
20
|
+
it('gives everything else the default deadline', () => {
|
|
21
|
+
expect(Date.parse(getNearIntentsQuoteDeadline({
|
|
22
|
+
sellAsset: asset(ethChainId),
|
|
23
|
+
buyAsset: asset(solanaChainId),
|
|
24
|
+
}))).toBe(Date.now() + DEFAULT_QUOTE_DEADLINE_MS);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
import { TxStatus } from '@shapeshiftoss/unchained-client';
|
|
2
2
|
import { checkEvmSwapStatus } from '../../utils/index.js';
|
|
3
3
|
import { getEvmTransactionFees, getUnsignedEvmTransaction } from '../../utils/evm/index.js';
|
|
4
|
+
import { fetchRelayRequestByTxHash, getRelayRequestFailureMessage, relayStatusToTxStatus, } from '../RelaySwapper/utils/relayStatus.js';
|
|
4
5
|
import { getPortalsTradeQuote } from './getPortalsTradeQuote/getPortalsTradeQuote.js';
|
|
5
6
|
import { getPortalsTradeRate } from './getPortalsTradeRate/getPortalsTradeRate.js';
|
|
6
|
-
import { fetchAxelarscanBridgeStatus
|
|
7
|
-
import { fetchSquidBridgeStatus
|
|
7
|
+
import { fetchAxelarscanBridgeStatus } from './utils/fetchAxelarscanStatus.js';
|
|
8
|
+
import { fetchSquidBridgeStatus } from './utils/fetchSquidStatus.js';
|
|
9
|
+
const bridgeStatusToTxStatus = (status) => {
|
|
10
|
+
switch (status) {
|
|
11
|
+
case 'confirmed':
|
|
12
|
+
return TxStatus.Confirmed;
|
|
13
|
+
case 'failed':
|
|
14
|
+
return TxStatus.Failed;
|
|
15
|
+
case 'pending':
|
|
16
|
+
default:
|
|
17
|
+
return TxStatus.Pending;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
8
20
|
export const portalsApi = {
|
|
9
21
|
getTradeQuote: (input, deps) => getPortalsTradeQuote(input, deps),
|
|
10
22
|
getTradeRate: (input, deps) => getPortalsTradeRate(input, deps),
|
|
11
23
|
getEvmTransactionFees,
|
|
12
24
|
getUnsignedEvmTransaction,
|
|
13
25
|
checkTradeStatus: async (input) => {
|
|
14
|
-
const { txHash, chainId, swap, assertGetEvmChainAdapter, address, fetchIsSmartContractAddressQuery, } = input;
|
|
26
|
+
const { txHash, chainId, swap, config, assertGetEvmChainAdapter, address, fetchIsSmartContractAddressQuery, } = input;
|
|
15
27
|
const isCrossChain = Boolean(swap && swap.sellAsset.chainId !== swap.buyAsset?.chainId);
|
|
16
28
|
if (!isCrossChain) {
|
|
17
29
|
return checkEvmSwapStatus({
|
|
@@ -39,64 +51,56 @@ export const portalsApi = {
|
|
|
39
51
|
if (sourceTxStatus.status === TxStatus.Failed) {
|
|
40
52
|
return sourceTxStatus;
|
|
41
53
|
}
|
|
54
|
+
const relayResult = await fetchRelayRequestByTxHash(txHash, config);
|
|
55
|
+
if (relayResult.isOk()) {
|
|
56
|
+
const relayRequest = relayResult.unwrap();
|
|
57
|
+
if (relayRequest) {
|
|
58
|
+
const relayTxStatus = relayStatusToTxStatus(relayRequest.status);
|
|
59
|
+
const txStatus = relayTxStatus === TxStatus.Unknown ? TxStatus.Pending : relayTxStatus;
|
|
60
|
+
return {
|
|
61
|
+
status: txStatus,
|
|
62
|
+
buyTxHash: relayRequest.data?.outTxs?.[0]?.hash,
|
|
63
|
+
message: txStatus === TxStatus.Failed
|
|
64
|
+
? getRelayRequestFailureMessage(relayRequest)
|
|
65
|
+
: txStatus === TxStatus.Confirmed
|
|
66
|
+
? undefined
|
|
67
|
+
: 'Bridge in progress',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
42
71
|
const axelarscanResult = await fetchAxelarscanBridgeStatus(txHash);
|
|
43
|
-
if (
|
|
72
|
+
if (axelarscanResult.isOk()) {
|
|
73
|
+
const bridgeStatus = axelarscanResult.unwrap();
|
|
74
|
+
if (bridgeStatus) {
|
|
75
|
+
const txStatus = bridgeStatusToTxStatus(bridgeStatus.status);
|
|
76
|
+
return {
|
|
77
|
+
status: txStatus,
|
|
78
|
+
buyTxHash: bridgeStatus.destinationTxHash,
|
|
79
|
+
message: txStatus === TxStatus.Pending
|
|
80
|
+
? 'Bridge in progress'
|
|
81
|
+
: txStatus === TxStatus.Failed
|
|
82
|
+
? bridgeStatus.errorMessage
|
|
83
|
+
: undefined,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (swap) {
|
|
44
88
|
const squidResult = await fetchSquidBridgeStatus(txHash, swap.sellAsset.chainId, swap.buyAsset.chainId);
|
|
45
89
|
if (squidResult.isOk()) {
|
|
46
90
|
const squidStatus = squidResult.unwrap();
|
|
47
|
-
const squidTxStatus = (
|
|
48
|
-
switch (squidStatus.status) {
|
|
49
|
-
case 'confirmed':
|
|
50
|
-
return TxStatus.Confirmed;
|
|
51
|
-
case 'failed':
|
|
52
|
-
return TxStatus.Failed;
|
|
53
|
-
case 'pending':
|
|
54
|
-
default:
|
|
55
|
-
return TxStatus.Pending;
|
|
56
|
-
}
|
|
57
|
-
})();
|
|
91
|
+
const squidTxStatus = bridgeStatusToTxStatus(squidStatus.status);
|
|
58
92
|
return {
|
|
59
93
|
status: squidTxStatus,
|
|
60
94
|
buyTxHash: squidStatus.destinationTxHash,
|
|
61
|
-
swapperTxLink: getSquidTrackingLink(txHash, squidStatus, swap.sellAsset.explorerTxLink, swap.buyAsset.explorerTxLink),
|
|
62
95
|
message: squidTxStatus === TxStatus.Pending ? 'Cross-chain swap in progress' : undefined,
|
|
63
96
|
};
|
|
64
97
|
}
|
|
65
|
-
return {
|
|
66
|
-
status: TxStatus.Pending,
|
|
67
|
-
buyTxHash: undefined,
|
|
68
|
-
swapperTxLink: getAxelarscanTrackingLink(txHash),
|
|
69
|
-
message: 'Bridge status check failed - track manually',
|
|
70
|
-
};
|
|
71
98
|
}
|
|
72
|
-
|
|
73
|
-
if (!bridgeStatus) {
|
|
74
|
-
return {
|
|
75
|
-
status: TxStatus.Pending,
|
|
76
|
-
buyTxHash: undefined,
|
|
77
|
-
message: 'Cross-chain swap in progress',
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
const txStatus = (() => {
|
|
81
|
-
switch (bridgeStatus.status) {
|
|
82
|
-
case 'confirmed':
|
|
83
|
-
return TxStatus.Confirmed;
|
|
84
|
-
case 'failed':
|
|
85
|
-
return TxStatus.Failed;
|
|
86
|
-
case 'pending':
|
|
87
|
-
default:
|
|
88
|
-
return TxStatus.Pending;
|
|
89
|
-
}
|
|
90
|
-
})();
|
|
99
|
+
// No indexer knows the tx yet - the bridge may not have picked it up, so keep polling
|
|
91
100
|
return {
|
|
92
|
-
status:
|
|
93
|
-
buyTxHash:
|
|
94
|
-
|
|
95
|
-
message: txStatus === TxStatus.Pending
|
|
96
|
-
? 'Bridge in progress'
|
|
97
|
-
: txStatus === TxStatus.Failed
|
|
98
|
-
? bridgeStatus.errorMessage
|
|
99
|
-
: undefined,
|
|
101
|
+
status: TxStatus.Pending,
|
|
102
|
+
buyTxHash: undefined,
|
|
103
|
+
message: 'Cross-chain swap in progress',
|
|
100
104
|
};
|
|
101
105
|
},
|
|
102
106
|
};
|
|
@@ -6,4 +6,3 @@ export type AxelarscanBridgeStatus = {
|
|
|
6
6
|
errorMessage?: string;
|
|
7
7
|
};
|
|
8
8
|
export declare const fetchAxelarscanBridgeStatus: (sourceTxHash: string) => Promise<Result<AxelarscanBridgeStatus | undefined, SwapErrorRight>>;
|
|
9
|
-
export declare const getAxelarscanTrackingLink: (sourceTxHash: string) => string;
|
|
@@ -13,9 +13,8 @@ export const fetchAxelarscanBridgeStatus = async (sourceTxHash) => {
|
|
|
13
13
|
return Ok(undefined);
|
|
14
14
|
}
|
|
15
15
|
const bridgeData = data.data[0];
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
bridgeData.express_executed?.transactionHash;
|
|
16
|
+
// `call` is the origin call, so only the executed hashes identify the destination leg
|
|
17
|
+
const destinationTxHash = bridgeData.executed?.transaction_hash || bridgeData.express_executed?.transactionHash;
|
|
19
18
|
const isCompleted = bridgeData.status === 'executed' ||
|
|
20
19
|
bridgeData.status === 'destination_executed' ||
|
|
21
20
|
bridgeData.status === 'express_executed' ||
|
|
@@ -44,4 +43,3 @@ export const fetchAxelarscanBridgeStatus = async (sourceTxHash) => {
|
|
|
44
43
|
}));
|
|
45
44
|
}
|
|
46
45
|
};
|
|
47
|
-
export const getAxelarscanTrackingLink = (sourceTxHash) => `https://axelarscan.io/gmp/${sourceTxHash}`;
|
|
@@ -16,9 +16,11 @@ export const fetchPortalsTradeOrder = async ({ sender, inputToken, inputAmount,
|
|
|
16
16
|
validate: validate.toString(),
|
|
17
17
|
});
|
|
18
18
|
if (!autoSlippage) {
|
|
19
|
-
|
|
19
|
+
// Portals API expects a string with at most 2 decimal places
|
|
20
|
+
params.append('slippageTolerancePercentage', slippageTolerancePercentage.toFixed(2));
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
+
// Portals defaults to their own partner fee when this is omitted - always send it, zero included
|
|
23
|
+
if (feePercentage !== undefined) {
|
|
22
24
|
params.append('feePercentage', feePercentage.toString());
|
|
23
25
|
}
|
|
24
26
|
try {
|
|
@@ -44,7 +46,8 @@ export const fetchPortalsTradeEstimate = async ({ inputToken, inputAmount, outpu
|
|
|
44
46
|
outputToken,
|
|
45
47
|
});
|
|
46
48
|
if (slippageTolerancePercentage !== undefined) {
|
|
47
|
-
|
|
49
|
+
// Portals API expects a string with at most 2 decimal places
|
|
50
|
+
params.append('slippageTolerancePercentage', slippageTolerancePercentage.toFixed(2));
|
|
48
51
|
}
|
|
49
52
|
try {
|
|
50
53
|
const response = await axios.get(url, { params });
|
|
@@ -6,4 +6,3 @@ export type SquidBridgeStatus = {
|
|
|
6
6
|
destinationTxHash?: string;
|
|
7
7
|
};
|
|
8
8
|
export declare const fetchSquidBridgeStatus: (sourceTxHash: string, sourceChainId: ChainId, destinationChainId: ChainId) => Promise<Result<SquidBridgeStatus, SwapErrorRight>>;
|
|
9
|
-
export declare const getSquidTrackingLink: (sourceTxHash: string, squidStatus: SquidBridgeStatus, sellAssetExplorerTxLink: string, buyAssetExplorerTxLink: string) => string;
|
|
@@ -44,9 +44,3 @@ export const fetchSquidBridgeStatus = async (sourceTxHash, sourceChainId, destin
|
|
|
44
44
|
}));
|
|
45
45
|
}
|
|
46
46
|
};
|
|
47
|
-
export const getSquidTrackingLink = (sourceTxHash, squidStatus, sellAssetExplorerTxLink, buyAssetExplorerTxLink) => {
|
|
48
|
-
if (squidStatus.status === 'confirmed' && squidStatus.destinationTxHash) {
|
|
49
|
-
return `${buyAssetExplorerTxLink}${squidStatus.destinationTxHash}`;
|
|
50
|
-
}
|
|
51
|
-
return `${sellAssetExplorerTxLink}${sourceTxHash}`;
|
|
52
|
-
};
|
|
@@ -3,6 +3,7 @@ import type { StepDataArgs, SwapErrorRight, TxBuildData } from '../../../types.j
|
|
|
3
3
|
import type { PortalsTx } from './fetchPortalsTradeOrder.js';
|
|
4
4
|
type BaseArgs = {
|
|
5
5
|
tx: PortalsTx;
|
|
6
|
+
sellAmountCryptoBaseUnit: string;
|
|
6
7
|
spenderAddress: string;
|
|
7
8
|
};
|
|
8
9
|
export type GetPortalsStepDataArgs = StepDataArgs<BaseArgs, {
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { fromChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { bnOrZero } from '@shapeshiftoss/utils';
|
|
2
3
|
import { Err, Ok } from '@sniptt/monads';
|
|
3
4
|
import { makeNetworkFeeEstimationFailedErr } from '../../../utils/index.js';
|
|
4
5
|
import { estimateGasWithStateOverride, getEvmNetworkFeeCryptoBaseUnit } from '../../../utils/evm/index.js';
|
|
5
6
|
import { fetchPortalsTradeEstimate } from './fetchPortalsTradeOrder.js';
|
|
6
7
|
export async function getPortalsStepData(args) {
|
|
7
|
-
const { tx, sellAsset, spenderAddress, input, deps } = args;
|
|
8
|
+
const { tx, sellAsset, sellAmountCryptoBaseUnit, spenderAddress, input, deps } = args;
|
|
8
9
|
const adapter = deps.assertGetEvmChainAdapter(sellAsset.chainId);
|
|
9
10
|
const supportsEIP1559 = 'supportsEIP1559' in input ? input.supportsEIP1559 : false;
|
|
10
11
|
if (args.type === 'rate') {
|
|
11
12
|
try {
|
|
12
13
|
// No placeholder estimation for provider built routes - overridden estimation (approval
|
|
13
|
-
// state need not exist yet) with the Portals estimate endpoint as
|
|
14
|
+
// state need not exist yet) with the Portals order and estimate endpoint as fallbacks
|
|
14
15
|
const gasLimit = await (async () => {
|
|
15
16
|
try {
|
|
16
17
|
const gasLimit = await estimateGasWithStateOverride({
|
|
17
18
|
sellAsset,
|
|
18
|
-
sellAmountCryptoBaseUnit
|
|
19
|
+
sellAmountCryptoBaseUnit,
|
|
19
20
|
from: tx.from,
|
|
20
21
|
spenderAddress,
|
|
21
22
|
to: tx.to,
|
|
@@ -25,6 +26,10 @@ export async function getPortalsStepData(args) {
|
|
|
25
26
|
return gasLimit;
|
|
26
27
|
}
|
|
27
28
|
catch {
|
|
29
|
+
// Portals only carry a tx gas limit on the bridge routes their estimate endpoint zeroes
|
|
30
|
+
const { gasLimit: txGasLimit } = tx;
|
|
31
|
+
if (txGasLimit && bnOrZero(txGasLimit).gt(0))
|
|
32
|
+
return txGasLimit;
|
|
28
33
|
const quoteEstimateResponse = await fetchPortalsTradeEstimate({
|
|
29
34
|
inputToken: args.inputToken,
|
|
30
35
|
outputToken: args.outputToken,
|
|
@@ -32,7 +37,10 @@ export async function getPortalsStepData(args) {
|
|
|
32
37
|
slippageTolerancePercentage: args.slippageTolerancePercentage,
|
|
33
38
|
swapperConfig: deps.config,
|
|
34
39
|
});
|
|
35
|
-
|
|
40
|
+
const estimatedGasLimit = quoteEstimateResponse.context.gasLimit.toString();
|
|
41
|
+
if (bnOrZero(estimatedGasLimit).lte(0))
|
|
42
|
+
throw new Error('no Portals gas limit');
|
|
43
|
+
return estimatedGasLimit;
|
|
36
44
|
}
|
|
37
45
|
})();
|
|
38
46
|
const networkFeeCryptoBaseUnit = await getEvmNetworkFeeCryptoBaseUnit({
|
|
@@ -65,7 +73,7 @@ export async function getPortalsStepData(args) {
|
|
|
65
73
|
supportsEIP1559,
|
|
66
74
|
stateOverride: {
|
|
67
75
|
sellAsset,
|
|
68
|
-
sellAmountCryptoBaseUnit
|
|
76
|
+
sellAmountCryptoBaseUnit,
|
|
69
77
|
spenderAddress,
|
|
70
78
|
},
|
|
71
79
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|