@shapeshiftoss/swapper 8.3.1 → 8.5.1
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 +8 -2
- package/dist/api.js +1 -0
- package/dist/swappers/index.d.ts +1 -0
- package/dist/swappers/index.js +1 -0
- package/dist/swappers/osmosis/OsmosisSwapper.d.ts +23 -0
- package/dist/swappers/osmosis/OsmosisSwapper.js +207 -0
- package/dist/swappers/osmosis/utils/constants.d.ts +8 -0
- package/dist/swappers/osmosis/utils/constants.js +8 -0
- package/dist/swappers/osmosis/utils/helpers.d.ts +69 -0
- package/dist/swappers/osmosis/utils/helpers.js +282 -0
- package/dist/swappers/osmosis/utils/types.d.ts +22 -0
- package/dist/swappers/osmosis/utils/types.js +2 -0
- package/dist/swappers/thorchain/thorTradeApproveInfinite/thorTradeApproveInfinite.js +17 -6
- package/dist/swappers/zrx/getZrxTradeQuote/getZrxTradeQuote.js +15 -12
- package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.d.ts +1 -0
- package/dist/swappers/zrx/utils/test-data/setupZrxSwapQuote.js +1 -0
- package/dist/swappers/zrx/zrxApproveInfinite/zrxApproveInfinite.js +16 -5
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AssetId, ChainId } from '@shapeshiftoss/caip';
|
|
2
|
-
import { avalanche, ethereum } from '@shapeshiftoss/chain-adapters';
|
|
2
|
+
import { avalanche, cosmos, ethereum, osmosis } from '@shapeshiftoss/chain-adapters';
|
|
3
3
|
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
4
4
|
import { Asset, BIP44Params, ChainSpecific, KnownChainIds, UtxoAccountType } from '@shapeshiftoss/types';
|
|
5
5
|
export declare const SwapError: {
|
|
@@ -67,17 +67,22 @@ declare type CommonTradeInput = {
|
|
|
67
67
|
receiveAddress: string;
|
|
68
68
|
};
|
|
69
69
|
export declare type EvmSupportedChainIds = KnownChainIds.EthereumMainnet | KnownChainIds.AvalancheMainnet;
|
|
70
|
+
export declare type CosmosSdkSupportedChainIds = KnownChainIds.CosmosMainnet | KnownChainIds.OsmosisMainnet;
|
|
70
71
|
export declare type EvmSupportedChainAdapters = ethereum.ChainAdapter | avalanche.ChainAdapter;
|
|
72
|
+
export declare type CosmosSdkSupportedChainAdapters = cosmos.ChainAdapter | osmosis.ChainAdapter;
|
|
71
73
|
export declare type GetEvmTradeQuoteInput = CommonTradeInput & {
|
|
72
74
|
chainId: EvmSupportedChainIds;
|
|
73
75
|
};
|
|
76
|
+
export declare type GetCosmosSdkTradeQuoteInput = CommonTradeInput & {
|
|
77
|
+
chainId: CosmosSdkSupportedChainIds;
|
|
78
|
+
};
|
|
74
79
|
declare type GetBtcTradeQuoteInput = CommonTradeInput & {
|
|
75
80
|
chainId: KnownChainIds.BitcoinMainnet;
|
|
76
81
|
accountType: UtxoAccountType;
|
|
77
82
|
bip44Params: BIP44Params;
|
|
78
83
|
wallet: HDWallet;
|
|
79
84
|
};
|
|
80
|
-
export declare type GetTradeQuoteInput = GetBtcTradeQuoteInput | GetEvmTradeQuoteInput;
|
|
85
|
+
export declare type GetTradeQuoteInput = GetBtcTradeQuoteInput | GetEvmTradeQuoteInput | GetCosmosSdkTradeQuoteInput;
|
|
81
86
|
export declare type BuildTradeInput = GetTradeQuoteInput & {
|
|
82
87
|
buyAssetAccountNumber: number;
|
|
83
88
|
slippage?: string;
|
|
@@ -131,6 +136,7 @@ export declare enum SwapperType {
|
|
|
131
136
|
ZrxEthereum = "0xEthereum",
|
|
132
137
|
ZrxAvalanche = "0xAvalanche",
|
|
133
138
|
Thorchain = "Thorchain",
|
|
139
|
+
Osmosis = "Osmosis",
|
|
134
140
|
CowSwap = "CowSwap",
|
|
135
141
|
Test = "Test"
|
|
136
142
|
}
|
package/dist/api.js
CHANGED
|
@@ -9,6 +9,7 @@ var SwapperType;
|
|
|
9
9
|
SwapperType["ZrxEthereum"] = "0xEthereum";
|
|
10
10
|
SwapperType["ZrxAvalanche"] = "0xAvalanche";
|
|
11
11
|
SwapperType["Thorchain"] = "Thorchain";
|
|
12
|
+
SwapperType["Osmosis"] = "Osmosis";
|
|
12
13
|
SwapperType["CowSwap"] = "CowSwap";
|
|
13
14
|
SwapperType["Test"] = "Test";
|
|
14
15
|
})(SwapperType = exports.SwapperType || (exports.SwapperType = {}));
|
package/dist/swappers/index.d.ts
CHANGED
package/dist/swappers/index.js
CHANGED
|
@@ -17,4 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./zrx/ZrxSwapper"), exports);
|
|
18
18
|
__exportStar(require("./thorchain/ThorchainSwapper"), exports);
|
|
19
19
|
__exportStar(require("./test/TestSwapper"), exports);
|
|
20
|
+
__exportStar(require("./osmosis/OsmosisSwapper"), exports);
|
|
20
21
|
__exportStar(require("./cow/CowSwapper"), exports);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AssetId, ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { Asset } from '@shapeshiftoss/types';
|
|
3
|
+
import { ApprovalNeededOutput, BuildTradeInput, BuyAssetBySellIdInput, ExecuteTradeInput, GetTradeQuoteInput, MinMaxOutput, Swapper, SwapperType, Trade, TradeQuote, TradeResult, TradeTxs } from '../../api';
|
|
4
|
+
import { OsmoSwapperDeps } from './utils/types';
|
|
5
|
+
export declare class OsmosisSwapper implements Swapper<ChainId> {
|
|
6
|
+
readonly name = "Osmosis";
|
|
7
|
+
supportAssets: string[];
|
|
8
|
+
deps: OsmoSwapperDeps;
|
|
9
|
+
getType(): SwapperType;
|
|
10
|
+
constructor(deps: OsmoSwapperDeps);
|
|
11
|
+
getTradeTxs(tradeResult: TradeResult): Promise<TradeTxs>;
|
|
12
|
+
getUsdRate(input: Pick<Asset, 'symbol' | 'assetId'>): Promise<string>;
|
|
13
|
+
getMinMax(input: {
|
|
14
|
+
sellAsset: Asset;
|
|
15
|
+
}): Promise<MinMaxOutput>;
|
|
16
|
+
approvalNeeded(): Promise<ApprovalNeededOutput>;
|
|
17
|
+
approveInfinite(): Promise<string>;
|
|
18
|
+
filterBuyAssetsBySellAssetId(args: BuyAssetBySellIdInput): string[];
|
|
19
|
+
filterAssetIdsBySellable(): AssetId[];
|
|
20
|
+
buildTrade(args: BuildTradeInput): Promise<Trade<ChainId>>;
|
|
21
|
+
getTradeQuote(input: GetTradeQuoteInput): Promise<TradeQuote<ChainId>>;
|
|
22
|
+
executeTrade({ trade, wallet }: ExecuteTradeInput<ChainId>): Promise<TradeResult>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OsmosisSwapper = void 0;
|
|
4
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
5
|
+
const api_1 = require("../../api");
|
|
6
|
+
const bignumber_1 = require("../utils/bignumber");
|
|
7
|
+
const constants_1 = require("./utils/constants");
|
|
8
|
+
const helpers_1 = require("./utils/helpers");
|
|
9
|
+
class OsmosisSwapper {
|
|
10
|
+
constructor(deps) {
|
|
11
|
+
this.name = 'Osmosis';
|
|
12
|
+
this.deps = deps;
|
|
13
|
+
this.supportAssets = [caip_1.cosmosAssetId, caip_1.osmosisAssetId];
|
|
14
|
+
}
|
|
15
|
+
getType() {
|
|
16
|
+
return api_1.SwapperType.Osmosis;
|
|
17
|
+
}
|
|
18
|
+
async getTradeTxs(tradeResult) {
|
|
19
|
+
return {
|
|
20
|
+
sellTxid: tradeResult.tradeId,
|
|
21
|
+
buyTxid: tradeResult.tradeId
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async getUsdRate(input) {
|
|
25
|
+
const { symbol } = input;
|
|
26
|
+
const sellAssetSymbol = symbol;
|
|
27
|
+
const buyAssetSymbol = 'USDC';
|
|
28
|
+
const sellAmount = '1';
|
|
29
|
+
const { rate: osmoRate } = await (0, helpers_1.getRateInfo)('OSMO', buyAssetSymbol, sellAmount, this.deps.osmoUrl);
|
|
30
|
+
if (sellAssetSymbol !== 'OSMO') {
|
|
31
|
+
const { rate } = await (0, helpers_1.getRateInfo)(sellAssetSymbol, 'OSMO', sellAmount, this.deps.osmoUrl);
|
|
32
|
+
return (0, bignumber_1.bnOrZero)(rate).times(osmoRate).toString();
|
|
33
|
+
}
|
|
34
|
+
return osmoRate;
|
|
35
|
+
}
|
|
36
|
+
async getMinMax(input) {
|
|
37
|
+
const { sellAsset } = input;
|
|
38
|
+
const usdRate = await this.getUsdRate({ ...sellAsset });
|
|
39
|
+
const minimum = (0, bignumber_1.bn)(1).dividedBy((0, bignumber_1.bnOrZero)(usdRate)).toString();
|
|
40
|
+
const maximum = constants_1.MAX_SWAPPER_SELL;
|
|
41
|
+
return {
|
|
42
|
+
minimum,
|
|
43
|
+
maximum
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async approvalNeeded() {
|
|
47
|
+
return { approvalNeeded: false };
|
|
48
|
+
}
|
|
49
|
+
async approveInfinite() {
|
|
50
|
+
throw new api_1.SwapError('OsmosisSwapper: approveInfinite unimplemented', {
|
|
51
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
filterBuyAssetsBySellAssetId(args) {
|
|
55
|
+
const { sellAssetId } = args;
|
|
56
|
+
if (!this.supportAssets.includes(sellAssetId))
|
|
57
|
+
return [];
|
|
58
|
+
return this.supportAssets;
|
|
59
|
+
}
|
|
60
|
+
filterAssetIdsBySellable() {
|
|
61
|
+
return this.supportAssets;
|
|
62
|
+
}
|
|
63
|
+
async buildTrade(args) {
|
|
64
|
+
const { sellAsset, buyAsset, sellAmount, receiveAddress } = args;
|
|
65
|
+
if (!sellAmount) {
|
|
66
|
+
throw new api_1.SwapError('sellAmount is required', {
|
|
67
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const { tradeFee, rate, buyAmount } = await (0, helpers_1.getRateInfo)(sellAsset.symbol, buyAsset.symbol, sellAmount !== '0' ? sellAmount : '1', this.deps.osmoUrl);
|
|
71
|
+
//convert amount to base
|
|
72
|
+
const amountBaseSell = String((0, bignumber_1.bnOrZero)(sellAmount).dp(0));
|
|
73
|
+
const osmosisAdapter = this.deps.adapterManager.get(caip_1.osmosisChainId);
|
|
74
|
+
if (!osmosisAdapter)
|
|
75
|
+
throw new api_1.SwapError('Failed to get Osmosis adapter', {
|
|
76
|
+
code: api_1.SwapErrorTypes.BUILD_TRADE_FAILED
|
|
77
|
+
});
|
|
78
|
+
const feeData = await osmosisAdapter.getFeeData({});
|
|
79
|
+
const fee = feeData.average.txFee;
|
|
80
|
+
return {
|
|
81
|
+
buyAmount,
|
|
82
|
+
buyAsset,
|
|
83
|
+
feeData: { fee, tradeFee },
|
|
84
|
+
rate,
|
|
85
|
+
receiveAddress,
|
|
86
|
+
sellAmount: amountBaseSell,
|
|
87
|
+
sellAsset,
|
|
88
|
+
sellAssetAccountNumber: 0,
|
|
89
|
+
sources: [{ name: 'Osmosis', proportion: '100' }]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async getTradeQuote(input) {
|
|
93
|
+
const { sellAsset, buyAsset, sellAmount } = input;
|
|
94
|
+
if (!sellAmount) {
|
|
95
|
+
throw new api_1.SwapError('sellAmount is required', {
|
|
96
|
+
code: api_1.SwapErrorTypes.RESPONSE_ERROR
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const { tradeFee, rate, buyAmount } = await (0, helpers_1.getRateInfo)(sellAsset.symbol, buyAsset.symbol, sellAmount !== '0' ? sellAmount : '1', this.deps.osmoUrl);
|
|
100
|
+
const { minimum, maximum } = await this.getMinMax(input);
|
|
101
|
+
const osmosisAdapter = this.deps.adapterManager.get(caip_1.osmosisChainId);
|
|
102
|
+
if (!osmosisAdapter)
|
|
103
|
+
throw new api_1.SwapError('Failed to get Osmosis adapter', {
|
|
104
|
+
code: api_1.SwapErrorTypes.TRADE_QUOTE_FAILED
|
|
105
|
+
});
|
|
106
|
+
const feeData = await osmosisAdapter.getFeeData({});
|
|
107
|
+
const fee = feeData.average.txFee;
|
|
108
|
+
return {
|
|
109
|
+
buyAsset,
|
|
110
|
+
feeData: { fee, tradeFee },
|
|
111
|
+
maximum,
|
|
112
|
+
minimum,
|
|
113
|
+
sellAssetAccountNumber: 0,
|
|
114
|
+
rate,
|
|
115
|
+
sellAsset,
|
|
116
|
+
sellAmount,
|
|
117
|
+
buyAmount,
|
|
118
|
+
sources: constants_1.DEFAULT_SOURCE,
|
|
119
|
+
allowanceContract: ''
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async executeTrade({ trade, wallet }) {
|
|
123
|
+
const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber, receiveAddress } = trade;
|
|
124
|
+
const isFromOsmo = sellAsset.assetId === caip_1.osmosisAssetId;
|
|
125
|
+
const sellAssetDenom = helpers_1.symbolDenomMapping[sellAsset.symbol];
|
|
126
|
+
const buyAssetDenom = helpers_1.symbolDenomMapping[buyAsset.symbol];
|
|
127
|
+
let ibcSellAmount;
|
|
128
|
+
const osmosisAdapter = this.deps.adapterManager.get(caip_1.osmosisChainId);
|
|
129
|
+
const cosmosAdapter = this.deps.adapterManager.get(caip_1.cosmosChainId);
|
|
130
|
+
if (!cosmosAdapter || !osmosisAdapter) {
|
|
131
|
+
throw new api_1.SwapError('Failed to get adapters', {
|
|
132
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
let sellAddress;
|
|
136
|
+
const feeData = await osmosisAdapter.getFeeData({});
|
|
137
|
+
const gas = feeData.average.chainSpecific.gasLimit;
|
|
138
|
+
if (!isFromOsmo) {
|
|
139
|
+
const sellBip44Params = cosmosAdapter.buildBIP44Params({
|
|
140
|
+
accountNumber: Number(sellAssetAccountNumber)
|
|
141
|
+
});
|
|
142
|
+
sellAddress = await cosmosAdapter.getAddress({ wallet, bip44Params: sellBip44Params });
|
|
143
|
+
if (!sellAddress)
|
|
144
|
+
throw new api_1.SwapError('Failed to get address', {
|
|
145
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
146
|
+
});
|
|
147
|
+
const transfer = {
|
|
148
|
+
sender: sellAddress,
|
|
149
|
+
receiver: receiveAddress,
|
|
150
|
+
amount: sellAmount
|
|
151
|
+
};
|
|
152
|
+
const responseAccount = await cosmosAdapter.getAccount(sellAddress);
|
|
153
|
+
const accountNumber = responseAccount.chainSpecific.accountNumber || '0';
|
|
154
|
+
const sequence = responseAccount.chainSpecific.sequence || '0';
|
|
155
|
+
const { tradeId } = await (0, helpers_1.performIbcTransfer)(transfer, cosmosAdapter, wallet, this.deps.osmoUrl, 'uatom', constants_1.COSMO_OSMO_CHANNEL, '0', accountNumber, sequence, gas);
|
|
156
|
+
// wait till confirmed
|
|
157
|
+
const pollResult = await (0, helpers_1.pollForComplete)(tradeId, this.deps.cosmosUrl);
|
|
158
|
+
if (pollResult !== 'success')
|
|
159
|
+
throw new api_1.SwapError('ibc transfer failed', {
|
|
160
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
161
|
+
});
|
|
162
|
+
ibcSellAmount = await (0, helpers_1.pollForAtomChannelBalance)(receiveAddress, this.deps.osmoUrl);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
const sellBip44Params = osmosisAdapter.buildBIP44Params({
|
|
166
|
+
accountNumber: Number(sellAssetAccountNumber)
|
|
167
|
+
});
|
|
168
|
+
sellAddress = await osmosisAdapter.getAddress({ wallet, bip44Params: sellBip44Params });
|
|
169
|
+
if (!sellAddress)
|
|
170
|
+
throw new api_1.SwapError('failed to get osmoAddress', {
|
|
171
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const osmoAddress = isFromOsmo ? sellAddress : receiveAddress;
|
|
175
|
+
const signTxInput = await (0, helpers_1.buildTradeTx)({
|
|
176
|
+
osmoAddress,
|
|
177
|
+
adapter: osmosisAdapter,
|
|
178
|
+
trade,
|
|
179
|
+
buyAssetDenom,
|
|
180
|
+
sellAssetDenom,
|
|
181
|
+
sellAmount: ibcSellAmount !== null && ibcSellAmount !== void 0 ? ibcSellAmount : sellAmount,
|
|
182
|
+
gas,
|
|
183
|
+
wallet
|
|
184
|
+
});
|
|
185
|
+
const signed = await osmosisAdapter.signTransaction(signTxInput);
|
|
186
|
+
const tradeId = await osmosisAdapter.broadcastTransaction(signed);
|
|
187
|
+
if (isFromOsmo) {
|
|
188
|
+
const pollResult = await (0, helpers_1.pollForComplete)(tradeId, this.deps.osmoUrl);
|
|
189
|
+
if (pollResult !== 'success')
|
|
190
|
+
throw new api_1.SwapError('osmo swap failed', {
|
|
191
|
+
code: api_1.SwapErrorTypes.EXECUTE_TRADE_FAILED
|
|
192
|
+
});
|
|
193
|
+
const amount = await (0, helpers_1.pollForAtomChannelBalance)(sellAddress, this.deps.osmoUrl);
|
|
194
|
+
const transfer = {
|
|
195
|
+
sender: sellAddress,
|
|
196
|
+
receiver: receiveAddress,
|
|
197
|
+
amount
|
|
198
|
+
};
|
|
199
|
+
const ibcResponseAccount = await osmosisAdapter.getAccount(sellAddress);
|
|
200
|
+
const ibcAccountNumber = ibcResponseAccount.chainSpecific.accountNumber || '0';
|
|
201
|
+
const ibcSequence = ibcResponseAccount.chainSpecific.sequence || '0';
|
|
202
|
+
await (0, helpers_1.performIbcTransfer)(transfer, osmosisAdapter, wallet, this.deps.cosmosUrl, buyAssetDenom, constants_1.OSMO_COSMO_CHANNEL, trade.feeData.fee, ibcAccountNumber, ibcSequence, gas);
|
|
203
|
+
}
|
|
204
|
+
return { tradeId: tradeId || 'error' };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
exports.OsmosisSwapper = OsmosisSwapper;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEFAULT_SOURCE: {
|
|
2
|
+
name: string;
|
|
3
|
+
proportion: string;
|
|
4
|
+
}[];
|
|
5
|
+
export declare const MAX_SWAPPER_SELL = "100000000000000000000000000";
|
|
6
|
+
export declare const OSMOSIS_PRECISION = 6;
|
|
7
|
+
export declare const COSMO_OSMO_CHANNEL = "channel-141";
|
|
8
|
+
export declare const OSMO_COSMO_CHANNEL = "channel-0";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OSMO_COSMO_CHANNEL = exports.COSMO_OSMO_CHANNEL = exports.OSMOSIS_PRECISION = exports.MAX_SWAPPER_SELL = exports.DEFAULT_SOURCE = void 0;
|
|
4
|
+
exports.DEFAULT_SOURCE = [{ name: 'Osmosis', proportion: '1' }];
|
|
5
|
+
exports.MAX_SWAPPER_SELL = '100000000000000000000000000';
|
|
6
|
+
exports.OSMOSIS_PRECISION = 6;
|
|
7
|
+
exports.COSMO_OSMO_CHANNEL = 'channel-141';
|
|
8
|
+
exports.OSMO_COSMO_CHANNEL = 'channel-0';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ChainId } from '@shapeshiftoss/caip';
|
|
2
|
+
import { osmosis } from '@shapeshiftoss/chain-adapters';
|
|
3
|
+
import { HDWallet } from '@shapeshiftoss/hdwallet-core';
|
|
4
|
+
import { CosmosSdkSupportedChainAdapters, Trade, TradeResult } from '../../../index';
|
|
5
|
+
import { IbcTransferInput } from './types';
|
|
6
|
+
export interface SymbolDenomMapping {
|
|
7
|
+
OSMO: string;
|
|
8
|
+
ATOM: string;
|
|
9
|
+
USDC: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const symbolDenomMapping: {
|
|
12
|
+
OSMO: string;
|
|
13
|
+
ATOM: string;
|
|
14
|
+
USDC: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const pollForComplete: (txid: string, baseUrl: string) => Promise<string>;
|
|
17
|
+
export declare const getAtomChannelBalance: (address: string, osmoUrl: string) => Promise<number>;
|
|
18
|
+
export declare const pollForAtomChannelBalance: (address: string, osmoUrl: string) => Promise<string>;
|
|
19
|
+
export declare const getRateInfo: (sellAsset: string, buyAsset: string, sellAmount: string, osmoUrl: string) => Promise<{
|
|
20
|
+
rate: string;
|
|
21
|
+
priceImpact: string;
|
|
22
|
+
tradeFee: string;
|
|
23
|
+
buyAmount: string;
|
|
24
|
+
}>;
|
|
25
|
+
export declare const performIbcTransfer: (input: IbcTransferInput, adapter: CosmosSdkSupportedChainAdapters, wallet: HDWallet, blockBaseUrl: string, denom: string, sourceChannel: string, feeAmount: string, accountNumber: string, sequence: string, gas: string) => Promise<TradeResult>;
|
|
26
|
+
export declare const buildTradeTx: ({ osmoAddress, adapter, trade, buyAssetDenom, sellAssetDenom, sellAmount, gas, wallet }: {
|
|
27
|
+
osmoAddress: string;
|
|
28
|
+
adapter: osmosis.ChainAdapter;
|
|
29
|
+
trade: Trade<ChainId>;
|
|
30
|
+
buyAssetDenom: string;
|
|
31
|
+
sellAssetDenom: string;
|
|
32
|
+
sellAmount: string;
|
|
33
|
+
gas: string;
|
|
34
|
+
wallet: HDWallet;
|
|
35
|
+
}) => Promise<{
|
|
36
|
+
txToSign: {
|
|
37
|
+
tx: {
|
|
38
|
+
memo: string;
|
|
39
|
+
fee: {
|
|
40
|
+
amount: {
|
|
41
|
+
amount: string;
|
|
42
|
+
denom: string;
|
|
43
|
+
}[];
|
|
44
|
+
gas: string;
|
|
45
|
+
};
|
|
46
|
+
signatures: null;
|
|
47
|
+
msg: {
|
|
48
|
+
type: string;
|
|
49
|
+
value: {
|
|
50
|
+
sender: string;
|
|
51
|
+
routes: {
|
|
52
|
+
poolId: string;
|
|
53
|
+
tokenOutDenom: string;
|
|
54
|
+
}[];
|
|
55
|
+
tokenIn: {
|
|
56
|
+
denom: string;
|
|
57
|
+
amount: string;
|
|
58
|
+
};
|
|
59
|
+
tokenOutMinAmount: string;
|
|
60
|
+
};
|
|
61
|
+
}[];
|
|
62
|
+
};
|
|
63
|
+
addressNList: number[];
|
|
64
|
+
chain_id: "osmosis-1";
|
|
65
|
+
account_number: string;
|
|
66
|
+
sequence: string;
|
|
67
|
+
};
|
|
68
|
+
wallet: HDWallet;
|
|
69
|
+
}>;
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildTradeTx = exports.performIbcTransfer = exports.getRateInfo = exports.pollForAtomChannelBalance = exports.getAtomChannelBalance = exports.pollForComplete = exports.symbolDenomMapping = void 0;
|
|
7
|
+
const caip_1 = require("@shapeshiftoss/caip");
|
|
8
|
+
const chain_adapters_1 = require("@shapeshiftoss/chain-adapters");
|
|
9
|
+
const hdwallet_core_1 = require("@shapeshiftoss/hdwallet-core");
|
|
10
|
+
const axios_1 = __importDefault(require("axios"));
|
|
11
|
+
const lodash_1 = require("lodash");
|
|
12
|
+
const index_1 = require("../../../index");
|
|
13
|
+
const bignumber_1 = require("../../utils/bignumber");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
15
|
+
exports.symbolDenomMapping = {
|
|
16
|
+
OSMO: 'uosmo',
|
|
17
|
+
ATOM: 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2',
|
|
18
|
+
USDC: 'ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858'
|
|
19
|
+
};
|
|
20
|
+
const txStatus = async (txid, baseUrl) => {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
try {
|
|
23
|
+
const txResponse = await axios_1.default.get(`${baseUrl}/txs/${txid}`);
|
|
24
|
+
if (!((_a = txResponse === null || txResponse === void 0 ? void 0 : txResponse.data) === null || _a === void 0 ? void 0 : _a.codespace) && !!((_b = txResponse === null || txResponse === void 0 ? void 0 : txResponse.data) === null || _b === void 0 ? void 0 : _b.gas_used))
|
|
25
|
+
return 'success';
|
|
26
|
+
if ((_c = txResponse === null || txResponse === void 0 ? void 0 : txResponse.data) === null || _c === void 0 ? void 0 : _c.codespace)
|
|
27
|
+
return 'failed';
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.error('Failed to get status');
|
|
31
|
+
}
|
|
32
|
+
return 'not found';
|
|
33
|
+
};
|
|
34
|
+
// TODO: leverage chain-adapters websockets
|
|
35
|
+
const pollForComplete = async (txid, baseUrl) => {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
const timeout = 120000; // 2 mins
|
|
38
|
+
const startTime = Date.now();
|
|
39
|
+
const interval = 5000; // 5 seconds
|
|
40
|
+
const poll = async function () {
|
|
41
|
+
const status = await txStatus(txid, baseUrl);
|
|
42
|
+
if (status === 'success') {
|
|
43
|
+
resolve(status);
|
|
44
|
+
}
|
|
45
|
+
else if (Date.now() - startTime > timeout) {
|
|
46
|
+
reject(new index_1.SwapError(`Couldnt find tx ${txid}`, {
|
|
47
|
+
code: index_1.SwapErrorTypes.RESPONSE_ERROR
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
setTimeout(poll, interval);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
poll();
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
exports.pollForComplete = pollForComplete;
|
|
58
|
+
const getAtomChannelBalance = async (address, osmoUrl) => {
|
|
59
|
+
const osmoResponseBalance = await (async () => {
|
|
60
|
+
try {
|
|
61
|
+
return axios_1.default.get(`${osmoUrl}/bank/balances/${address}`);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
throw new index_1.SwapError('failed to get balance', {
|
|
65
|
+
code: index_1.SwapErrorTypes.RESPONSE_ERROR
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
})();
|
|
69
|
+
let toAtomChannelBalance = 0;
|
|
70
|
+
try {
|
|
71
|
+
const { amount } = (0, lodash_1.find)(osmoResponseBalance.data.result, (b) => b.denom === exports.symbolDenomMapping.ATOM);
|
|
72
|
+
toAtomChannelBalance = Number(amount);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.error('no channel balance');
|
|
76
|
+
}
|
|
77
|
+
return toAtomChannelBalance;
|
|
78
|
+
};
|
|
79
|
+
exports.getAtomChannelBalance = getAtomChannelBalance;
|
|
80
|
+
const pollForAtomChannelBalance = async (address, osmoUrl) => {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const timeout = 120000; // 2 mins
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
const interval = 5000; // 5 seconds
|
|
85
|
+
const poll = async function () {
|
|
86
|
+
const balance = await (0, exports.getAtomChannelBalance)(address, osmoUrl);
|
|
87
|
+
if (balance > 0) {
|
|
88
|
+
resolve(balance.toString());
|
|
89
|
+
}
|
|
90
|
+
else if (Date.now() - startTime > timeout) {
|
|
91
|
+
reject(new index_1.SwapError(`Couldnt find channel balance for ${address}`, {
|
|
92
|
+
code: index_1.SwapErrorTypes.RESPONSE_ERROR
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
setTimeout(poll, interval);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
poll();
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
exports.pollForAtomChannelBalance = pollForAtomChannelBalance;
|
|
103
|
+
const findPool = async (sellAssetSymbol, buyAssetSymbol, osmoUrl) => {
|
|
104
|
+
const sellAssetDenom = exports.symbolDenomMapping[sellAssetSymbol];
|
|
105
|
+
const buyAssetDenom = exports.symbolDenomMapping[buyAssetSymbol];
|
|
106
|
+
const poolsUrl = osmoUrl + '/osmosis/gamm/v1beta1/pools?pagination.limit=1000';
|
|
107
|
+
const poolsResponse = await (async () => {
|
|
108
|
+
try {
|
|
109
|
+
return axios_1.default.get(poolsUrl);
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
throw new index_1.SwapError('failed to get pool', {
|
|
113
|
+
code: index_1.SwapErrorTypes.POOL_NOT_FOUND
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
117
|
+
const foundPool = (0, lodash_1.find)(poolsResponse.data.pools, (pool) => {
|
|
118
|
+
const token0Denom = pool.poolAssets[0].token.denom;
|
|
119
|
+
const token1Denom = pool.poolAssets[1].token.denom;
|
|
120
|
+
return ((token0Denom === sellAssetDenom && token1Denom === buyAssetDenom) ||
|
|
121
|
+
(token0Denom === buyAssetDenom && token1Denom === sellAssetDenom));
|
|
122
|
+
});
|
|
123
|
+
if (!foundPool)
|
|
124
|
+
throw new index_1.SwapError('could not find pool', {
|
|
125
|
+
code: index_1.SwapErrorTypes.POOL_NOT_FOUND
|
|
126
|
+
});
|
|
127
|
+
const { sellAssetIndex, buyAssetIndex } = (() => {
|
|
128
|
+
if (foundPool.poolAssets[0].token.denom === sellAssetDenom) {
|
|
129
|
+
return { sellAssetIndex: 0, buyAssetIndex: 1 };
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return { sellAssetIndex: 1, buyAssetIndex: 0 };
|
|
133
|
+
}
|
|
134
|
+
})();
|
|
135
|
+
return { pool: foundPool, sellAssetIndex, buyAssetIndex };
|
|
136
|
+
};
|
|
137
|
+
const getInfoFromPool = (sellAmount, pool, sellAssetIndex, buyAssetIndex) => {
|
|
138
|
+
const constantProduct = (0, bignumber_1.bnOrZero)(pool.poolAssets[0].token.amount).times(pool.poolAssets[1].token.amount);
|
|
139
|
+
const sellAssetInitialPoolSize = (0, bignumber_1.bnOrZero)(pool.poolAssets[sellAssetIndex].token.amount);
|
|
140
|
+
const buyAssetInitialPoolSize = (0, bignumber_1.bnOrZero)(pool.poolAssets[buyAssetIndex].token.amount);
|
|
141
|
+
const initialMarketPrice = sellAssetInitialPoolSize.dividedBy(buyAssetInitialPoolSize);
|
|
142
|
+
const sellAssetFinalPoolSize = sellAssetInitialPoolSize.plus(sellAmount);
|
|
143
|
+
const buyAssetFinalPoolSize = constantProduct.dividedBy(sellAssetFinalPoolSize);
|
|
144
|
+
const finalMarketPrice = sellAssetFinalPoolSize.dividedBy(buyAssetFinalPoolSize);
|
|
145
|
+
const buyAmount = buyAssetInitialPoolSize.minus(buyAssetFinalPoolSize).toString();
|
|
146
|
+
const rate = (0, bignumber_1.bnOrZero)(buyAmount).dividedBy(sellAmount).toString();
|
|
147
|
+
const priceImpact = (0, bignumber_1.bn)(1).minus(initialMarketPrice.dividedBy(finalMarketPrice)).abs().toString();
|
|
148
|
+
const tradeFeeBase = (0, bignumber_1.bnOrZero)(buyAmount).times((0, bignumber_1.bnOrZero)(pool.poolParams.swapFee));
|
|
149
|
+
const tradeFee = tradeFeeBase.dividedBy((0, bignumber_1.bn)(10).exponentiatedBy(constants_1.OSMOSIS_PRECISION)).toString();
|
|
150
|
+
return {
|
|
151
|
+
rate,
|
|
152
|
+
priceImpact,
|
|
153
|
+
tradeFee,
|
|
154
|
+
buyAmount
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const getRateInfo = async (sellAsset, buyAsset, sellAmount, osmoUrl) => {
|
|
158
|
+
const { pool, sellAssetIndex, buyAssetIndex } = await findPool(sellAsset, buyAsset, osmoUrl);
|
|
159
|
+
return getInfoFromPool(sellAmount, pool, sellAssetIndex, buyAssetIndex);
|
|
160
|
+
};
|
|
161
|
+
exports.getRateInfo = getRateInfo;
|
|
162
|
+
// TODO: move to chain adapters
|
|
163
|
+
const performIbcTransfer = async (input, adapter, wallet, blockBaseUrl, denom, sourceChannel, feeAmount, accountNumber, sequence, gas) => {
|
|
164
|
+
const { sender, receiver, amount } = input;
|
|
165
|
+
const responseLatestBlock = await (async () => {
|
|
166
|
+
try {
|
|
167
|
+
return axios_1.default.get(`${blockBaseUrl}/blocks/latest`);
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
throw new index_1.SwapError('failed to get latest block', {
|
|
171
|
+
code: index_1.SwapErrorTypes.RESPONSE_ERROR
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
})();
|
|
175
|
+
const latestBlock = responseLatestBlock.data.block.header.height;
|
|
176
|
+
const bip44Params = adapter.buildBIP44Params({
|
|
177
|
+
accountNumber: 0 // TODO: Use real accountNumbers
|
|
178
|
+
});
|
|
179
|
+
const path = (0, chain_adapters_1.toPath)(bip44Params);
|
|
180
|
+
const addressNList = (0, hdwallet_core_1.bip32ToAddressNList)(path);
|
|
181
|
+
const tx1 = {
|
|
182
|
+
memo: '',
|
|
183
|
+
fee: {
|
|
184
|
+
amount: [
|
|
185
|
+
{
|
|
186
|
+
amount: feeAmount.toString(),
|
|
187
|
+
denom: 'uosmo'
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
gas
|
|
191
|
+
},
|
|
192
|
+
signatures: null,
|
|
193
|
+
msg: [
|
|
194
|
+
{
|
|
195
|
+
type: 'cosmos-sdk/MsgTransfer',
|
|
196
|
+
value: {
|
|
197
|
+
source_port: 'transfer',
|
|
198
|
+
source_channel: sourceChannel,
|
|
199
|
+
token: {
|
|
200
|
+
denom,
|
|
201
|
+
amount
|
|
202
|
+
},
|
|
203
|
+
sender,
|
|
204
|
+
receiver,
|
|
205
|
+
timeout_height: {
|
|
206
|
+
revision_number: '4',
|
|
207
|
+
revision_height: String(Number(latestBlock) + 100)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
};
|
|
213
|
+
const signed = await adapter.signTransaction({
|
|
214
|
+
txToSign: {
|
|
215
|
+
tx: tx1,
|
|
216
|
+
addressNList,
|
|
217
|
+
chain_id: caip_1.CHAIN_REFERENCE.OsmosisMainnet,
|
|
218
|
+
account_number: accountNumber,
|
|
219
|
+
sequence
|
|
220
|
+
},
|
|
221
|
+
wallet
|
|
222
|
+
});
|
|
223
|
+
const tradeId = await adapter.broadcastTransaction(signed);
|
|
224
|
+
return {
|
|
225
|
+
tradeId
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
exports.performIbcTransfer = performIbcTransfer;
|
|
229
|
+
// TODO: move to chain adapters
|
|
230
|
+
const buildTradeTx = async ({ osmoAddress, adapter, trade, buyAssetDenom, sellAssetDenom, sellAmount, gas, wallet }) => {
|
|
231
|
+
const responseAccount = await adapter.getAccount(osmoAddress);
|
|
232
|
+
const accountNumber = responseAccount.chainSpecific.accountNumber || '0';
|
|
233
|
+
const sequence = responseAccount.chainSpecific.sequence || '0';
|
|
234
|
+
const bip44Params = adapter.buildBIP44Params({
|
|
235
|
+
accountNumber: 0 // TODO: Use real accountNumbers
|
|
236
|
+
});
|
|
237
|
+
const path = (0, chain_adapters_1.toPath)(bip44Params);
|
|
238
|
+
const osmoAddressNList = (0, hdwallet_core_1.bip32ToAddressNList)(path);
|
|
239
|
+
const tx = {
|
|
240
|
+
memo: '',
|
|
241
|
+
fee: {
|
|
242
|
+
amount: [
|
|
243
|
+
{
|
|
244
|
+
amount: trade.feeData.fee.toString(),
|
|
245
|
+
denom: 'uosmo'
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
gas
|
|
249
|
+
},
|
|
250
|
+
signatures: null,
|
|
251
|
+
msg: [
|
|
252
|
+
{
|
|
253
|
+
type: 'osmosis/gamm/swap-exact-amount-in',
|
|
254
|
+
value: {
|
|
255
|
+
sender: osmoAddress,
|
|
256
|
+
routes: [
|
|
257
|
+
{
|
|
258
|
+
poolId: '1',
|
|
259
|
+
tokenOutDenom: buyAssetDenom
|
|
260
|
+
}
|
|
261
|
+
],
|
|
262
|
+
tokenIn: {
|
|
263
|
+
denom: sellAssetDenom,
|
|
264
|
+
amount: sellAmount
|
|
265
|
+
},
|
|
266
|
+
tokenOutMinAmount: '1' // slippage tolerance
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
};
|
|
271
|
+
return {
|
|
272
|
+
txToSign: {
|
|
273
|
+
tx,
|
|
274
|
+
addressNList: osmoAddressNList,
|
|
275
|
+
chain_id: caip_1.CHAIN_REFERENCE.OsmosisMainnet,
|
|
276
|
+
account_number: accountNumber,
|
|
277
|
+
sequence
|
|
278
|
+
},
|
|
279
|
+
wallet
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
exports.buildTradeTx = buildTradeTx;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ChainAdapterManager } from '@shapeshiftoss/chain-adapters';
|
|
2
|
+
export declare type OsmoSwapperDeps = {
|
|
3
|
+
adapterManager: ChainAdapterManager;
|
|
4
|
+
osmoUrl: string;
|
|
5
|
+
cosmosUrl: string;
|
|
6
|
+
};
|
|
7
|
+
export declare type IbcTransferInput = {
|
|
8
|
+
sender: string;
|
|
9
|
+
receiver: string;
|
|
10
|
+
amount: string;
|
|
11
|
+
};
|
|
12
|
+
export declare type PoolInfo = {
|
|
13
|
+
poolAssets: PoolAssetInfo[];
|
|
14
|
+
poolParams: {
|
|
15
|
+
swapFee: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare type PoolAssetInfo = {
|
|
19
|
+
token: {
|
|
20
|
+
amount: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -4,13 +4,27 @@ exports.thorTradeApproveInfinite = void 0;
|
|
|
4
4
|
const types_1 = require("@shapeshiftoss/types");
|
|
5
5
|
const api_1 = require("../../../api");
|
|
6
6
|
const erc20_abi_1 = require("../../utils/abi/erc20-abi");
|
|
7
|
+
const constants_1 = require("../../utils/constants");
|
|
7
8
|
const helpers_1 = require("../../utils/helpers/helpers");
|
|
8
|
-
const
|
|
9
|
+
const constants_2 = require("../utils/constants");
|
|
9
10
|
const thorTradeApproveInfinite = async ({ deps, input }) => {
|
|
10
11
|
try {
|
|
11
12
|
const { adapterManager, web3 } = deps;
|
|
12
13
|
const { quote, wallet } = input;
|
|
13
|
-
const
|
|
14
|
+
const approvalQuote = {
|
|
15
|
+
...quote,
|
|
16
|
+
sellAmount: constants_2.MAX_ALLOWANCE,
|
|
17
|
+
feeData: {
|
|
18
|
+
...quote.feeData,
|
|
19
|
+
chainSpecific: {
|
|
20
|
+
...quote.feeData.chainSpecific,
|
|
21
|
+
// Thor approvals are cheaper than trades, but we don't have dynamic quote data for them.
|
|
22
|
+
// Instead, we use a hardcoded gasLimit estimate in place of the estimatedGas in the Thor quote response.
|
|
23
|
+
estimatedGas: constants_1.APPROVAL_GAS_LIMIT
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const sellAssetChainId = approvalQuote.sellAsset.chainId;
|
|
14
28
|
const adapter = adapterManager.get(types_1.KnownChainIds.EthereumMainnet);
|
|
15
29
|
if (!adapter)
|
|
16
30
|
throw new api_1.SwapError(`[thorTradeApproveInfinite] - No chain adapter found for ${sellAssetChainId}.`, {
|
|
@@ -18,10 +32,7 @@ const thorTradeApproveInfinite = async ({ deps, input }) => {
|
|
|
18
32
|
details: { sellAssetChainId }
|
|
19
33
|
});
|
|
20
34
|
const allowanceGrantRequired = await (0, helpers_1.grantAllowance)({
|
|
21
|
-
quote:
|
|
22
|
-
...quote,
|
|
23
|
-
sellAmount: constants_1.MAX_ALLOWANCE
|
|
24
|
-
},
|
|
35
|
+
quote: approvalQuote,
|
|
25
36
|
wallet,
|
|
26
37
|
adapter,
|
|
27
38
|
erc20Abi: erc20_abi_1.erc20Abi,
|
|
@@ -11,7 +11,6 @@ const constants_2 = require("../utils/constants");
|
|
|
11
11
|
const helpers_2 = require("../utils/helpers/helpers");
|
|
12
12
|
const zrxService_1 = require("../utils/zrxService");
|
|
13
13
|
async function getZrxTradeQuote(input) {
|
|
14
|
-
var _a;
|
|
15
14
|
try {
|
|
16
15
|
const { sellAsset, buyAsset, sellAmount, sellAssetAccountNumber } = input;
|
|
17
16
|
if (buyAsset.chainId !== input.chainId || sellAsset.chainId !== input.chainId) {
|
|
@@ -46,27 +45,31 @@ async function getZrxTradeQuote(input) {
|
|
|
46
45
|
sellAmount: normalizedSellAmount
|
|
47
46
|
}
|
|
48
47
|
});
|
|
49
|
-
const { data } = quoteResponse;
|
|
50
|
-
const estimatedGas = (0, bignumber_1.bnOrZero)(
|
|
51
|
-
const rate = useSellAmount ?
|
|
48
|
+
const { data: { estimatedGas: estimatedGasResponse, gasPrice, price, sellAmount: sellAmountResponse, buyAmount, sources, allowanceTarget } } = quoteResponse;
|
|
49
|
+
const estimatedGas = (0, bignumber_1.bnOrZero)(estimatedGasResponse).times(1.5);
|
|
50
|
+
const rate = useSellAmount ? price : (0, bignumber_1.bn)(1).div(price).toString();
|
|
51
|
+
const fee = (0, bignumber_1.bnOrZero)(estimatedGas).multipliedBy((0, bignumber_1.bnOrZero)(gasPrice)).toString();
|
|
52
|
+
// 0x approvals are cheaper than trades, but we don't have dynamic quote data for them.
|
|
53
|
+
// Instead, we use a hardcoded gasLimit estimate in place of the estimatedGas in the 0x quote response.
|
|
54
|
+
const approvalFee = sellAssetErc20Address &&
|
|
55
|
+
(0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(gasPrice)).toString();
|
|
52
56
|
return {
|
|
53
57
|
rate,
|
|
54
58
|
minimum,
|
|
55
59
|
maximum,
|
|
56
60
|
feeData: {
|
|
57
|
-
fee
|
|
61
|
+
fee,
|
|
58
62
|
chainSpecific: {
|
|
59
63
|
estimatedGas: estimatedGas.toString(),
|
|
60
|
-
gasPrice
|
|
61
|
-
approvalFee
|
|
62
|
-
(0, bignumber_1.bnOrZero)(constants_1.APPROVAL_GAS_LIMIT).multipliedBy((0, bignumber_1.bnOrZero)(data.gasPrice)).toString()
|
|
64
|
+
gasPrice,
|
|
65
|
+
approvalFee
|
|
63
66
|
},
|
|
64
67
|
tradeFee: '0'
|
|
65
68
|
},
|
|
66
|
-
sellAmount:
|
|
67
|
-
buyAmount
|
|
68
|
-
sources: (
|
|
69
|
-
allowanceContract:
|
|
69
|
+
sellAmount: sellAmountResponse,
|
|
70
|
+
buyAmount,
|
|
71
|
+
sources: (sources === null || sources === void 0 ? void 0 : sources.filter((s) => parseFloat(s.proportion) > 0)) || constants_2.DEFAULT_SOURCE,
|
|
72
|
+
allowanceContract: allowanceTarget,
|
|
70
73
|
buyAsset,
|
|
71
74
|
sellAsset,
|
|
72
75
|
sellAssetAccountNumber
|
|
@@ -3,15 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.zrxApproveInfinite = void 0;
|
|
4
4
|
const api_1 = require("../../../api");
|
|
5
5
|
const erc20_abi_1 = require("../../utils/abi/erc20-abi");
|
|
6
|
+
const constants_1 = require("../../utils/constants");
|
|
6
7
|
const helpers_1 = require("../../utils/helpers/helpers");
|
|
7
|
-
const
|
|
8
|
+
const constants_2 = require("../utils/constants");
|
|
8
9
|
async function zrxApproveInfinite({ adapter, web3 }, { quote, wallet }) {
|
|
9
10
|
try {
|
|
11
|
+
const approvalQuote = {
|
|
12
|
+
...quote,
|
|
13
|
+
sellAmount: constants_2.MAX_ALLOWANCE,
|
|
14
|
+
feeData: {
|
|
15
|
+
...quote.feeData,
|
|
16
|
+
chainSpecific: {
|
|
17
|
+
...quote.feeData.chainSpecific,
|
|
18
|
+
// 0x approvals are cheaper than trades, but we don't have dynamic quote data for them.
|
|
19
|
+
// Instead, we use a hardcoded gasLimit estimate in place of the estimatedGas in the 0x quote response.
|
|
20
|
+
estimatedGas: constants_1.APPROVAL_GAS_LIMIT
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
10
24
|
const allowanceGrantRequired = await (0, helpers_1.grantAllowance)({
|
|
11
|
-
quote:
|
|
12
|
-
...quote,
|
|
13
|
-
sellAmount: constants_1.MAX_ALLOWANCE
|
|
14
|
-
},
|
|
25
|
+
quote: approvalQuote,
|
|
15
26
|
wallet,
|
|
16
27
|
adapter,
|
|
17
28
|
erc20Abi: erc20_abi_1.erc20Abi,
|
package/package.json
CHANGED