@shapeshiftoss/swapper 17.7.1 → 17.7.3
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/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/constants.d.ts +1 -0
- package/dist/cjs/swappers/NearIntentsSwapper/constants.js +2 -1
- package/dist/cjs/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +5 -2
- package/dist/cjs/swappers/NearIntentsSwapper/utils/helpers/helpers.js +5 -1
- package/dist/cjs/swappers/ThorchainSwapper/getTradeQuote/getTradeQuote.test.js +10 -0
- package/dist/cjs/thorchain-utils/checkTradeStatus.js +8 -1
- package/dist/cjs/thorchain-utils/cosmossdk/getThorTxData.d.ts +12 -0
- package/dist/cjs/thorchain-utils/cosmossdk/getThorTxData.js +19 -0
- package/dist/cjs/thorchain-utils/cosmossdk/index.d.ts +1 -0
- package/dist/cjs/thorchain-utils/cosmossdk/index.js +1 -0
- package/dist/cjs/thorchain-utils/getL1RateOrQuote.js +35 -10
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.d.ts +3 -2
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.js +21 -14
- package/dist/cjs/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.js +11 -5
- package/dist/cjs/thorchain-utils/index.d.ts +1 -0
- package/dist/cjs/thorchain-utils/index.js +12 -1
- package/dist/cjs/types.d.ts +6 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/constants.d.ts +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/constants.js +1 -0
- package/dist/esm/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.js +7 -4
- package/dist/esm/swappers/NearIntentsSwapper/utils/helpers/helpers.js +5 -1
- package/dist/esm/swappers/ThorchainSwapper/getTradeQuote/getTradeQuote.test.js +10 -0
- package/dist/esm/thorchain-utils/checkTradeStatus.js +8 -1
- package/dist/esm/thorchain-utils/cosmossdk/getThorTxData.d.ts +12 -0
- package/dist/esm/thorchain-utils/cosmossdk/getThorTxData.js +15 -0
- package/dist/esm/thorchain-utils/cosmossdk/index.d.ts +1 -0
- package/dist/esm/thorchain-utils/cosmossdk/index.js +1 -0
- package/dist/esm/thorchain-utils/getL1RateOrQuote.js +35 -10
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.d.ts +3 -2
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.js +20 -13
- package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.js +12 -6
- package/dist/esm/thorchain-utils/index.d.ts +1 -0
- package/dist/esm/thorchain-utils/index.js +11 -1
- package/dist/esm/types.d.ts +6 -0
- package/package.json +2 -2
package/dist/esm/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './swappers/PortalsSwapper/index.js';
|
|
|
14
14
|
export * from './swappers/ThorchainSwapper/index.js';
|
|
15
15
|
export * from './swappers/MayachainSwapper/index.js';
|
|
16
16
|
export * from './swappers/ButterSwap/index.js';
|
|
17
|
+
export * from './swappers/RelaySwapper/index.js';
|
|
17
18
|
export * from './swappers/utils/helpers/helpers.js';
|
|
18
19
|
export * from './thorchain-utils/index.js';
|
|
19
20
|
export * from './types.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export * from './swappers/PortalsSwapper/index.js';
|
|
|
14
14
|
export * from './swappers/ThorchainSwapper/index.js';
|
|
15
15
|
export * from './swappers/MayachainSwapper/index.js';
|
|
16
16
|
export * from './swappers/ButterSwap/index.js';
|
|
17
|
+
export * from './swappers/RelaySwapper/index.js';
|
|
17
18
|
export * from './swappers/utils/helpers/helpers.js';
|
|
18
19
|
export * from './thorchain-utils/index.js';
|
|
19
20
|
export * from './types.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CHAIN_NAMESPACE, fromAssetId, nearChainId } from '@shapeshiftoss/caip';
|
|
1
|
+
import { btcChainId, CHAIN_NAMESPACE, fromAssetId, nearChainId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { evm } from '@shapeshiftoss/chain-adapters';
|
|
3
3
|
import { bn, bnOrZero, chainIdToFeeAssetId, contractAddressOrUndefined, DAO_TREASURY_NEAR, isToken, } from '@shapeshiftoss/utils';
|
|
4
4
|
import { Err, Ok } from '@sniptt/monads';
|
|
@@ -8,7 +8,7 @@ import { SwapperName, TradeQuoteError } from '../../../types.js';
|
|
|
8
8
|
import { createTradeAmountTooSmallErr, getInputOutputRate, makeSwapErrorRight, } from '../../../utils.js';
|
|
9
9
|
import { buildAffiliateFee } from '../../utils/affiliateFee.js';
|
|
10
10
|
import { isNativeEvmAsset } from '../../utils/helpers/helpers.js';
|
|
11
|
-
import { DEFAULT_QUOTE_DEADLINE_MS, DEFAULT_SLIPPAGE_BPS } from '../constants.js';
|
|
11
|
+
import { BTC_QUOTE_DEADLINE_MS, DEFAULT_QUOTE_DEADLINE_MS, DEFAULT_SLIPPAGE_BPS, } from '../constants.js';
|
|
12
12
|
import { QuoteRequest } from '../types.js';
|
|
13
13
|
import { assetToNearIntentsAsset, calculateAccountCreationCosts } from '../utils/helpers/helpers.js';
|
|
14
14
|
import { ApiError, initializeOneClickService, OneClickService } from '../utils/oneClickService.js';
|
|
@@ -49,6 +49,9 @@ export const getTradeQuote = async (input, deps) => {
|
|
|
49
49
|
message: `Asset ${buyAsset.symbol} on ${buyAsset.networkName || buyAsset.chainId} is not supported by NEAR Intents`,
|
|
50
50
|
}));
|
|
51
51
|
}
|
|
52
|
+
const quoteDeadline = sellAsset.chainId === btcChainId || buyAsset.chainId === btcChainId
|
|
53
|
+
? BTC_QUOTE_DEADLINE_MS
|
|
54
|
+
: DEFAULT_QUOTE_DEADLINE_MS;
|
|
52
55
|
const quoteRequest = {
|
|
53
56
|
dry: false,
|
|
54
57
|
swapType: QuoteRequest.swapType.EXACT_INPUT,
|
|
@@ -63,7 +66,7 @@ export const getTradeQuote = async (input, deps) => {
|
|
|
63
66
|
refundType: QuoteRequest.refundType.ORIGIN_CHAIN,
|
|
64
67
|
recipient: receiveAddress,
|
|
65
68
|
recipientType: QuoteRequest.recipientType.DESTINATION_CHAIN,
|
|
66
|
-
deadline: new Date(Date.now() +
|
|
69
|
+
deadline: new Date(Date.now() + quoteDeadline).toISOString(),
|
|
67
70
|
referral: 'shapeshift',
|
|
68
71
|
appFees: [
|
|
69
72
|
{
|
|
@@ -256,7 +259,7 @@ export const getTradeQuote = async (input, deps) => {
|
|
|
256
259
|
steps: [
|
|
257
260
|
{
|
|
258
261
|
accountNumber,
|
|
259
|
-
allowanceContract:
|
|
262
|
+
allowanceContract: '',
|
|
260
263
|
buyAmountBeforeFeesCryptoBaseUnit: quote.amountOut,
|
|
261
264
|
buyAmountAfterFeesCryptoBaseUnit: quote.amountOut,
|
|
262
265
|
buyAsset,
|
|
@@ -45,6 +45,7 @@ export const getNearIntentsAsset = ({ nearNetwork, contractAddress, }) => {
|
|
|
45
45
|
const NEP245_CHAINS = ['bsc', 'pol', 'avax', 'op', 'tron', 'monad', 'plasma'];
|
|
46
46
|
const TOKEN_LOOKUP_CHAINS = ['sui', 'starknet', 'ton'];
|
|
47
47
|
const NEAR_CHAIN = 'near';
|
|
48
|
+
const BTC_CHAIN = 'btc';
|
|
48
49
|
const WNEAR_CONTRACT_ADDRESS = 'wrap.near';
|
|
49
50
|
const isNep245Chain = (chain) => {
|
|
50
51
|
return NEP245_CHAINS.includes(chain);
|
|
@@ -56,6 +57,9 @@ export const assetToNearIntentsAsset = async (asset) => {
|
|
|
56
57
|
const nearNetwork = chainIdToNearIntentsChain[asset.chainId];
|
|
57
58
|
if (!nearNetwork)
|
|
58
59
|
return null;
|
|
60
|
+
// https://partners.near-intents.org/omni-migration#partners
|
|
61
|
+
if (nearNetwork === BTC_CHAIN)
|
|
62
|
+
return `1cs_v1:btc:native:coin`;
|
|
59
63
|
// NEAR chain requires special handling
|
|
60
64
|
// Native NEAR maps to wNEAR (wrap.near)
|
|
61
65
|
if (nearNetwork === NEAR_CHAIN) {
|
|
@@ -91,7 +95,7 @@ export const assetToNearIntentsAsset = async (asset) => {
|
|
|
91
95
|
}
|
|
92
96
|
return match.assetId;
|
|
93
97
|
}
|
|
94
|
-
// NEP-141 chains (ETH, ARB, BASE, GNOSIS,
|
|
98
|
+
// NEP-141 chains (ETH, ARB, BASE, GNOSIS, DOGE): use predictable format
|
|
95
99
|
const contractAddress = isToken(asset.assetId)
|
|
96
100
|
? fromAssetId(asset.assetId).assetReference
|
|
97
101
|
: zeroAddress;
|
|
@@ -76,6 +76,11 @@ const expectedQuoteResponse = [
|
|
|
76
76
|
thorchainSpecific: {
|
|
77
77
|
maxStreamingQuantity: undefined,
|
|
78
78
|
},
|
|
79
|
+
thorchainTransactionMetadata: {
|
|
80
|
+
to: '0x3624525075b88B24ecc29CE226b0CEc1fFcB6976',
|
|
81
|
+
data: '0x',
|
|
82
|
+
value: '0',
|
|
83
|
+
},
|
|
79
84
|
},
|
|
80
85
|
],
|
|
81
86
|
},
|
|
@@ -119,6 +124,11 @@ const expectedQuoteResponse = [
|
|
|
119
124
|
thorchainSpecific: {
|
|
120
125
|
maxStreamingQuantity: undefined,
|
|
121
126
|
},
|
|
127
|
+
thorchainTransactionMetadata: {
|
|
128
|
+
to: '0x3624525075b88B24ecc29CE226b0CEc1fFcB6976',
|
|
129
|
+
data: '0x',
|
|
130
|
+
value: '0',
|
|
131
|
+
},
|
|
122
132
|
},
|
|
123
133
|
],
|
|
124
134
|
},
|
|
@@ -62,7 +62,14 @@ export const checkTradeStatus = async ({ txHash, chainId, address, fetchIsSmartC
|
|
|
62
62
|
return { buyTxHash, status: TxStatus.Pending, message };
|
|
63
63
|
}
|
|
64
64
|
catch (e) {
|
|
65
|
-
|
|
65
|
+
const message = (() => {
|
|
66
|
+
if (axios.isAxiosError(e))
|
|
67
|
+
return e.response?.data?.message ?? e.message;
|
|
68
|
+
if (e instanceof Error)
|
|
69
|
+
return e.message;
|
|
70
|
+
return String(e);
|
|
71
|
+
})();
|
|
72
|
+
console.error(`checkTradeStatus(${nativeChain}, ${txHash}): ${message}`);
|
|
66
73
|
return { buyTxHash: undefined, status: TxStatus.Unknown, message: undefined };
|
|
67
74
|
}
|
|
68
75
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Asset } from '@shapeshiftoss/types';
|
|
2
|
+
import type { SwapperConfig, SwapperName } from '../../types.js';
|
|
3
|
+
type GetThorTxDataArgs = {
|
|
4
|
+
sellAsset: Asset;
|
|
5
|
+
config: SwapperConfig;
|
|
6
|
+
swapperName: SwapperName;
|
|
7
|
+
};
|
|
8
|
+
type GetThorTxDataReturn = {
|
|
9
|
+
vault: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const getThorTxData: ({ sellAsset, config, swapperName, }: GetThorTxDataArgs) => Promise<GetThorTxDataReturn>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getInboundAddressDataForChain } from '../getInboundAddressDataForChain.js';
|
|
2
|
+
import { getChainIdBySwapper, getDaemonUrl } from '../index.js';
|
|
3
|
+
export const getThorTxData = async ({ sellAsset, config, swapperName, }) => {
|
|
4
|
+
// Native assets on the swapper's own chain (RUNE on THORChain, CACAO on MAYAChain)
|
|
5
|
+
// deposit via MsgDeposit and have no recipient address.
|
|
6
|
+
if (sellAsset.chainId === getChainIdBySwapper(swapperName))
|
|
7
|
+
return { vault: '' };
|
|
8
|
+
// Everything else (e.g. ATOM via THORChain, RUNE via MAYAChain) sends via MsgSend
|
|
9
|
+
// to the swapper's inbound vault on that chain.
|
|
10
|
+
const daemonUrl = getDaemonUrl(config, swapperName);
|
|
11
|
+
const res = await getInboundAddressDataForChain(daemonUrl, sellAsset.assetId, true, swapperName);
|
|
12
|
+
if (res.isErr())
|
|
13
|
+
throw res.unwrapErr();
|
|
14
|
+
return { vault: res.unwrap().address };
|
|
15
|
+
};
|
|
@@ -7,8 +7,10 @@ import { TronWeb } from 'tronweb';
|
|
|
7
7
|
import { v4 as uuid } from 'uuid';
|
|
8
8
|
import { getDefaultSlippageDecimalPercentageForSwapper } from '../index.js';
|
|
9
9
|
import { buildAffiliateFee } from '../swappers/utils/affiliateFee.js';
|
|
10
|
+
import { isNativeEvmAsset } from '../swappers/utils/helpers/helpers.js';
|
|
10
11
|
import { TradeQuoteError } from '../types.js';
|
|
11
12
|
import { getInputOutputRate, makeSwapErrorRight } from '../utils.js';
|
|
13
|
+
import * as cosmossdk from './cosmossdk/index.js';
|
|
12
14
|
import * as evm from './evm/index.js';
|
|
13
15
|
import { getLimitWithManualSlippage } from './getLimitWithManualSlippage/getLimitWithManualSlippage.js';
|
|
14
16
|
import { getQuote } from './getQuote.js';
|
|
@@ -128,7 +130,7 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
128
130
|
affilate: getAffiliate(swapperName),
|
|
129
131
|
});
|
|
130
132
|
};
|
|
131
|
-
const makeThorTradeRateOrQuote = ({ route, memo, allowanceContract, feeData, data, router, vault, }) => {
|
|
133
|
+
const makeThorTradeRateOrQuote = ({ route, memo, allowanceContract, feeData, data, router, vault, thorchainTransactionMetadata, }) => {
|
|
132
134
|
const buyAmountAfterFeesCryptoBaseUnit = convertPrecision({
|
|
133
135
|
value: route.expectedAmountOutThorBaseUnit,
|
|
134
136
|
inputExponent: buyAssetNativePrecision,
|
|
@@ -182,6 +184,7 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
182
184
|
thorchainSpecific: {
|
|
183
185
|
maxStreamingQuantity: route.quote.max_streaming_quantity,
|
|
184
186
|
},
|
|
187
|
+
thorchainTransactionMetadata,
|
|
185
188
|
},
|
|
186
189
|
],
|
|
187
190
|
};
|
|
@@ -213,6 +216,11 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
213
216
|
data,
|
|
214
217
|
router,
|
|
215
218
|
vault,
|
|
219
|
+
thorchainTransactionMetadata: {
|
|
220
|
+
to: router,
|
|
221
|
+
data,
|
|
222
|
+
value: isNativeEvmAsset(sellAsset.assetId) ? sellAmountCryptoBaseUnit : '0',
|
|
223
|
+
},
|
|
216
224
|
feeData: {
|
|
217
225
|
protocolFees: getProtocolFees(route.quote),
|
|
218
226
|
networkFeeCryptoBaseUnit,
|
|
@@ -260,6 +268,11 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
260
268
|
route,
|
|
261
269
|
allowanceContract: '0x0',
|
|
262
270
|
memo,
|
|
271
|
+
thorchainTransactionMetadata: {
|
|
272
|
+
to: vault,
|
|
273
|
+
memo,
|
|
274
|
+
value: sellAmountCryptoBaseUnit,
|
|
275
|
+
},
|
|
263
276
|
feeData,
|
|
264
277
|
});
|
|
265
278
|
}));
|
|
@@ -275,11 +288,18 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
275
288
|
case CHAIN_NAMESPACE.CosmosSdk: {
|
|
276
289
|
const cosmosChainAdapter = assertGetCosmosSdkChainAdapter(sellAsset.chainId);
|
|
277
290
|
const { fast } = await cosmosChainAdapter.getFeeData({});
|
|
291
|
+
const { vault } = await cosmossdk.getThorTxData({ sellAsset, config, swapperName });
|
|
278
292
|
return Ok(perRouteValues.map((route) => {
|
|
293
|
+
const memo = getMemo(route);
|
|
279
294
|
return makeThorTradeRateOrQuote({
|
|
280
295
|
route,
|
|
281
|
-
memo
|
|
296
|
+
memo,
|
|
282
297
|
allowanceContract: '0x0',
|
|
298
|
+
thorchainTransactionMetadata: {
|
|
299
|
+
to: vault,
|
|
300
|
+
memo,
|
|
301
|
+
value: sellAmountCryptoBaseUnit,
|
|
302
|
+
},
|
|
283
303
|
feeData: {
|
|
284
304
|
networkFeeCryptoBaseUnit: fast.txFee,
|
|
285
305
|
protocolFees: getProtocolFees(route.quote),
|
|
@@ -293,13 +313,13 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
293
313
|
case CHAIN_NAMESPACE.Solana: {
|
|
294
314
|
const adapter = assertGetSolanaChainAdapter(sellAsset.chainId);
|
|
295
315
|
const sendAddress = input.sendAddress;
|
|
316
|
+
const { vault } = await solana.getThorTxData({ sellAsset, config, swapperName });
|
|
296
317
|
const maybeRoutes = await Promise.allSettled(perRouteValues.map(async (route) => {
|
|
297
318
|
const memo = getMemo(route);
|
|
298
319
|
const protocolFees = getProtocolFees(route.quote);
|
|
299
320
|
const feeData = await (async () => {
|
|
300
321
|
if (!sendAddress)
|
|
301
322
|
return { networkFeeCryptoBaseUnit: undefined, protocolFees };
|
|
302
|
-
const { vault } = await solana.getThorTxData({ sellAsset, config, swapperName });
|
|
303
323
|
const memoInstruction = new TransactionInstruction({
|
|
304
324
|
keys: [],
|
|
305
325
|
programId: new PublicKey(SOLANA_MEMO_PROGRAM_ID),
|
|
@@ -325,6 +345,11 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
325
345
|
route,
|
|
326
346
|
allowanceContract: '0x0',
|
|
327
347
|
memo,
|
|
348
|
+
thorchainTransactionMetadata: {
|
|
349
|
+
to: vault,
|
|
350
|
+
memo,
|
|
351
|
+
value: sellAmountCryptoBaseUnit,
|
|
352
|
+
},
|
|
328
353
|
feeData,
|
|
329
354
|
});
|
|
330
355
|
}));
|
|
@@ -338,20 +363,15 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
338
363
|
return Ok(routes);
|
|
339
364
|
}
|
|
340
365
|
case CHAIN_NAMESPACE.Tron: {
|
|
366
|
+
const { vault } = await tron.getThorTxData({ sellAsset, config, swapperName });
|
|
341
367
|
const maybeRoutes = await Promise.allSettled(perRouteValues.map(async (route) => {
|
|
342
368
|
const memo = getMemo(route);
|
|
343
369
|
let networkFeeCryptoBaseUnit = undefined;
|
|
344
370
|
// Calculate fees for rates when we have a receive address (wallet connected)
|
|
345
|
-
if (input.quoteOrRate === 'rate' && input.receiveAddress) {
|
|
371
|
+
if (input.quoteOrRate === 'rate' && input.receiveAddress && vault) {
|
|
346
372
|
try {
|
|
347
373
|
const { sellAsset, sellAmountIncludingProtocolFeesCryptoBaseUnit } = input;
|
|
348
374
|
const contractAddress = contractAddressOrUndefined(sellAsset.assetId);
|
|
349
|
-
// Get vault address
|
|
350
|
-
const { vault } = await tron.getThorTxData({
|
|
351
|
-
sellAsset,
|
|
352
|
-
config,
|
|
353
|
-
swapperName,
|
|
354
|
-
});
|
|
355
375
|
// Estimate fees using the receive address for accurate energy calculation
|
|
356
376
|
const tronWeb = new TronWeb({
|
|
357
377
|
fullHost: deps.config.VITE_TRON_NODE_URL,
|
|
@@ -400,6 +420,11 @@ export const getL1RateOrQuote = async (input, deps, streamingInterval, tradeType
|
|
|
400
420
|
route,
|
|
401
421
|
allowanceContract: '0x0',
|
|
402
422
|
memo,
|
|
423
|
+
thorchainTransactionMetadata: {
|
|
424
|
+
to: vault,
|
|
425
|
+
memo,
|
|
426
|
+
value: sellAmountCryptoBaseUnit,
|
|
427
|
+
},
|
|
403
428
|
feeData: {
|
|
404
429
|
networkFeeCryptoBaseUnit,
|
|
405
430
|
protocolFees: getProtocolFees(route.quote),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { AssetId } from '@shapeshiftoss/caip';
|
|
1
2
|
import type { Asset } from '@shapeshiftoss/types';
|
|
2
3
|
import type { SwapperConfig, SwapperName } from '../../types.js';
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const getOutboundFeeSellAssetThorBaseUnit: (runePerAsset: string, sellAssetId: AssetId, swapperName: SwapperName) => BigNumber;
|
|
5
|
+
export declare const getExpectedAffiliateFeeSellAssetThorBaseUnit: (sellAmountCryptoBaseUnit: string, sellAsset: Asset, affiliateBps: string, swapperName: SwapperName) => BigNumber;
|
|
5
6
|
export declare const getThresholdedAffiliateBps: ({ sellAsset, affiliateBps, sellAmountCryptoBaseUnit, config, swapperName, }: {
|
|
6
7
|
sellAsset: Asset;
|
|
7
8
|
affiliateBps: string;
|
|
@@ -1,21 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getMidgardUrl, getNativeFee, getNativePrecision, getPoolAssetId, isNativeAsset, thorService, } from '../index.js';
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { convertBasisPointsToDecimalPercentage, convertPrecision } from '@shapeshiftoss/utils';
|
|
2
|
+
import { getMidgardUrl, getNativeFee, getNativePrecision, getPoolAssetId, getSwapperNativeAssetId, isNativeAsset, thorService, } from '../index.js';
|
|
3
|
+
// Convert native fee to sell asset's native precision before dividing by `assetPrice`.
|
|
4
|
+
// MAYA's CACAO is 10-dec but pool assets are 8-dec — skip this and the result is 100x off.
|
|
5
|
+
export const getOutboundFeeSellAssetThorBaseUnit = (runePerAsset, sellAssetId, swapperName) => {
|
|
6
|
+
const nativeFeeSellAssetThorBaseUnit = convertPrecision({
|
|
7
|
+
value: getNativeFee(swapperName),
|
|
8
|
+
inputExponent: getNativePrecision(getSwapperNativeAssetId(swapperName), swapperName),
|
|
9
|
+
outputExponent: getNativePrecision(sellAssetId, swapperName),
|
|
10
|
+
});
|
|
11
|
+
return nativeFeeSellAssetThorBaseUnit.dividedBy(runePerAsset);
|
|
5
12
|
};
|
|
6
|
-
export const
|
|
7
|
-
const
|
|
13
|
+
export const getExpectedAffiliateFeeSellAssetThorBaseUnit = (sellAmountCryptoBaseUnit, sellAsset, affiliateBps, swapperName) => {
|
|
14
|
+
const sellAmountThorBaseUnit = convertPrecision({
|
|
8
15
|
value: sellAmountCryptoBaseUnit,
|
|
9
16
|
inputExponent: sellAsset.precision,
|
|
10
17
|
outputExponent: getNativePrecision(sellAsset.assetId, swapperName),
|
|
11
18
|
});
|
|
12
19
|
const affiliatePercent = convertBasisPointsToDecimalPercentage(affiliateBps);
|
|
13
|
-
return
|
|
20
|
+
return sellAmountThorBaseUnit.times(affiliatePercent);
|
|
14
21
|
};
|
|
15
22
|
// don't apply an affiliate fee if it's below the outbound fee for the inbound pool
|
|
16
23
|
export const getThresholdedAffiliateBps = async ({ sellAsset, affiliateBps, sellAmountCryptoBaseUnit, config, swapperName, }) => {
|
|
17
24
|
const midgardUrl = getMidgardUrl(config, swapperName);
|
|
18
|
-
const
|
|
25
|
+
const outboundFeeSellAssetThorBaseUnit = await (async () => {
|
|
19
26
|
if (isNativeAsset(sellAsset.assetId, swapperName))
|
|
20
27
|
return getNativeFee(swapperName);
|
|
21
28
|
const sellPoolId = getPoolAssetId({ assetId: sellAsset.assetId, swapperName });
|
|
@@ -24,11 +31,11 @@ export const getThresholdedAffiliateBps = async ({ sellAsset, affiliateBps, sell
|
|
|
24
31
|
if (res.isErr())
|
|
25
32
|
throw res.unwrapErr();
|
|
26
33
|
const pool = res.unwrap().data;
|
|
27
|
-
// calculate the rune outbound fee denominated in the sell asset, in
|
|
28
|
-
return
|
|
34
|
+
// calculate the rune outbound fee denominated in the sell asset, in thor base units
|
|
35
|
+
return getOutboundFeeSellAssetThorBaseUnit(pool.assetPrice, sellAsset.assetId, swapperName);
|
|
29
36
|
})();
|
|
30
|
-
// calculate the expected affiliate fee, in
|
|
31
|
-
const
|
|
32
|
-
const isAffiliateFeeBelowOutboundFee =
|
|
37
|
+
// calculate the expected affiliate fee, in thor base units
|
|
38
|
+
const expectedAffiliateFeeSellAssetThorBaseUnit = getExpectedAffiliateFeeSellAssetThorBaseUnit(sellAmountCryptoBaseUnit, sellAsset, affiliateBps, swapperName);
|
|
39
|
+
const isAffiliateFeeBelowOutboundFee = expectedAffiliateFeeSellAssetThorBaseUnit.lte(outboundFeeSellAssetThorBaseUnit);
|
|
33
40
|
return isAffiliateFeeBelowOutboundFee ? '0' : affiliateBps;
|
|
34
41
|
};
|
package/dist/esm/thorchain-utils/getThresholdedAffiliateBps/getThresholdedAffiliateBps.test.js
CHANGED
|
@@ -5,7 +5,7 @@ import { describe, expect, it, vi } from 'vitest';
|
|
|
5
5
|
import { ETH } from '../../swappers/utils/test-data/index.js';
|
|
6
6
|
import { SwapperName } from '../../types.js';
|
|
7
7
|
import { thorService } from '../service.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getExpectedAffiliateFeeSellAssetThorBaseUnit, getOutboundFeeSellAssetThorBaseUnit, getThresholdedAffiliateBps, } from './getThresholdedAffiliateBps.js';
|
|
9
9
|
const mockedThorService = vi.mocked(thorService);
|
|
10
10
|
const mocks = vi.hoisted(() => ({
|
|
11
11
|
get: vi.fn(),
|
|
@@ -24,18 +24,24 @@ vi.mock('../service', () => {
|
|
|
24
24
|
thorService: mockAxios.default.create(),
|
|
25
25
|
};
|
|
26
26
|
});
|
|
27
|
-
describe('
|
|
27
|
+
describe('getOutboundFeeSellAssetThorBaseUnit', () => {
|
|
28
28
|
it('should return 0.02 rune denominated in the target asset, in thor units', () => {
|
|
29
29
|
const assetPricePrecision = '4.00000'; // 1 token is 4x as valuable as 1 rune
|
|
30
|
-
expect(
|
|
30
|
+
expect(getOutboundFeeSellAssetThorBaseUnit(assetPricePrecision, ETH.assetId, SwapperName.Thorchain).toNumber()).toEqual(Number(thorchain.NATIVE_FEE) / 4);
|
|
31
|
+
});
|
|
32
|
+
it('should scale CACAO 10-dec native fee down to non-CACAO 8-dec sell asset precision on MAYA', () => {
|
|
33
|
+
// 1 eth = 100 cacao, NATIVE_FEE = 2e9 (10-dec CACAO = 0.2 CACAO)
|
|
34
|
+
// 0.2 CACAO / 100 (CACAO/ETH) = 0.002 ETH = 200_000 at 8-dec ETH
|
|
35
|
+
const assetPrice = '100';
|
|
36
|
+
expect(getOutboundFeeSellAssetThorBaseUnit(assetPrice, ETH.assetId, SwapperName.Mayachain).toNumber()).toEqual(200_000);
|
|
31
37
|
});
|
|
32
38
|
});
|
|
33
|
-
describe('
|
|
39
|
+
describe('getExpectedAffiliateFeeSellAssetThorBaseUnit', () => {
|
|
34
40
|
it('should return the correct affiliate fee in thor base units', () => {
|
|
35
41
|
const sellAmountCryptoBaseUnit = '1000000000000000000'; // 1 eth
|
|
36
42
|
const affiliateBps = '35';
|
|
37
43
|
const sellAsset = ETH;
|
|
38
|
-
const result =
|
|
44
|
+
const result = getExpectedAffiliateFeeSellAssetThorBaseUnit(sellAmountCryptoBaseUnit, sellAsset, affiliateBps, SwapperName.Thorchain);
|
|
39
45
|
const expectation = bn('100000000').times('0.0035').toFixed(0);
|
|
40
46
|
expect(result.toFixed(0)).toEqual(expectation);
|
|
41
47
|
});
|
|
@@ -43,7 +49,7 @@ describe('getExpectedAffiliateFeeSellAssetThorUnit', () => {
|
|
|
43
49
|
const sellAmountCryptoBaseUnit = '1000000000000000000'; // 1 eth
|
|
44
50
|
const affiliateBps = '0';
|
|
45
51
|
const sellAsset = ETH;
|
|
46
|
-
const result =
|
|
52
|
+
const result = getExpectedAffiliateFeeSellAssetThorBaseUnit(sellAmountCryptoBaseUnit, sellAsset, affiliateBps, SwapperName.Thorchain);
|
|
47
53
|
const expectation = '0';
|
|
48
54
|
expect(result.toFixed(0)).toEqual(expectation);
|
|
49
55
|
});
|
|
@@ -23,6 +23,7 @@ export declare const getDaemonUrl: (config: SwapperConfig, swapperName: SwapperN
|
|
|
23
23
|
export declare const getMidgardUrl: (config: SwapperConfig, swapperName: SwapperName) => string;
|
|
24
24
|
export declare const isNativeAsset: (assetId: AssetId, swapperName: SwapperName) => boolean;
|
|
25
25
|
export declare const getNativePrecision: (assetId: AssetId, swapperName: SwapperName) => 8 | 10;
|
|
26
|
+
export declare const getSwapperNativeAssetId: (swapperName: SwapperName) => AssetId;
|
|
26
27
|
export declare const getNativeFee: (swapperName: SwapperName) => "2000000" | "2000000000";
|
|
27
28
|
export declare const getAffiliate: (swapperName: SwapperName) => "ss" | "ssmaya";
|
|
28
29
|
export declare const getPoolAssetId: ({ assetId, swapperName, }: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mayachainAssetId, mayachainChainId, thorchainChainId } from '@shapeshiftoss/caip';
|
|
1
|
+
import { mayachainAssetId, mayachainChainId, thorchainAssetId, thorchainChainId, } from '@shapeshiftoss/caip';
|
|
2
2
|
import * as adapters from '@shapeshiftoss/chain-adapters';
|
|
3
3
|
import { assetIdToMayaPoolAssetId, CACAO_PRECISION, isCacao, MAYACHAIN_AFFILIATE_NAME, MAYACHAIN_PRECISION, MAYACHAIN_STREAM_SWAP_SOURCE, } from '../swappers/MayachainSwapper/index.js';
|
|
4
4
|
import { assetIdToThorPoolAssetId, isRune, THORCHAIN_AFFILIATE_NAME, THORCHAIN_LONGTAIL_STREAMING_SWAP_SOURCE, THORCHAIN_LONGTAIL_SWAP_SOURCE, THORCHAIN_PRECISION, THORCHAIN_STREAM_SWAP_SOURCE, } from '../swappers/ThorchainSwapper/index.js';
|
|
@@ -69,6 +69,16 @@ export const getNativePrecision = (assetId, swapperName) => {
|
|
|
69
69
|
throw new Error(`Invalid swapper: ${swapperName}`);
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
|
+
export const getSwapperNativeAssetId = (swapperName) => {
|
|
73
|
+
switch (swapperName) {
|
|
74
|
+
case SwapperName.Thorchain:
|
|
75
|
+
return thorchainAssetId;
|
|
76
|
+
case SwapperName.Mayachain:
|
|
77
|
+
return mayachainAssetId;
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`Invalid swapper: ${swapperName}`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
72
82
|
export const getNativeFee = (swapperName) => {
|
|
73
83
|
switch (swapperName) {
|
|
74
84
|
case SwapperName.Thorchain:
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -327,6 +327,12 @@ export type TradeQuoteStep = {
|
|
|
327
327
|
thorchainSpecific?: {
|
|
328
328
|
maxStreamingQuantity?: number;
|
|
329
329
|
};
|
|
330
|
+
thorchainTransactionMetadata?: {
|
|
331
|
+
to: string;
|
|
332
|
+
data?: string;
|
|
333
|
+
value?: string;
|
|
334
|
+
memo?: string;
|
|
335
|
+
};
|
|
330
336
|
relayTransactionMetadata?: RelayTransactionMetadata;
|
|
331
337
|
butterSwapTransactionMetadata?: {
|
|
332
338
|
to: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshiftoss/swapper",
|
|
3
|
-
"version": "17.7.
|
|
3
|
+
"version": "17.7.3",
|
|
4
4
|
"repository": "https://github.com/shapeshift/web",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"@shapeshiftoss/caip": "^8.16.7",
|
|
53
53
|
"@shapeshiftoss/chain-adapters": "^11.3.9",
|
|
54
54
|
"@shapeshiftoss/contracts": "^1.0.5-coderabbit-fix.2",
|
|
55
|
-
"@shapeshiftoss/hdwallet-core": "^1.62.41",
|
|
56
55
|
"@shapeshiftoss/types": "^8.6.7",
|
|
56
|
+
"@shapeshiftoss/hdwallet-core": "^1.62.41",
|
|
57
57
|
"@shapeshiftoss/unchained-client": "^10.14.10",
|
|
58
58
|
"@shapeshiftoss/utils": "^1.0.5"
|
|
59
59
|
},
|