@shapeshiftoss/swapper 9.3.2 → 9.6.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/api.d.ts +5 -1
- package/dist/api.js +1 -0
- package/dist/swappers/thorchain/ThorchainSwapper.d.ts +4 -2
- package/dist/swappers/thorchain/ThorchainSwapper.js +62 -14
- package/dist/swappers/thorchain/buildThorTrade/buildThorTrade.js +21 -0
- package/dist/swappers/thorchain/getThorTradeQuote/getTradeQuote.js +15 -2
- package/dist/swappers/thorchain/types.d.ts +20 -2
- package/dist/swappers/thorchain/utils/bitcoin/utils/getThorTxData.js +11 -17
- package/dist/swappers/thorchain/utils/constants.d.ts +3 -2
- package/dist/swappers/thorchain/utils/constants.js +16 -4
- package/dist/swappers/thorchain/utils/cosmos/cosmosTxData.d.ts +19 -0
- package/dist/swappers/thorchain/utils/cosmos/cosmosTxData.js +46 -0
- package/dist/swappers/thorchain/utils/estimateTradeFee/estimateTradeFee.js +8 -43
- package/dist/swappers/thorchain/utils/ethereum/utils/getThorTxData.js +11 -17
- package/dist/swappers/thorchain/utils/getLimit/getLimit.d.ts +12 -0
- package/dist/swappers/thorchain/utils/getLimit/getLimit.js +24 -0
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -42,6 +42,9 @@ declare type ChainSpecificQuoteFeeData<T extends ChainId> = ChainSpecific<T, {
|
|
|
42
42
|
byteCount: string;
|
|
43
43
|
satsPerByte: string;
|
|
44
44
|
};
|
|
45
|
+
[KnownChainIds.CosmosMainnet]: {
|
|
46
|
+
estimatedGas: string;
|
|
47
|
+
};
|
|
45
48
|
}>;
|
|
46
49
|
export declare type QuoteFeeData<T extends ChainId> = {
|
|
47
50
|
fee: string;
|
|
@@ -165,7 +168,8 @@ export declare enum SwapErrorTypes {
|
|
|
165
168
|
MAKE_MEMO_FAILED = "MAKE_MEMO_FAILED",
|
|
166
169
|
PRICE_RATIO_FAILED = "PRICE_RATIO_FAILED",
|
|
167
170
|
POOL_NOT_FOUND = "POOL_NOT_FOUND",
|
|
168
|
-
GET_TRADE_TXS_FAILED = "GET_TRADE_TXS_FAILED"
|
|
171
|
+
GET_TRADE_TXS_FAILED = "GET_TRADE_TXS_FAILED",
|
|
172
|
+
TRADE_FAILED = "TRADE_FAILED"
|
|
169
173
|
}
|
|
170
174
|
export interface Swapper<T extends ChainId> {
|
|
171
175
|
/** Human readable swapper name */
|
package/dist/api.js
CHANGED
|
@@ -37,4 +37,5 @@ var SwapErrorTypes;
|
|
|
37
37
|
SwapErrorTypes["PRICE_RATIO_FAILED"] = "PRICE_RATIO_FAILED";
|
|
38
38
|
SwapErrorTypes["POOL_NOT_FOUND"] = "POOL_NOT_FOUND";
|
|
39
39
|
SwapErrorTypes["GET_TRADE_TXS_FAILED"] = "GET_TRADE_TXS_FAILED";
|
|
40
|
+
SwapErrorTypes["TRADE_FAILED"] = "TRADE_FAILED";
|
|
40
41
|
})(SwapErrorTypes = exports.SwapErrorTypes || (exports.SwapErrorTypes = {}));
|
|
@@ -5,8 +5,10 @@ import { ApprovalNeededInput, ApprovalNeededOutput, ApproveInfiniteInput, BuildT
|
|
|
5
5
|
import { ThorchainSwapperDeps } from './types';
|
|
6
6
|
export declare class ThorchainSwapper implements Swapper<ChainId> {
|
|
7
7
|
readonly name = "Thorchain";
|
|
8
|
-
private
|
|
9
|
-
private
|
|
8
|
+
private sellSupportedChainIds;
|
|
9
|
+
private buySupportedChainIds;
|
|
10
|
+
private supportedSellAssetIds;
|
|
11
|
+
private supportedBuyAssetIds;
|
|
10
12
|
deps: ThorchainSwapperDeps;
|
|
11
13
|
constructor(deps: ThorchainSwapperDeps);
|
|
12
14
|
initialize(): Promise<void>;
|
|
@@ -13,24 +13,40 @@ const thorService_1 = require("./utils/thorService");
|
|
|
13
13
|
class ThorchainSwapper {
|
|
14
14
|
constructor(deps) {
|
|
15
15
|
this.name = 'Thorchain';
|
|
16
|
-
this.
|
|
16
|
+
this.sellSupportedChainIds = {
|
|
17
17
|
[types_1.KnownChainIds.EthereumMainnet]: true,
|
|
18
|
-
[types_1.KnownChainIds.BitcoinMainnet]: true
|
|
18
|
+
[types_1.KnownChainIds.BitcoinMainnet]: true,
|
|
19
|
+
[types_1.KnownChainIds.CosmosMainnet]: true
|
|
19
20
|
};
|
|
20
|
-
this.
|
|
21
|
+
this.buySupportedChainIds = {
|
|
22
|
+
[types_1.KnownChainIds.EthereumMainnet]: true,
|
|
23
|
+
[types_1.KnownChainIds.BitcoinMainnet]: true,
|
|
24
|
+
[types_1.KnownChainIds.DogecoinMainnet]: true,
|
|
25
|
+
[types_1.KnownChainIds.LitecoinMainnet]: true,
|
|
26
|
+
[types_1.KnownChainIds.BitcoinCashMainnet]: true,
|
|
27
|
+
[types_1.KnownChainIds.CosmosMainnet]: true
|
|
28
|
+
};
|
|
29
|
+
this.supportedSellAssetIds = [];
|
|
30
|
+
this.supportedBuyAssetIds = [];
|
|
21
31
|
this.deps = deps;
|
|
22
32
|
}
|
|
23
33
|
async initialize() {
|
|
24
34
|
try {
|
|
25
35
|
const { data: responseData } = await thorService_1.thorService.get(`${this.deps.midgardUrl}/pools`);
|
|
26
|
-
|
|
36
|
+
this.supportedSellAssetIds = responseData.reduce((acc, midgardPool) => {
|
|
37
|
+
const assetId = caip_1.adapters.poolAssetIdToAssetId(midgardPool.asset);
|
|
38
|
+
if (!assetId || !this.sellSupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
|
|
39
|
+
return acc;
|
|
40
|
+
acc.push(assetId);
|
|
41
|
+
return acc;
|
|
42
|
+
}, []);
|
|
43
|
+
this.supportedBuyAssetIds = responseData.reduce((acc, midgardPool) => {
|
|
27
44
|
const assetId = caip_1.adapters.poolAssetIdToAssetId(midgardPool.asset);
|
|
28
|
-
if (!assetId || !this.
|
|
45
|
+
if (!assetId || !this.buySupportedChainIds[(0, caip_1.fromAssetId)(assetId).chainId])
|
|
29
46
|
return acc;
|
|
30
47
|
acc.push(assetId);
|
|
31
48
|
return acc;
|
|
32
49
|
}, []);
|
|
33
|
-
this.supportedAssetIds = supportedAssetIds;
|
|
34
50
|
}
|
|
35
51
|
catch (e) {
|
|
36
52
|
throw new api_1.SwapError('[thorchainInitialize]: initialize failed to set supportedAssetIds', {
|
|
@@ -53,12 +69,12 @@ class ThorchainSwapper {
|
|
|
53
69
|
}
|
|
54
70
|
filterBuyAssetsBySellAssetId(args) {
|
|
55
71
|
const { assetIds = [], sellAssetId } = args;
|
|
56
|
-
if (!this.
|
|
72
|
+
if (!this.supportedSellAssetIds.includes(sellAssetId))
|
|
57
73
|
return [];
|
|
58
|
-
return assetIds.filter((assetId) => this.
|
|
74
|
+
return assetIds.filter((assetId) => this.supportedBuyAssetIds.includes(assetId) && assetId !== sellAssetId);
|
|
59
75
|
}
|
|
60
76
|
filterAssetIdsBySellable() {
|
|
61
|
-
return this.
|
|
77
|
+
return this.supportedSellAssetIds;
|
|
62
78
|
}
|
|
63
79
|
async buildTrade(input) {
|
|
64
80
|
return (0, buildThorTrade_1.buildTrade)({ deps: this.deps, input });
|
|
@@ -92,6 +108,14 @@ class ThorchainSwapper {
|
|
|
92
108
|
const txid = await adapter.broadcastTransaction(signedTx);
|
|
93
109
|
return { tradeId: txid };
|
|
94
110
|
}
|
|
111
|
+
else if (trade.sellAsset.chainId === types_1.KnownChainIds.CosmosMainnet) {
|
|
112
|
+
const signedTx = await adapter.signTransaction({
|
|
113
|
+
txToSign: trade.txData,
|
|
114
|
+
wallet
|
|
115
|
+
});
|
|
116
|
+
const txid = await adapter.broadcastTransaction(signedTx);
|
|
117
|
+
return { tradeId: txid };
|
|
118
|
+
}
|
|
95
119
|
else {
|
|
96
120
|
throw new api_1.SwapError('[executeTrade]: unsupported trade', {
|
|
97
121
|
code: api_1.SwapErrorTypes.SIGN_AND_BROADCAST_FAILED,
|
|
@@ -109,11 +133,35 @@ class ThorchainSwapper {
|
|
|
109
133
|
}
|
|
110
134
|
}
|
|
111
135
|
async getTradeTxs(tradeResult) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
var _a, _b, _c, _d;
|
|
137
|
+
try {
|
|
138
|
+
const midgardTxid = tradeResult.tradeId.startsWith('0x')
|
|
139
|
+
? tradeResult.tradeId.slice(2)
|
|
140
|
+
: tradeResult.tradeId;
|
|
141
|
+
const { data: responseData } = await thorService_1.thorService.get(`${this.deps.midgardUrl}/actions?txid=${midgardTxid}`);
|
|
142
|
+
const buyTxid = ((_a = responseData === null || responseData === void 0 ? void 0 : responseData.actions[0]) === null || _a === void 0 ? void 0 : _a.status) === 'success' && ((_b = responseData === null || responseData === void 0 ? void 0 : responseData.actions[0]) === null || _b === void 0 ? void 0 : _b.type) === 'swap'
|
|
143
|
+
? responseData === null || responseData === void 0 ? void 0 : responseData.actions[0].out[0].txID
|
|
144
|
+
: '';
|
|
145
|
+
// This will detect all the errors I have seen.
|
|
146
|
+
if (((_c = responseData === null || responseData === void 0 ? void 0 : responseData.actions[0]) === null || _c === void 0 ? void 0 : _c.status) === 'success' &&
|
|
147
|
+
((_d = responseData === null || responseData === void 0 ? void 0 : responseData.actions[0]) === null || _d === void 0 ? void 0 : _d.type) !== 'swap')
|
|
148
|
+
throw new api_1.SwapError('[getTradeTxs]: trade failed', {
|
|
149
|
+
code: api_1.SwapErrorTypes.TRADE_FAILED,
|
|
150
|
+
cause: responseData
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
sellTxid: tradeResult.tradeId,
|
|
154
|
+
buyTxid: buyTxid.toLowerCase()
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
if (e instanceof api_1.SwapError)
|
|
159
|
+
throw e;
|
|
160
|
+
throw new api_1.SwapError('[getTradeTxs]: error', {
|
|
161
|
+
code: api_1.SwapErrorTypes.GET_TRADE_TXS_FAILED,
|
|
162
|
+
cause: e
|
|
163
|
+
});
|
|
164
|
+
}
|
|
117
165
|
}
|
|
118
166
|
}
|
|
119
167
|
exports.ThorchainSwapper = ThorchainSwapper;
|
|
@@ -6,6 +6,7 @@ const api_1 = require("../../../api");
|
|
|
6
6
|
const constants_1 = require("../../utils/constants");
|
|
7
7
|
const getTradeQuote_1 = require("../getThorTradeQuote/getTradeQuote");
|
|
8
8
|
const getThorTxData_1 = require("../utils/bitcoin/utils/getThorTxData");
|
|
9
|
+
const cosmosTxData_1 = require("../utils/cosmos/cosmosTxData");
|
|
9
10
|
const makeTradeTx_1 = require("../utils/ethereum/makeTradeTx");
|
|
10
11
|
const buildTrade = async ({ deps, input }) => {
|
|
11
12
|
var _a, _b, _c, _d;
|
|
@@ -75,6 +76,26 @@ const buildTrade = async ({ deps, input }) => {
|
|
|
75
76
|
txData: buildTxResponse.txToSign
|
|
76
77
|
};
|
|
77
78
|
}
|
|
79
|
+
else if (input.chainId === types_1.KnownChainIds.CosmosMainnet) {
|
|
80
|
+
const txData = await (0, cosmosTxData_1.cosmosTxData)({
|
|
81
|
+
deps,
|
|
82
|
+
sellAdapter: sellAdapter,
|
|
83
|
+
sellAmount,
|
|
84
|
+
sellAsset,
|
|
85
|
+
slippageTolerance,
|
|
86
|
+
chainId: input.chainId,
|
|
87
|
+
buyAsset,
|
|
88
|
+
wallet,
|
|
89
|
+
destinationAddress,
|
|
90
|
+
quote: quote
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
chainId: types_1.KnownChainIds.CosmosMainnet,
|
|
94
|
+
...quote,
|
|
95
|
+
receiveAddress: destinationAddress,
|
|
96
|
+
txData
|
|
97
|
+
};
|
|
98
|
+
}
|
|
78
99
|
else {
|
|
79
100
|
throw new api_1.SwapError('[buildTrade]: unsupported chain id', {
|
|
80
101
|
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
@@ -21,8 +21,8 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
21
21
|
});
|
|
22
22
|
try {
|
|
23
23
|
const { assetReference: sellAssetErc20Address } = (0, caip_1.fromAssetId)(sellAsset.assetId);
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
24
|
+
const sellAdapter = deps.adapterManager.get(chainId);
|
|
25
|
+
if (!sellAdapter)
|
|
26
26
|
throw new api_1.SwapError(`[getThorTradeQuote] - No chain adapter found for ${chainId}.`, {
|
|
27
27
|
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
28
28
|
details: { chainId }
|
|
@@ -97,6 +97,19 @@ const getThorTradeQuote = async ({ deps, input }) => {
|
|
|
97
97
|
feeData
|
|
98
98
|
};
|
|
99
99
|
})();
|
|
100
|
+
case types_1.KnownChainIds.CosmosMainnet:
|
|
101
|
+
return (async () => {
|
|
102
|
+
const feeData = await sellAdapter.getFeeData({});
|
|
103
|
+
return {
|
|
104
|
+
...commonQuoteFields,
|
|
105
|
+
allowanceContract: '0x0',
|
|
106
|
+
feeData: {
|
|
107
|
+
fee: feeData.fast.txFee,
|
|
108
|
+
tradeFee,
|
|
109
|
+
chainSpecific: { estimatedGas: feeData.fast.chainSpecific.gasLimit }
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
})();
|
|
100
113
|
default:
|
|
101
114
|
throw new api_1.SwapError('[getThorTradeQuote] - Asset chainId is not supported.', {
|
|
102
115
|
code: api_1.SwapErrorTypes.UNSUPPORTED_CHAIN,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ChainId } from '@shapeshiftoss/caip';
|
|
2
2
|
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
3
|
-
import { BTCSignTx, ETHSignTx } from '@shapeshiftoss/hdwallet-core';
|
|
3
|
+
import { BTCSignTx, CosmosSignTx, ETHSignTx } from '@shapeshiftoss/hdwallet-core';
|
|
4
4
|
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
5
5
|
import type Web3 from 'web3';
|
|
6
6
|
import { Trade } from '../../api';
|
|
@@ -18,6 +18,19 @@ export declare type PoolResponse = {
|
|
|
18
18
|
units: string;
|
|
19
19
|
volume24h: string;
|
|
20
20
|
};
|
|
21
|
+
declare type MidgardActionOut = {
|
|
22
|
+
txID: string;
|
|
23
|
+
};
|
|
24
|
+
declare type MidgardAction = {
|
|
25
|
+
date: string;
|
|
26
|
+
height: string;
|
|
27
|
+
out: MidgardActionOut[];
|
|
28
|
+
status: string;
|
|
29
|
+
type: string;
|
|
30
|
+
};
|
|
31
|
+
export declare type MidgardActionsResponse = {
|
|
32
|
+
actions: MidgardAction[];
|
|
33
|
+
};
|
|
21
34
|
export declare type InboundResponse = {
|
|
22
35
|
chain: string;
|
|
23
36
|
pub_key: string;
|
|
@@ -39,4 +52,9 @@ export interface EthThorTrade<C extends ChainId> extends Trade<C> {
|
|
|
39
52
|
chainId: KnownChainIds.EthereumMainnet;
|
|
40
53
|
txData: ETHSignTx;
|
|
41
54
|
}
|
|
42
|
-
export
|
|
55
|
+
export interface CosmosThorTrade<C extends ChainId> extends Trade<C> {
|
|
56
|
+
chainId: KnownChainIds.CosmosMainnet;
|
|
57
|
+
txData: CosmosSignTx;
|
|
58
|
+
}
|
|
59
|
+
export declare type ThorTrade<C extends ChainId> = BtcThorTrade<C> | EthThorTrade<C> | CosmosThorTrade<C>;
|
|
60
|
+
export {};
|
|
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getThorTxInfo = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../../../api");
|
|
6
|
-
const
|
|
7
|
-
const constants_1 = require("../../constants");
|
|
8
|
-
const getTradeRate_1 = require("../../getTradeRate/getTradeRate");
|
|
6
|
+
const getLimit_1 = require("../../getLimit/getLimit");
|
|
9
7
|
const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
|
|
10
8
|
const thorService_1 = require("../../thorService");
|
|
11
9
|
const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTolerance, destinationAddress, wallet, bip44Params, accountType, tradeFee }) => {
|
|
@@ -18,20 +16,16 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
|
|
|
18
16
|
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
19
17
|
details: { inboundAddresses }
|
|
20
18
|
});
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
32
|
-
.minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
|
|
33
|
-
.decimalPlaces(0)
|
|
34
|
-
.toString();
|
|
19
|
+
const limit = await (0, getLimit_1.getLimit)({
|
|
20
|
+
buyAssetId: buyAsset.assetId,
|
|
21
|
+
destinationAddress,
|
|
22
|
+
sellAmount,
|
|
23
|
+
sellAsset,
|
|
24
|
+
buyAsset,
|
|
25
|
+
slippageTolerance,
|
|
26
|
+
deps,
|
|
27
|
+
tradeFee
|
|
28
|
+
});
|
|
35
29
|
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
36
30
|
buyAssetId: buyAsset.assetId,
|
|
37
31
|
destinationAddress,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import BigNumber from 'bignumber.js';
|
|
1
3
|
export declare const MAX_THORCHAIN_TRADE = "100000000000000000000000000";
|
|
2
4
|
export declare const MAX_ALLOWANCE = "100000000000000000000000000";
|
|
3
5
|
export declare const THOR_MINIMUM_PADDING = 1.2;
|
|
@@ -5,5 +7,4 @@ export declare const THOR_ETH_GAS_LIMIT = "100000";
|
|
|
5
7
|
export declare const THORCHAIN_FIXED_PRECISION = 8;
|
|
6
8
|
export declare const THORCHAIN_AFFILIATE_NAME = "ss";
|
|
7
9
|
export declare const THORCHAIN_AFFILIATE_BIPS = "0";
|
|
8
|
-
export declare const
|
|
9
|
-
export declare const THOR_TRADE_FEE_ETH_GAS = 120000;
|
|
10
|
+
export declare const THOR_TRADE_FEE_MULTIPLIERS: Record<ChainId, BigNumber>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.THOR_TRADE_FEE_MULTIPLIERS = exports.THORCHAIN_AFFILIATE_BIPS = exports.THORCHAIN_AFFILIATE_NAME = exports.THORCHAIN_FIXED_PRECISION = exports.THOR_ETH_GAS_LIMIT = exports.THOR_MINIMUM_PADDING = exports.MAX_ALLOWANCE = exports.MAX_THORCHAIN_TRADE = void 0;
|
|
4
|
+
const types_1 = require("@shapeshiftoss/types");
|
|
5
|
+
const bignumber_1 = require("../../utils/bignumber");
|
|
4
6
|
exports.MAX_THORCHAIN_TRADE = '100000000000000000000000000';
|
|
5
7
|
exports.MAX_ALLOWANCE = '100000000000000000000000000';
|
|
6
8
|
exports.THOR_MINIMUM_PADDING = 1.2;
|
|
@@ -8,7 +10,17 @@ exports.THOR_ETH_GAS_LIMIT = '100000'; // for sends of eth / erc20 into thorchai
|
|
|
8
10
|
exports.THORCHAIN_FIXED_PRECISION = 8; // limit values are precision 8 regardless of the chain
|
|
9
11
|
exports.THORCHAIN_AFFILIATE_NAME = 'ss';
|
|
10
12
|
exports.THORCHAIN_AFFILIATE_BIPS = '0'; // affiliate fee in basis points (100 = 1%)
|
|
11
|
-
// These are different from THOR_ETH_GAS_LIMIT
|
|
12
13
|
// Used to estimate the fee thorchain will take out of the buyAsset
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
// Official docs on fees are incorrect
|
|
15
|
+
// https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
|
|
16
|
+
// This is still not "perfect" and tends to overestimate by a small randomish amount
|
|
17
|
+
// TODO figure out if its possible to accurately estimate the outbound fee.
|
|
18
|
+
// Neither the discord nor official docs are correct
|
|
19
|
+
exports.THOR_TRADE_FEE_MULTIPLIERS = {
|
|
20
|
+
[types_1.KnownChainIds.BitcoinMainnet]: (0, bignumber_1.bn)(0.00002),
|
|
21
|
+
[types_1.KnownChainIds.DogecoinMainnet]: (0, bignumber_1.bn)(0.00002),
|
|
22
|
+
[types_1.KnownChainIds.LitecoinMainnet]: (0, bignumber_1.bn)(0.000005),
|
|
23
|
+
[types_1.KnownChainIds.BitcoinCashMainnet]: (0, bignumber_1.bn)(0.00003),
|
|
24
|
+
[types_1.KnownChainIds.CosmosMainnet]: (0, bignumber_1.bn)(0.00000002),
|
|
25
|
+
[types_1.KnownChainIds.EthereumMainnet]: (0, bignumber_1.bn)(0.00024) // A value that "works". Discord recommended value (80,000 gas * 2 or 160k) is often too low
|
|
26
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
|
+
import { ChainId } from '@shapeshiftoss/caip';
|
|
3
|
+
import { ChainAdapter } from '@shapeshiftoss/chain-adapters';
|
|
4
|
+
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
5
|
+
import { KnownChainIds } from '@shapeshiftoss/types';
|
|
6
|
+
import { TradeQuote } from '../../../../api';
|
|
7
|
+
import { ThorchainSwapperDeps } from '../../types';
|
|
8
|
+
export declare const cosmosTxData: (input: {
|
|
9
|
+
destinationAddress: string;
|
|
10
|
+
deps: ThorchainSwapperDeps;
|
|
11
|
+
sellAmount: string;
|
|
12
|
+
sellAsset: Asset;
|
|
13
|
+
buyAsset: Asset;
|
|
14
|
+
slippageTolerance: string;
|
|
15
|
+
wallet: HDWallet;
|
|
16
|
+
quote: TradeQuote<KnownChainIds.CosmosMainnet>;
|
|
17
|
+
chainId: ChainId;
|
|
18
|
+
sellAdapter: ChainAdapter<KnownChainIds.CosmosMainnet>;
|
|
19
|
+
}) => Promise<import("@shapeshiftoss/hdwallet-core").CosmosSignTx>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cosmosTxData = void 0;
|
|
4
|
+
const api_1 = require("../../../../api");
|
|
5
|
+
const getLimit_1 = require("../getLimit/getLimit");
|
|
6
|
+
const makeSwapMemo_1 = require("../makeSwapMemo/makeSwapMemo");
|
|
7
|
+
const thorService_1 = require("../thorService");
|
|
8
|
+
const cosmosTxData = async (input) => {
|
|
9
|
+
const { deps, destinationAddress, sellAmount, sellAsset, buyAsset, slippageTolerance, quote, wallet, sellAdapter } = input;
|
|
10
|
+
const { data: inboundAddresses } = await thorService_1.thorService.get(`${deps.midgardUrl}/thorchain/inbound_addresses`);
|
|
11
|
+
const atomInboundAddresses = inboundAddresses.find((inbound) => inbound.chain === 'GAIA');
|
|
12
|
+
const vault = atomInboundAddresses === null || atomInboundAddresses === void 0 ? void 0 : atomInboundAddresses.address;
|
|
13
|
+
if (!vault)
|
|
14
|
+
throw new api_1.SwapError('[buildTrade]: no vault for chain', {
|
|
15
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
16
|
+
fn: 'buildTrade',
|
|
17
|
+
details: { chainId: input.chainId }
|
|
18
|
+
});
|
|
19
|
+
const limit = await (0, getLimit_1.getLimit)({
|
|
20
|
+
buyAssetId: buyAsset.assetId,
|
|
21
|
+
destinationAddress,
|
|
22
|
+
sellAmount,
|
|
23
|
+
sellAsset,
|
|
24
|
+
buyAsset,
|
|
25
|
+
slippageTolerance,
|
|
26
|
+
deps,
|
|
27
|
+
tradeFee: quote.feeData.tradeFee
|
|
28
|
+
});
|
|
29
|
+
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
30
|
+
buyAssetId: buyAsset.assetId,
|
|
31
|
+
destinationAddress,
|
|
32
|
+
limit
|
|
33
|
+
});
|
|
34
|
+
const buildTxResponse = await sellAdapter.buildSendTransaction({
|
|
35
|
+
value: sellAmount,
|
|
36
|
+
wallet,
|
|
37
|
+
to: vault,
|
|
38
|
+
memo,
|
|
39
|
+
chainSpecific: {
|
|
40
|
+
gas: quote.feeData.chainSpecific.estimatedGas,
|
|
41
|
+
fee: quote.feeData.fee
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
return buildTxResponse.txToSign;
|
|
45
|
+
};
|
|
46
|
+
exports.cosmosTxData = cosmosTxData;
|
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.estimateTradeFee = void 0;
|
|
4
|
-
const asset_service_1 = require("@shapeshiftoss/asset-service");
|
|
5
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
6
5
|
const api_1 = require("../../../../api");
|
|
7
|
-
const bignumber_1 = require("../../../utils/bignumber");
|
|
8
6
|
const constants_1 = require("../constants");
|
|
9
7
|
const getPriceRatio_1 = require("../getPriceRatio/getPriceRatio");
|
|
10
8
|
const thorService_1 = require("../thorService");
|
|
11
|
-
const gweiGasPrecision = 9;
|
|
12
|
-
// Official docs on fees are incorrect
|
|
13
|
-
// https://discord.com/channels/838986635756044328/997675038675316776/998552541170253834
|
|
14
|
-
// This is still not "perfect" and tends to overestimate by a randomish amount
|
|
15
|
-
// TODO figure out if its possible to accurately estimate the outbound fee.
|
|
16
|
-
// Neither the discord nor official docs are correct
|
|
17
|
-
const ethEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
|
|
18
|
-
.times(constants_1.THOR_TRADE_FEE_ETH_GAS)
|
|
19
|
-
.times(2)
|
|
20
|
-
.times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
|
|
21
|
-
.toString();
|
|
22
|
-
const erc20Estimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate)
|
|
23
|
-
.times(constants_1.THOR_TRADE_FEE_ETH_GAS)
|
|
24
|
-
.times(2)
|
|
25
|
-
.times((0, bignumber_1.bn)(10).exponentiatedBy(gweiGasPrecision))
|
|
26
|
-
.toString();
|
|
27
|
-
const btcEstimate = (gasRate) => (0, bignumber_1.bnOrZero)(gasRate).times(constants_1.THOR_TRADE_FEE_BTC_SIZE).times(2).toString();
|
|
28
9
|
const estimateTradeFee = async (deps, buyAsset) => {
|
|
29
10
|
const thorId = caip_1.adapters.assetIdToPoolAssetId({ assetId: buyAsset.assetId });
|
|
30
11
|
if (!thorId)
|
|
@@ -41,7 +22,7 @@ const estimateTradeFee = async (deps, buyAsset) => {
|
|
|
41
22
|
details: { thorPoolChainId }
|
|
42
23
|
});
|
|
43
24
|
const gasRate = inboundInfo.gas_rate;
|
|
44
|
-
const { chainId: buyChainId
|
|
25
|
+
const { chainId: buyChainId } = (0, caip_1.fromAssetId)(buyAsset.assetId);
|
|
45
26
|
const buyAdapter = deps.adapterManager.get(buyChainId);
|
|
46
27
|
if (!buyAdapter)
|
|
47
28
|
throw new api_1.SwapError('[estimateTradeFee] - unable to get buy asset adapter', {
|
|
@@ -54,33 +35,17 @@ const estimateTradeFee = async (deps, buyAsset) => {
|
|
|
54
35
|
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
55
36
|
details: { buyAssetId: buyAsset.assetId }
|
|
56
37
|
});
|
|
57
|
-
const
|
|
38
|
+
const buyFeeAssetRatio = buyAsset.assetId !== buyFeeAssetId
|
|
58
39
|
? await (0, getPriceRatio_1.getPriceRatio)(deps, {
|
|
59
40
|
sellAssetId: buyAsset.assetId,
|
|
60
41
|
buyAssetId: buyFeeAssetId
|
|
61
42
|
})
|
|
62
43
|
: '1';
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
case 'slip44':
|
|
70
|
-
return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(ethEstimate(gasRate)).times(feeAssetRatio).dp(0), buyFeeAsset.precision);
|
|
71
|
-
case 'erc20':
|
|
72
|
-
return (0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(erc20Estimate(gasRate)).times(feeAssetRatio).dp(0), buyFeeAsset.precision);
|
|
73
|
-
default:
|
|
74
|
-
throw new api_1.SwapError('[estimateTradeFee] - unsupported asset namespace', {
|
|
75
|
-
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
76
|
-
details: { assetNamespace }
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
default:
|
|
80
|
-
throw new api_1.SwapError('[estimateTradeFee] - unsupported chain id', {
|
|
81
|
-
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
82
|
-
details: { chainId: buyChainId }
|
|
83
|
-
});
|
|
84
|
-
}
|
|
44
|
+
if (!constants_1.THOR_TRADE_FEE_MULTIPLIERS[buyChainId])
|
|
45
|
+
throw new api_1.SwapError('[estimateTradeFee] - no trade fee multiplier', {
|
|
46
|
+
code: api_1.SwapErrorTypes.VALIDATION_FAILED,
|
|
47
|
+
details: { buyChainId }
|
|
48
|
+
});
|
|
49
|
+
return constants_1.THOR_TRADE_FEE_MULTIPLIERS[buyChainId].times(buyFeeAssetRatio).times(gasRate).toString();
|
|
85
50
|
};
|
|
86
51
|
exports.estimateTradeFee = estimateTradeFee;
|
|
@@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getThorTxInfo = void 0;
|
|
4
4
|
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
5
|
const api_1 = require("../../../../../api");
|
|
6
|
-
const
|
|
7
|
-
const getTradeRate_1 = require("../../../utils/getTradeRate/getTradeRate");
|
|
8
|
-
const constants_1 = require("../../constants");
|
|
6
|
+
const getLimit_1 = require("../../getLimit/getLimit");
|
|
9
7
|
const makeSwapMemo_1 = require("../../makeSwapMemo/makeSwapMemo");
|
|
10
8
|
const thorService_1 = require("../../thorService");
|
|
11
9
|
const routerCalldata_1 = require("../routerCalldata");
|
|
@@ -22,20 +20,16 @@ const getThorTxInfo = async ({ deps, sellAsset, buyAsset, sellAmount, slippageTo
|
|
|
22
20
|
code: api_1.SwapErrorTypes.RESPONSE_ERROR,
|
|
23
21
|
details: { inboundAddresses }
|
|
24
22
|
});
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
36
|
-
.minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
|
|
37
|
-
.decimalPlaces(0)
|
|
38
|
-
.toString();
|
|
23
|
+
const limit = await (0, getLimit_1.getLimit)({
|
|
24
|
+
buyAssetId: buyAsset.assetId,
|
|
25
|
+
destinationAddress,
|
|
26
|
+
sellAmount,
|
|
27
|
+
sellAsset,
|
|
28
|
+
buyAsset,
|
|
29
|
+
slippageTolerance,
|
|
30
|
+
deps,
|
|
31
|
+
tradeFee
|
|
32
|
+
});
|
|
39
33
|
const memo = (0, makeSwapMemo_1.makeSwapMemo)({
|
|
40
34
|
buyAssetId: buyAsset.assetId,
|
|
41
35
|
destinationAddress,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Asset } from '@shapeshiftoss/asset-service';
|
|
2
|
+
import { ThorchainSwapperDeps } from '../../types';
|
|
3
|
+
export declare const getLimit: ({ sellAsset, buyAsset, sellAmount, deps, slippageTolerance, tradeFee }: {
|
|
4
|
+
buyAssetId: string;
|
|
5
|
+
destinationAddress: string;
|
|
6
|
+
sellAsset: Asset;
|
|
7
|
+
buyAsset: Asset;
|
|
8
|
+
sellAmount: string;
|
|
9
|
+
deps: ThorchainSwapperDeps;
|
|
10
|
+
slippageTolerance: string;
|
|
11
|
+
tradeFee: string;
|
|
12
|
+
}) => Promise<string>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLimit = void 0;
|
|
4
|
+
const api_1 = require("../../../../api");
|
|
5
|
+
const bignumber_1 = require("../../../utils/bignumber");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const getTradeRate_1 = require("../getTradeRate/getTradeRate");
|
|
8
|
+
const getLimit = async ({ sellAsset, buyAsset, sellAmount, deps, slippageTolerance, tradeFee }) => {
|
|
9
|
+
const tradeRate = await (0, getTradeRate_1.getTradeRate)(sellAsset, buyAsset.assetId, sellAmount, deps);
|
|
10
|
+
const expectedBuyAmountPrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.fromBaseUnit)((0, bignumber_1.bnOrZero)(sellAmount).times(tradeRate), sellAsset.precision), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
11
|
+
const isValidSlippageRange = (0, bignumber_1.bnOrZero)(slippageTolerance).gte(0) && (0, bignumber_1.bnOrZero)(slippageTolerance).lte(1);
|
|
12
|
+
if ((0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8).lt(0) || !isValidSlippageRange)
|
|
13
|
+
throw new api_1.SwapError('[getThorTxInfo]: bad expected buy amount or bad slippage tolerance', {
|
|
14
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED,
|
|
15
|
+
details: { expectedBuyAmountPrecision8, slippageTolerance }
|
|
16
|
+
});
|
|
17
|
+
const tradeFeePrecision8 = (0, bignumber_1.toBaseUnit)((0, bignumber_1.bnOrZero)(tradeFee), constants_1.THORCHAIN_FIXED_PRECISION);
|
|
18
|
+
return (0, bignumber_1.bnOrZero)(expectedBuyAmountPrecision8)
|
|
19
|
+
.times((0, bignumber_1.bn)(1).minus(slippageTolerance))
|
|
20
|
+
.minus((0, bignumber_1.bnOrZero)(tradeFeePrecision8))
|
|
21
|
+
.decimalPlaces(0)
|
|
22
|
+
.toString();
|
|
23
|
+
};
|
|
24
|
+
exports.getLimit = getLimit;
|
package/package.json
CHANGED