@xchainjs/xchain-thorchain-amm 0.8.21 → 1.0.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/lib/index.d.ts +10 -1
- package/lib/index.esm.js +371 -895
- package/lib/index.js +358 -883
- package/lib/thorchain-action.d.ts +21 -0
- package/lib/thorchain-amm.d.ts +78 -71
- package/lib/types.d.ts +38 -0
- package/lib/utils.d.ts +19 -0
- package/package.json +12 -18
- package/lib/utils/evm-helper.d.ts +0 -25
- package/lib/utils/index.d.ts +0 -1
- package/lib/wallet.d.ts +0 -173
package/lib/index.js
CHANGED
|
@@ -12,12 +12,12 @@ var xchainCosmos = require('@xchainjs/xchain-cosmos');
|
|
|
12
12
|
var xchainDoge = require('@xchainjs/xchain-doge');
|
|
13
13
|
var xchainEthereum = require('@xchainjs/xchain-ethereum');
|
|
14
14
|
var xchainLitecoin = require('@xchainjs/xchain-litecoin');
|
|
15
|
-
var xchainMayachain = require('@xchainjs/xchain-mayachain');
|
|
16
15
|
var xchainThorchain = require('@xchainjs/xchain-thorchain');
|
|
17
|
-
var
|
|
16
|
+
var xchainThorchainQuery = require('@xchainjs/xchain-thorchain-query');
|
|
17
|
+
var xchainWallet = require('@xchainjs/xchain-wallet');
|
|
18
18
|
var xchainEvm = require('@xchainjs/xchain-evm');
|
|
19
|
+
var xchainUtil = require('@xchainjs/xchain-util');
|
|
19
20
|
var ethers = require('ethers');
|
|
20
|
-
var xchainThorchainQuery = require('@xchainjs/xchain-thorchain-query');
|
|
21
21
|
|
|
22
22
|
/******************************************************************************
|
|
23
23
|
Copyright (c) Microsoft Corporation.
|
|
@@ -44,803 +44,128 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const FIFTEEN_MIN_IN_SECS = 15 * 60;
|
|
48
|
-
class EvmHelper {
|
|
49
|
-
constructor(client, thorchainCache) {
|
|
50
|
-
this.evmClient = client;
|
|
51
|
-
this.client = client;
|
|
52
|
-
this.thorchainCache = thorchainCache;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Transaction to THORChain inbound address.
|
|
56
|
-
*
|
|
57
|
-
* @param {DepositParams} params The transaction options.
|
|
58
|
-
* @returns {TxHash} The transaction hash.
|
|
59
|
-
*
|
|
60
|
-
* @throws {"halted chain"} Thrown if chain is halted.
|
|
61
|
-
* @throws {"halted trading"} Thrown if trading is halted.
|
|
62
|
-
* @throws {"amount is not approved"} Thrown if the amount is not allowed to spend
|
|
63
|
-
* @throws {"router address is not defined"} Thrown if router address is not defined
|
|
64
|
-
*/
|
|
65
|
-
sendDeposit(params) {
|
|
66
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
-
const inboundAsgard = (yield this.thorchainCache.getInboundDetails())[params.asset.chain];
|
|
68
|
-
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router)) {
|
|
69
|
-
throw new Error('router address is not defined');
|
|
70
|
-
}
|
|
71
|
-
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
72
|
-
throw new Error('Vault address is not defined');
|
|
73
|
-
}
|
|
74
|
-
const address = yield this.client.getAddressAsync(params.walletIndex);
|
|
75
|
-
const gasPrice = yield this.evmClient.estimateGasPrices(xchainClient.Protocol.THORCHAIN);
|
|
76
|
-
if (xchainUtil.eqAsset(params.asset, this.evmClient.config.gasAsset)) {
|
|
77
|
-
// simple transfer
|
|
78
|
-
return yield this.evmClient.transfer({
|
|
79
|
-
walletIndex: params.walletIndex || 0,
|
|
80
|
-
asset: params.asset,
|
|
81
|
-
amount: params.amount,
|
|
82
|
-
recipient: inboundAsgard.address,
|
|
83
|
-
memo: params.memo,
|
|
84
|
-
gasPrice: gasPrice.fast,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
//erc-20 must be depsited to the router
|
|
89
|
-
const isApprovedResult = yield this.isTCRouterApprovedToSpend(params.asset, params.amount, params.walletIndex);
|
|
90
|
-
if (!isApprovedResult) {
|
|
91
|
-
throw new Error('The amount is not allowed to spend');
|
|
92
|
-
}
|
|
93
|
-
const contractAddress = xchainUtil.getContractAddressFromAsset(params.asset);
|
|
94
|
-
const checkSummedContractAddress = ethers.ethers.utils.getAddress(contractAddress);
|
|
95
|
-
const latestBlockTimeUnixSecs = (yield this.evmClient.getProvider().getBlock('latest')).timestamp;
|
|
96
|
-
const expiry = latestBlockTimeUnixSecs + FIFTEEN_MIN_IN_SECS;
|
|
97
|
-
const depositParams = [
|
|
98
|
-
inboundAsgard.address,
|
|
99
|
-
checkSummedContractAddress,
|
|
100
|
-
params.amount.amount().toFixed(),
|
|
101
|
-
params.memo,
|
|
102
|
-
expiry,
|
|
103
|
-
];
|
|
104
|
-
const routerContract = new ethers.ethers.Contract(inboundAsgard.router, xchainEvm.abi.router);
|
|
105
|
-
const gasLimit = '160000';
|
|
106
|
-
const unsignedTx = yield routerContract.populateTransaction.depositWithExpiry(...depositParams, {
|
|
107
|
-
from: address,
|
|
108
|
-
value: 0,
|
|
109
|
-
gasPrice: gasPrice.fast.amount().toFixed(),
|
|
110
|
-
gasLimit: gasLimit,
|
|
111
|
-
});
|
|
112
|
-
const { hash } = yield this.evmClient.getWallet(params.walletIndex).sendTransaction(unsignedTx);
|
|
113
|
-
return hash;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
isTCRouterApprovedToSpend(asset, amount, walletIndex = 0) {
|
|
118
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
119
|
-
const router = yield this.thorchainCache.getRouterAddressForChain(asset.chain);
|
|
120
|
-
const contractAddress = xchainUtil.getContractAddressFromAsset(asset);
|
|
121
|
-
return yield this.evmClient.isApproved({
|
|
122
|
-
amount: amount,
|
|
123
|
-
spenderAddress: router,
|
|
124
|
-
contractAddress,
|
|
125
|
-
walletIndex: walletIndex,
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
approveTCRouterToSpend(asset, amount = xchainEvm.MAX_APPROVAL, walletIndex = 0) {
|
|
130
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
const contractAddress = xchainUtil.getContractAddressFromAsset(asset);
|
|
132
|
-
const router = yield this.thorchainCache.getRouterAddressForChain(asset.chain);
|
|
133
|
-
const decimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset);
|
|
134
|
-
const approveParams = {
|
|
135
|
-
contractAddress,
|
|
136
|
-
spenderAddress: router,
|
|
137
|
-
amount: xchainUtil.baseAmount(amount.toString(), decimals),
|
|
138
|
-
walletIndex,
|
|
139
|
-
};
|
|
140
|
-
return yield this.evmClient.approve(approveParams);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
47
|
/**
|
|
146
|
-
*
|
|
48
|
+
* Check if a chain is EVM and supported by the protocol
|
|
49
|
+
* @param {Chain} chain to check
|
|
50
|
+
* @returns true if chain is EVM, otherwise, false
|
|
147
51
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
};
|
|
173
|
-
this.evmHelpers = {
|
|
174
|
-
ETH: new EvmHelper(this.clients.ETH, this.thorchainQuery.thorchainCache),
|
|
175
|
-
BSC: new EvmHelper(this.clients.BSC, this.thorchainQuery.thorchainCache),
|
|
176
|
-
AVAX: new EvmHelper(this.clients.AVAX, this.thorchainQuery.thorchainCache),
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Fetch balances for all wallets
|
|
181
|
-
*
|
|
182
|
-
* @returns AllBalances[]
|
|
183
|
-
*/
|
|
184
|
-
getAllBalances() {
|
|
185
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
186
|
-
const allBalances = [];
|
|
187
|
-
for (const [chain, client] of Object.entries(this.clients)) {
|
|
188
|
-
const address = yield client.getAddressAsync(0);
|
|
189
|
-
try {
|
|
190
|
-
const balances = yield client.getBalance(address);
|
|
191
|
-
allBalances.push({ chain, address, balances });
|
|
192
|
-
}
|
|
193
|
-
catch (err) {
|
|
194
|
-
allBalances.push({ chain, address, balances: err.message });
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return allBalances;
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Executes a Swap from THORChainAMM.doSwap()
|
|
202
|
-
*
|
|
203
|
-
* @param swap object with all the required details for a swap.
|
|
204
|
-
* @returns transaction details and explorer url
|
|
205
|
-
* @see ThorchainAMM.doSwap()
|
|
206
|
-
*/
|
|
207
|
-
executeSwap(swap) {
|
|
208
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
-
yield this.validateSwap(swap);
|
|
210
|
-
if (swap.input.asset.chain === xchainThorchain.THORChain || swap.input.asset.synth) {
|
|
211
|
-
return yield this.swapRuneTo(swap);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
return yield this.swapNonRune(swap);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
/** Validate swap object
|
|
219
|
-
*
|
|
220
|
-
* @param swap - swap parameters
|
|
221
|
-
*/
|
|
222
|
-
validateSwap(swap) {
|
|
223
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
224
|
-
const errors = [];
|
|
225
|
-
const isThorchainDestinationAsset = swap.destinationAsset.synth || swap.destinationAsset.chain === xchainThorchain.THORChain;
|
|
226
|
-
const chain = isThorchainDestinationAsset ? xchainThorchain.THORChain : swap.destinationAsset.chain;
|
|
227
|
-
// check address
|
|
228
|
-
if (swap.destinationAddress && !this.clients[chain].validateAddress(swap.destinationAddress)) {
|
|
229
|
-
errors.push(`destinationAddress ${swap.destinationAddress} is not a valid address`);
|
|
230
|
-
}
|
|
231
|
-
// Affiliate address should be THORName or THORAddress
|
|
232
|
-
const checkAffiliateAddress = swap.memo.split(':');
|
|
233
|
-
if (checkAffiliateAddress.length > 4) {
|
|
234
|
-
const affiliateAddress = checkAffiliateAddress[4];
|
|
235
|
-
if (affiliateAddress.length > 0) {
|
|
236
|
-
const isValidThorchainAddress = this.clients[xchainThorchain.THORChain].validateAddress(affiliateAddress);
|
|
237
|
-
const isValidThorname = this.isThorname(affiliateAddress);
|
|
238
|
-
if (!(isValidThorchainAddress || isValidThorname))
|
|
239
|
-
errors.push(`affiliateAddress ${affiliateAddress} is not a valid THOR address`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
// if input == synth return errors.
|
|
243
|
-
if (swap.input.asset.synth)
|
|
244
|
-
return errors;
|
|
245
|
-
if (this.isERC20Asset(swap.input.asset)) {
|
|
246
|
-
const isApprovedResult = yield this.evmHelpers[swap.input.asset.chain].isTCRouterApprovedToSpend(swap.input.asset, swap.input.baseAmount, swap.walletIndex);
|
|
247
|
-
if (!isApprovedResult) {
|
|
248
|
-
errors.push('TC router has not been approved to spend this amount');
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
return errors;
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
isThorname(name) {
|
|
255
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
-
const thornameDetails = yield this.thorchainQuery.thorchainCache.midgardQuery.midgardCache.midgard.getTHORNameDetails(name); // Update when thorchainCache expose getTHORNameDetails method
|
|
257
|
-
return thornameDetails !== undefined;
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
/** Function handles all swaps from Rune to asset
|
|
261
|
-
*
|
|
262
|
-
* @param swap - swap parameters
|
|
263
|
-
* @returns - tx submitted object
|
|
264
|
-
*/
|
|
265
|
-
swapRuneTo(swap) {
|
|
266
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
267
|
-
const thorClient = this.clients.THOR;
|
|
268
|
-
const hash = yield thorClient.deposit({
|
|
269
|
-
amount: swap.input.baseAmount,
|
|
270
|
-
asset: swap.input.asset,
|
|
271
|
-
memo: swap.memo,
|
|
272
|
-
});
|
|
273
|
-
return { hash, url: this.clients.THOR.getExplorerTxUrl(hash) };
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
/** Function handles all swaps from Non Rune
|
|
277
|
-
*
|
|
278
|
-
* @param swap - swap object
|
|
279
|
-
* @returns - TxSubmitted object
|
|
280
|
-
*/
|
|
281
|
-
swapNonRune(swap) {
|
|
282
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
283
|
-
const client = this.clients[swap.input.asset.chain];
|
|
284
|
-
const inbound = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[swap.input.asset.chain];
|
|
285
|
-
if (!(inbound === null || inbound === void 0 ? void 0 : inbound.address))
|
|
286
|
-
throw Error(`no asgard address found for ${swap.input.asset.chain}`);
|
|
287
|
-
if (this.isEVMChain(swap.input.asset)) {
|
|
288
|
-
const params = {
|
|
289
|
-
walletIndex: 0,
|
|
290
|
-
asset: swap.input.asset,
|
|
291
|
-
amount: swap.input.baseAmount,
|
|
292
|
-
feeOption: swap.feeOption || xchainClient.FeeOption.Fast,
|
|
293
|
-
memo: swap.memo,
|
|
294
|
-
};
|
|
295
|
-
const hash = yield this.evmHelpers[swap.input.asset.chain].sendDeposit(params);
|
|
296
|
-
return { hash, url: client.getExplorerTxUrl(hash) };
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
const params = {
|
|
300
|
-
walletIndex: 0,
|
|
301
|
-
asset: swap.input.asset,
|
|
302
|
-
amount: swap.input.baseAmount,
|
|
303
|
-
recipient: inbound.address,
|
|
304
|
-
memo: swap.memo,
|
|
305
|
-
};
|
|
306
|
-
const hash = yield client.transfer(params);
|
|
307
|
-
return { hash, url: client.getExplorerTxUrl(hash) };
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
/** Function handles liquidity Add
|
|
312
|
-
* BASED OFF https://dev.thorchain.or›g/thorchain-dev/network/memos
|
|
313
|
-
* @param params input parameters needed to add liquidity
|
|
314
|
-
* @returns transaction details submitted
|
|
315
|
-
*/
|
|
316
|
-
addLiquidity(params) {
|
|
317
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
318
|
-
const assetClient = this.clients[params.asset.asset.chain];
|
|
319
|
-
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain]
|
|
320
|
-
.address;
|
|
321
|
-
const thorchainClient = this.clients[params.rune.asset.chain];
|
|
322
|
-
const addressRune = yield thorchainClient.getAddressAsync();
|
|
323
|
-
const addressAsset = yield assetClient.getAddressAsync();
|
|
324
|
-
// const waitTimeSeconds = params.waitTimeSeconds
|
|
325
|
-
let constructedMemo = '';
|
|
326
|
-
const txSubmitted = [];
|
|
327
|
-
// symmetrical add
|
|
328
|
-
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
329
|
-
constructedMemo = `+:${params.assetPool}:${addressRune}`;
|
|
330
|
-
txSubmitted.push(yield this.addAssetLP(params, constructedMemo, assetClient, inboundAsgard));
|
|
331
|
-
constructedMemo = `+:${params.assetPool}:${addressAsset}`;
|
|
332
|
-
txSubmitted.push(yield this.addRuneLP(params, constructedMemo, thorchainClient));
|
|
333
|
-
return txSubmitted;
|
|
334
|
-
}
|
|
335
|
-
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
336
|
-
// asymmetrical asset only
|
|
337
|
-
constructedMemo = `+:${params.assetPool}`;
|
|
338
|
-
txSubmitted.push(yield this.addAssetLP(params, constructedMemo, assetClient, inboundAsgard));
|
|
339
|
-
return txSubmitted;
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
// asymmetrical rune only
|
|
343
|
-
constructedMemo = `+:${params.assetPool}`;
|
|
344
|
-
txSubmitted.push(yield this.addRuneLP(params, constructedMemo, thorchainClient));
|
|
345
|
-
return txSubmitted;
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
/** Function handles liquidity Withdraw
|
|
350
|
-
*
|
|
351
|
-
* @param params - parameters required for liquidity position
|
|
352
|
-
* @returns object with tx response, url and wait time in seconds
|
|
353
|
-
*/
|
|
354
|
-
withdrawLiquidity(params) {
|
|
355
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
356
|
-
const assetClient = this.clients[params.assetFee.asset.chain];
|
|
357
|
-
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.assetFee.asset.chain]
|
|
358
|
-
.address;
|
|
359
|
-
// const waitTimeSeconds = params.waitTimeSeconds
|
|
360
|
-
const thorchainClient = this.clients[params.runeFee.asset.chain];
|
|
361
|
-
const basisPoints = (params.percentage * 100).toFixed(); // convert to basis points
|
|
362
|
-
let constructedMemo = '';
|
|
363
|
-
const txSubmitted = [];
|
|
364
|
-
if (params.assetAddress && params.runeAddress) {
|
|
365
|
-
constructedMemo = `-:${params.assetPool}:${basisPoints}`;
|
|
366
|
-
txSubmitted.push(yield this.withdrawAssetLP(params, constructedMemo, assetClient, inboundAsgard));
|
|
367
|
-
constructedMemo = `-:${params.assetPool}:${basisPoints}`;
|
|
368
|
-
txSubmitted.push(yield this.withdrawRuneLP(params, constructedMemo, thorchainClient));
|
|
369
|
-
return txSubmitted;
|
|
370
|
-
}
|
|
371
|
-
else if (params.assetAddress && !params.runeAddress) {
|
|
372
|
-
// asymmetrical asset only
|
|
373
|
-
constructedMemo = `-:${params.assetPool}:${basisPoints}`;
|
|
374
|
-
txSubmitted.push(yield this.withdrawAssetLP(params, constructedMemo, assetClient, inboundAsgard));
|
|
375
|
-
return txSubmitted;
|
|
376
|
-
}
|
|
377
|
-
else {
|
|
378
|
-
// asymmetrical rune only
|
|
379
|
-
constructedMemo = `-:${params.assetPool}:${basisPoints}`;
|
|
380
|
-
txSubmitted.push(yield this.withdrawRuneLP(params, constructedMemo, thorchainClient));
|
|
381
|
-
return txSubmitted;
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
*
|
|
387
|
-
* @param assetAmount - amount to add
|
|
388
|
-
* @param memo - memo required
|
|
389
|
-
* @param waitTimeSeconds - expected wait for the transaction to be processed
|
|
390
|
-
* @returns
|
|
391
|
-
*/
|
|
392
|
-
addSavers(assetAmount, memo, toAddress) {
|
|
393
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
394
|
-
const assetClient = this.clients[assetAmount.asset.chain];
|
|
395
|
-
if (this.isEVMChain(assetAmount.asset)) {
|
|
396
|
-
const addParams = {
|
|
397
|
-
wallIndex: 0,
|
|
398
|
-
asset: assetAmount.asset,
|
|
399
|
-
amount: assetAmount.baseAmount,
|
|
400
|
-
feeOption: xchainClient.FeeOption.Fast,
|
|
401
|
-
memo: memo,
|
|
402
|
-
};
|
|
403
|
-
const evmHelper = new EvmHelper(assetClient, this.thorchainQuery.thorchainCache);
|
|
404
|
-
const hash = yield evmHelper.sendDeposit(addParams);
|
|
405
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
406
|
-
}
|
|
407
|
-
else if (this.isUTXOChain(assetAmount.asset)) {
|
|
408
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
409
|
-
const addParams = {
|
|
410
|
-
wallIndex: 0,
|
|
411
|
-
asset: assetAmount.asset,
|
|
412
|
-
amount: assetAmount.baseAmount,
|
|
413
|
-
recipient: toAddress,
|
|
414
|
-
memo: memo,
|
|
415
|
-
feeRate: feeRates.fast,
|
|
416
|
-
};
|
|
417
|
-
try {
|
|
418
|
-
const hash = yield assetClient.transfer(addParams);
|
|
419
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
420
|
-
}
|
|
421
|
-
catch (err) {
|
|
422
|
-
const hash = JSON.stringify(err);
|
|
423
|
-
return { hash, url: assetClient.getExplorerAddressUrl(assetClient.getAddress()) };
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
const addParams = {
|
|
428
|
-
wallIndex: 0,
|
|
429
|
-
asset: assetAmount.asset,
|
|
430
|
-
amount: assetAmount.baseAmount,
|
|
431
|
-
recipient: toAddress,
|
|
432
|
-
memo: memo,
|
|
433
|
-
};
|
|
434
|
-
try {
|
|
435
|
-
const hash = yield assetClient.transfer(addParams);
|
|
436
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
437
|
-
}
|
|
438
|
-
catch (err) {
|
|
439
|
-
const hash = JSON.stringify(err);
|
|
440
|
-
return { hash, url: assetClient.getExplorerAddressUrl(assetClient.getAddress()) };
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
*
|
|
447
|
-
* @param assetAmount - amount to withdraw
|
|
448
|
-
* @param memo - memo required
|
|
449
|
-
* @param waitTimeSeconds - expected wait for the transaction to be processed
|
|
450
|
-
* @returns
|
|
451
|
-
*/
|
|
452
|
-
withdrawSavers(assetAmount, memo, toAddress) {
|
|
52
|
+
const isProtocolEVMChain = (chain) => {
|
|
53
|
+
return [xchainEthereum.AssetETH.chain, xchainBsc.AssetBSC.chain, xchainAvax.AssetAVAX.chain].includes(chain);
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Check if asset is ERC20
|
|
57
|
+
* @param {Asset} asset to check
|
|
58
|
+
* @returns true if asset is ERC20, otherwise, false
|
|
59
|
+
*/
|
|
60
|
+
const isProtocolERC20Asset = (asset) => {
|
|
61
|
+
return isProtocolEVMChain(asset.chain)
|
|
62
|
+
? ![xchainEthereum.AssetETH.symbol, xchainAvax.AssetAVAX.symbol, xchainBsc.AssetBSC.symbol].includes(asset.symbol)
|
|
63
|
+
: false;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Check if a chain is EVM and supported by the protocol
|
|
67
|
+
* @param {Chain} chain to check
|
|
68
|
+
* @returns true if chain is EVM, otherwise, false
|
|
69
|
+
*/
|
|
70
|
+
const isProtocolBFTChain = (chain) => {
|
|
71
|
+
return [xchainBinance.AssetBNB.chain, xchainCosmos.AssetATOM.chain].includes(chain);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
class ThorchainAction {
|
|
75
|
+
static makeAction(actionParams) {
|
|
453
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
wallIndex: 0,
|
|
458
|
-
asset: assetAmount.asset,
|
|
459
|
-
amount: assetAmount.baseAmount,
|
|
460
|
-
feeOption: xchainClient.FeeOption.Fast,
|
|
461
|
-
memo: memo,
|
|
462
|
-
};
|
|
463
|
-
const evmHelper = new EvmHelper(assetClient, this.thorchainQuery.thorchainCache);
|
|
464
|
-
const hash = yield evmHelper.sendDeposit(addParams);
|
|
465
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
466
|
-
}
|
|
467
|
-
else if (this.isUTXOChain(assetAmount.asset)) {
|
|
468
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
469
|
-
const addParams = {
|
|
470
|
-
wallIndex: 0,
|
|
471
|
-
asset: assetAmount.asset,
|
|
472
|
-
amount: assetAmount.baseAmount,
|
|
473
|
-
recipient: toAddress,
|
|
474
|
-
memo: memo,
|
|
475
|
-
feeRate: feeRates.fast,
|
|
476
|
-
};
|
|
477
|
-
try {
|
|
478
|
-
const hash = yield assetClient.transfer(addParams);
|
|
479
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
480
|
-
}
|
|
481
|
-
catch (err) {
|
|
482
|
-
const hash = JSON.stringify(err);
|
|
483
|
-
return { hash, url: yield assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
const addParams = {
|
|
488
|
-
wallIndex: 0,
|
|
489
|
-
asset: assetAmount.asset,
|
|
490
|
-
amount: assetAmount.baseAmount,
|
|
491
|
-
recipient: toAddress,
|
|
492
|
-
memo: memo,
|
|
493
|
-
};
|
|
494
|
-
try {
|
|
495
|
-
const hash = yield assetClient.transfer(addParams);
|
|
496
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
497
|
-
}
|
|
498
|
-
catch (err) {
|
|
499
|
-
const hash = JSON.stringify(err);
|
|
500
|
-
return { hash, url: yield assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
501
|
-
}
|
|
502
|
-
}
|
|
77
|
+
return this.isNonProtocolParams(actionParams)
|
|
78
|
+
? this.makeNonProtocolAction(actionParams)
|
|
79
|
+
: this.makeProtocolAction(actionParams);
|
|
503
80
|
});
|
|
504
81
|
}
|
|
505
|
-
|
|
82
|
+
static makeProtocolAction({ wallet, assetAmount, memo }) {
|
|
506
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
amount: params.amount.baseAmount,
|
|
513
|
-
feeOption: xchainClient.FeeOption.Fast,
|
|
514
|
-
memo: params.memo,
|
|
515
|
-
};
|
|
516
|
-
const evmHelper = new EvmHelper(assetClient, this.thorchainQuery.thorchainCache);
|
|
517
|
-
const hash = yield evmHelper.sendDeposit(addParams);
|
|
518
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
519
|
-
}
|
|
520
|
-
else if (this.isUTXOChain(params.amount.asset)) {
|
|
521
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
522
|
-
const addParams = {
|
|
523
|
-
wallIndex: 0,
|
|
524
|
-
asset: params.amount.asset,
|
|
525
|
-
amount: params.amount.baseAmount,
|
|
526
|
-
recipient: params.toAddress,
|
|
527
|
-
memo: params.memo,
|
|
528
|
-
feeRate: feeRates.fast,
|
|
529
|
-
};
|
|
530
|
-
try {
|
|
531
|
-
const hash = yield assetClient.transfer(addParams);
|
|
532
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
533
|
-
}
|
|
534
|
-
catch (err) {
|
|
535
|
-
const hash = JSON.stringify(err);
|
|
536
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
else {
|
|
540
|
-
const addParams = {
|
|
541
|
-
wallIndex: 0,
|
|
542
|
-
asset: params.amount.asset,
|
|
543
|
-
amount: params.amount.baseAmount,
|
|
544
|
-
recipient: params.toAddress,
|
|
545
|
-
memo: params.memo,
|
|
546
|
-
};
|
|
547
|
-
try {
|
|
548
|
-
const hash = yield assetClient.transfer(addParams);
|
|
549
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
550
|
-
}
|
|
551
|
-
catch (err) {
|
|
552
|
-
const hash = JSON.stringify(err);
|
|
553
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
554
|
-
}
|
|
555
|
-
}
|
|
84
|
+
const hash = yield wallet.deposit({ asset: assetAmount.asset, amount: assetAmount.baseAmount, memo });
|
|
85
|
+
return {
|
|
86
|
+
hash,
|
|
87
|
+
url: yield wallet.getExplorerTxUrl(assetAmount.asset.chain, hash),
|
|
88
|
+
};
|
|
556
89
|
});
|
|
557
90
|
}
|
|
558
|
-
|
|
559
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
560
|
-
|
|
561
|
-
if (
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
else if (this.isUTXOChain(params.amount.asset)) {
|
|
574
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
575
|
-
const addParams = {
|
|
576
|
-
wallIndex: 0,
|
|
577
|
-
asset: params.amount.asset,
|
|
578
|
-
amount: params.amount.baseAmount,
|
|
579
|
-
recipient: params.toAddress,
|
|
580
|
-
memo: params.memo,
|
|
581
|
-
feeRate: feeRates.average,
|
|
582
|
-
};
|
|
583
|
-
try {
|
|
584
|
-
const hash = yield assetClient.transfer(addParams);
|
|
585
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
586
|
-
}
|
|
587
|
-
catch (err) {
|
|
588
|
-
const hash = JSON.stringify(err);
|
|
589
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
91
|
+
static makeNonProtocolAction({ wallet, assetAmount, recipient, memo, }) {
|
|
92
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
93
|
+
// Non ERC20 swaps
|
|
94
|
+
if (!isProtocolERC20Asset(assetAmount.asset)) {
|
|
95
|
+
if (isProtocolBFTChain(assetAmount.asset.chain)) {
|
|
96
|
+
const hash = yield wallet.transfer({
|
|
97
|
+
asset: assetAmount.asset,
|
|
98
|
+
amount: assetAmount.baseAmount,
|
|
99
|
+
recipient,
|
|
100
|
+
memo,
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
hash,
|
|
104
|
+
url: yield wallet.getExplorerTxUrl(assetAmount.asset.chain, hash),
|
|
105
|
+
};
|
|
590
106
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
107
|
+
const feeRates = yield wallet.getFeeRates(assetAmount.asset.chain, xchainClient.Protocol.THORCHAIN);
|
|
108
|
+
const hash = yield wallet.transfer(isProtocolEVMChain(assetAmount.asset.chain)
|
|
109
|
+
? {
|
|
110
|
+
asset: assetAmount.asset,
|
|
111
|
+
amount: assetAmount.baseAmount,
|
|
112
|
+
recipient,
|
|
113
|
+
memo,
|
|
114
|
+
gasPrice: feeRates.fast,
|
|
115
|
+
}
|
|
116
|
+
: {
|
|
117
|
+
asset: assetAmount.asset,
|
|
118
|
+
amount: assetAmount.baseAmount,
|
|
119
|
+
recipient,
|
|
120
|
+
memo,
|
|
121
|
+
feeRate: feeRates.fast,
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
hash,
|
|
125
|
+
url: yield wallet.getExplorerTxUrl(assetAmount.asset.chain, hash),
|
|
599
126
|
};
|
|
600
|
-
try {
|
|
601
|
-
const hash = yield assetClient.transfer(addParams);
|
|
602
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
603
|
-
}
|
|
604
|
-
catch (err) {
|
|
605
|
-
const hash = JSON.stringify(err);
|
|
606
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
/**
|
|
612
|
-
* Register a THORName with a default expirity of one year. By default chain and chainAddress is getting from wallet instance and is BTC.
|
|
613
|
-
* By default owner is getting from wallet
|
|
614
|
-
* @param thorname - Name to register
|
|
615
|
-
* @param chain - Chain to add alias
|
|
616
|
-
* @param chainAddress - Address to add to chain alias
|
|
617
|
-
* @param owner - Owner address (rune address)
|
|
618
|
-
* @param preferredAsset - referred asset
|
|
619
|
-
* @param expirity - expirity of the domain in MILLISECONDS
|
|
620
|
-
* @param isUpdate - true only if the domain is already register and you want to update its data
|
|
621
|
-
* @returns memo and value of deposit
|
|
622
|
-
*/
|
|
623
|
-
registerThorname(params) {
|
|
624
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
625
|
-
const chainClient = this.clients[params.chain || xchainBitcoin.BTCChain];
|
|
626
|
-
const thorClient = this.clients.THOR;
|
|
627
|
-
if (!chainClient || !thorClient) {
|
|
628
|
-
throw Error('Can not find a wallet client');
|
|
629
127
|
}
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
128
|
+
// ERC20 swaps
|
|
129
|
+
const thorchainQuery = new xchainThorchainQuery.ThorchainQuery(new xchainThorchainQuery.ThorchainCache(new xchainThorchainQuery.Thornode(wallet.getNetwork())));
|
|
130
|
+
const inboundDetails = yield thorchainQuery.getChainInboundDetails(assetAmount.asset.chain);
|
|
131
|
+
if (!inboundDetails.router)
|
|
132
|
+
throw Error(`Unknown router for ${assetAmount.asset.chain} chain`);
|
|
133
|
+
const contractAddress = xchainUtil.getContractAddressFromAsset(assetAmount.asset);
|
|
134
|
+
const checkSummedContractAddress = ethers.ethers.utils.getAddress(contractAddress);
|
|
135
|
+
const expiration = Math.floor(new Date(new Date().getTime() + 15 * 60000).getTime() / 1000);
|
|
136
|
+
const depositParams = [
|
|
137
|
+
recipient,
|
|
138
|
+
checkSummedContractAddress,
|
|
139
|
+
assetAmount.baseAmount.amount().toFixed(),
|
|
140
|
+
memo,
|
|
141
|
+
expiration,
|
|
142
|
+
];
|
|
143
|
+
const routerContract = new ethers.ethers.Contract(inboundDetails.router, xchainEvm.abi.router);
|
|
144
|
+
const chainWallet = wallet.getChainWallet(assetAmount.asset.chain);
|
|
145
|
+
const gasPrices = yield wallet.getFeeRates(assetAmount.asset.chain);
|
|
146
|
+
const unsignedTx = yield routerContract.populateTransaction.depositWithExpiry(...depositParams, {
|
|
147
|
+
from: wallet.getAddress(assetAmount.asset.chain),
|
|
148
|
+
value: 0,
|
|
149
|
+
gasPrice: gasPrices.fast.amount().toFixed(),
|
|
150
|
+
gasLimit: '160000',
|
|
636
151
|
});
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
* Register a THORName with a default expirity of one year. By default chain and chainAddress is getting from wallet instance and is BTC.
|
|
642
|
-
* By default owner is getting from wallet
|
|
643
|
-
* @param thorname - Name to register
|
|
644
|
-
* @param chain - Chain to add alias
|
|
645
|
-
* @param chainAddress - Address to add to chain alias
|
|
646
|
-
* @param owner - Owner address (rune address)
|
|
647
|
-
* @param preferredAsset - referred asset
|
|
648
|
-
* @param expirity - expirity of the domain in MILLISECONDS
|
|
649
|
-
* @returns memo and value of deposit
|
|
650
|
-
*/
|
|
651
|
-
updateThorname(params) {
|
|
652
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
653
|
-
const chainClient = this.clients[params.chain || xchainBitcoin.BTCChain];
|
|
654
|
-
const thorClient = this.clients.THOR;
|
|
655
|
-
if (!chainClient || !thorClient) {
|
|
656
|
-
throw Error('Can not find a wallet client');
|
|
657
|
-
}
|
|
658
|
-
const thornameDetail = yield this.thorchainQuery.getThornameDetails(params.thorname);
|
|
659
|
-
if ((thornameDetail === null || thornameDetail === void 0 ? void 0 : thornameDetail.owner) !== (yield thorClient.getAddressAsync())) {
|
|
660
|
-
throw Error('You cannot update a domain that is not yours');
|
|
661
|
-
}
|
|
662
|
-
const thornameEstimation = yield this.thorchainQuery.estimateThorname(Object.assign(Object.assign({}, params), { chain: params.chain || xchainBitcoin.BTCChain, isUpdate: true, preferredAsset: params.preferredAsset || xchainUtil.assetFromString(thornameDetail.preferredAsset), chainAddress: params.chainAddress || (yield chainClient.getAddressAsync()) }));
|
|
663
|
-
const castedThorClient = thorClient;
|
|
664
|
-
const result = yield castedThorClient.deposit({
|
|
665
|
-
asset: thornameEstimation.value.asset,
|
|
666
|
-
amount: thornameEstimation.value.baseAmount,
|
|
667
|
-
memo: thornameEstimation.memo,
|
|
668
|
-
});
|
|
669
|
-
return result;
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
/** Function handles liquidity add for all non rune assets
|
|
673
|
-
*
|
|
674
|
-
* @param params - parameters for add liquidity
|
|
675
|
-
* @param constructedMemo - memo needed for thorchain
|
|
676
|
-
* @param waitTimeSeconds - wait time for the tx to be confirmed
|
|
677
|
-
* @param assetClient - passing XchainClient
|
|
678
|
-
* @param inboundAsgard - inbound Asgard address for the LP
|
|
679
|
-
* @returns - tx object
|
|
680
|
-
*/
|
|
681
|
-
addAssetLP(params, constructedMemo, assetClient, inboundAsgard) {
|
|
682
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
683
|
-
if (this.isEVMChain(params.asset.asset)) {
|
|
684
|
-
const addParams = {
|
|
685
|
-
wallIndex: 0,
|
|
686
|
-
asset: params.asset.asset,
|
|
687
|
-
amount: params.asset.baseAmount,
|
|
688
|
-
feeOption: xchainClient.FeeOption.Fast,
|
|
689
|
-
memo: constructedMemo,
|
|
690
|
-
};
|
|
691
|
-
const evmHelper = new EvmHelper(assetClient, this.thorchainQuery.thorchainCache);
|
|
692
|
-
const hash = yield evmHelper.sendDeposit(addParams);
|
|
693
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
694
|
-
}
|
|
695
|
-
else if (this.isUTXOChain(params.asset.asset)) {
|
|
696
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
697
|
-
const addParams = {
|
|
698
|
-
wallIndex: 0,
|
|
699
|
-
asset: params.asset.asset,
|
|
700
|
-
amount: params.asset.baseAmount,
|
|
701
|
-
recipient: inboundAsgard,
|
|
702
|
-
memo: constructedMemo,
|
|
703
|
-
feeRate: feeRates.fast,
|
|
704
|
-
};
|
|
705
|
-
try {
|
|
706
|
-
const hash = yield assetClient.transfer(addParams);
|
|
707
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
708
|
-
}
|
|
709
|
-
catch (err) {
|
|
710
|
-
const hash = JSON.stringify(err);
|
|
711
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
else {
|
|
715
|
-
const addParams = {
|
|
716
|
-
wallIndex: 0,
|
|
717
|
-
asset: params.asset.asset,
|
|
718
|
-
amount: params.asset.baseAmount,
|
|
719
|
-
recipient: inboundAsgard,
|
|
720
|
-
memo: constructedMemo,
|
|
721
|
-
};
|
|
722
|
-
try {
|
|
723
|
-
const hash = yield assetClient.transfer(addParams);
|
|
724
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
725
|
-
}
|
|
726
|
-
catch (err) {
|
|
727
|
-
const hash = JSON.stringify(err);
|
|
728
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
/** Function handles liquidity Withdraw for Non rune assets
|
|
734
|
-
*
|
|
735
|
-
* @param params - parameters for withdraw liquidity
|
|
736
|
-
* @param constructedMemo - memo needed for thorchain execution
|
|
737
|
-
* @param assetClient - asset client to call transfer
|
|
738
|
-
* @param waitTimeSeconds - return back estimated wait
|
|
739
|
-
* @param inboundAsgard - destination address
|
|
740
|
-
* @returns - tx object
|
|
741
|
-
*/
|
|
742
|
-
withdrawAssetLP(params, constructedMemo, assetClient, inboundAsgard) {
|
|
743
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
744
|
-
if (this.isEVMChain(params.assetFee.asset)) {
|
|
745
|
-
const withdrawParams = {
|
|
746
|
-
wallIndex: 0,
|
|
747
|
-
asset: params.assetFee.asset,
|
|
748
|
-
amount: params.assetFee.baseAmount,
|
|
749
|
-
feeOption: xchainClient.FeeOption.Fast,
|
|
750
|
-
memo: constructedMemo,
|
|
751
|
-
};
|
|
752
|
-
const evmHelper = new EvmHelper(assetClient, this.thorchainQuery.thorchainCache);
|
|
753
|
-
const hash = yield evmHelper.sendDeposit(withdrawParams);
|
|
754
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
755
|
-
}
|
|
756
|
-
else if (this.isUTXOChain(params.assetFee.asset)) {
|
|
757
|
-
const feeRates = yield assetClient.getFeeRates(xchainClient.Protocol.THORCHAIN);
|
|
758
|
-
const withdrawParams = {
|
|
759
|
-
wallIndex: 0,
|
|
760
|
-
asset: params.assetFee.asset,
|
|
761
|
-
amount: params.assetFee.baseAmount,
|
|
762
|
-
recipient: inboundAsgard,
|
|
763
|
-
memo: constructedMemo,
|
|
764
|
-
feeRate: feeRates.fast,
|
|
765
|
-
};
|
|
766
|
-
try {
|
|
767
|
-
const hash = yield assetClient.transfer(withdrawParams);
|
|
768
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
769
|
-
}
|
|
770
|
-
catch (err) {
|
|
771
|
-
const hash = JSON.stringify(err);
|
|
772
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
else {
|
|
776
|
-
const withdrawParams = {
|
|
777
|
-
wallIndex: 0,
|
|
778
|
-
asset: params.assetFee.asset,
|
|
779
|
-
amount: params.assetFee.baseAmount,
|
|
780
|
-
recipient: inboundAsgard,
|
|
781
|
-
memo: constructedMemo,
|
|
782
|
-
};
|
|
783
|
-
try {
|
|
784
|
-
const hash = yield assetClient.transfer(withdrawParams);
|
|
785
|
-
return { hash, url: assetClient.getExplorerTxUrl(hash) };
|
|
786
|
-
}
|
|
787
|
-
catch (err) {
|
|
788
|
-
const hash = JSON.stringify(err);
|
|
789
|
-
return { hash, url: assetClient.getExplorerAddressUrl(yield assetClient.getAddressAsync()) };
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
});
|
|
793
|
-
}
|
|
794
|
-
/** Function handles liquidity Add for Rune only
|
|
795
|
-
*
|
|
796
|
-
* @param params - deposit parameters
|
|
797
|
-
* @param memo - memo needed to withdraw lp
|
|
798
|
-
* @returns - tx object
|
|
799
|
-
*/
|
|
800
|
-
addRuneLP(params, memo, thorchainClient) {
|
|
801
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
802
|
-
const thorClient = this.clients.THOR;
|
|
803
|
-
const addParams = {
|
|
804
|
-
asset: params.rune.asset,
|
|
805
|
-
amount: params.rune.baseAmount,
|
|
806
|
-
memo: memo,
|
|
807
|
-
};
|
|
808
|
-
const hash = yield thorClient.deposit(addParams);
|
|
809
|
-
return { hash, url: thorchainClient.getExplorerTxUrl(hash) };
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
/** Function handles liquidity Withdraw for Rune only
|
|
813
|
-
*
|
|
814
|
-
* @param params - withdraw parameters
|
|
815
|
-
* @param memo - memo needed to withdraw lp
|
|
816
|
-
* @returns - tx object
|
|
817
|
-
*/
|
|
818
|
-
withdrawRuneLP(params, memo, thorchainClient) {
|
|
819
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
820
|
-
const thorClient = this.clients.THOR;
|
|
821
|
-
const addParams = {
|
|
822
|
-
asset: params.runeFee.asset,
|
|
823
|
-
amount: params.runeFee.baseAmount,
|
|
824
|
-
memo: memo,
|
|
152
|
+
const { hash } = yield chainWallet.sendTransaction(unsignedTx);
|
|
153
|
+
return {
|
|
154
|
+
hash,
|
|
155
|
+
url: yield wallet.getExplorerTxUrl(assetAmount.asset.chain, hash),
|
|
825
156
|
};
|
|
826
|
-
const hash = yield thorClient.deposit(addParams);
|
|
827
|
-
return { hash, url: thorchainClient.getExplorerTxUrl(hash) };
|
|
828
157
|
});
|
|
829
158
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
return
|
|
837
|
-
}
|
|
838
|
-
isUTXOChain(asset) {
|
|
839
|
-
return ['BTC', 'BCH', 'DOGE'].includes(asset.chain);
|
|
159
|
+
static isNonProtocolParams(params) {
|
|
160
|
+
if ((params.assetAmount.asset.chain === xchainThorchain.THORChain || params.assetAmount.asset.synth) &&
|
|
161
|
+
'address' in params &&
|
|
162
|
+
!!params.address) {
|
|
163
|
+
throw Error('Inconsistent params. Native actions do not support recipient');
|
|
164
|
+
}
|
|
165
|
+
return params.assetAmount.asset.chain !== xchainThorchain.THORChain && !params.assetAmount.asset.synth;
|
|
840
166
|
}
|
|
841
167
|
}
|
|
842
168
|
|
|
843
|
-
const defaultQuery = new xchainThorchainQuery.ThorchainQuery();
|
|
844
169
|
/**
|
|
845
170
|
* THORChain Class for interacting with THORChain.
|
|
846
171
|
* Recommended main class to use for swapping with THORChain
|
|
@@ -848,79 +173,144 @@ const defaultQuery = new xchainThorchainQuery.ThorchainQuery();
|
|
|
848
173
|
*/
|
|
849
174
|
class ThorchainAMM {
|
|
850
175
|
/**
|
|
851
|
-
*
|
|
176
|
+
* Constructor to create a ThorchainAMM instance
|
|
852
177
|
*
|
|
853
178
|
* @param thorchainQuery - an instance of the ThorchainQuery
|
|
854
179
|
* @returns ThorchainAMM
|
|
855
180
|
*/
|
|
856
|
-
constructor(thorchainQuery =
|
|
181
|
+
constructor(thorchainQuery = new xchainThorchainQuery.ThorchainQuery(), wallet = new xchainWallet.Wallet({
|
|
182
|
+
BTC: new xchainBitcoin.Client(Object.assign(Object.assign({}, xchainBitcoin.defaultBTCParams), { network: xchainClient.Network.Mainnet })),
|
|
183
|
+
BCH: new xchainBitcoincash.Client(Object.assign(Object.assign({}, xchainBitcoincash.defaultBchParams), { network: xchainClient.Network.Mainnet })),
|
|
184
|
+
LTC: new xchainLitecoin.Client(Object.assign(Object.assign({}, xchainLitecoin.defaultLtcParams), { network: xchainClient.Network.Mainnet })),
|
|
185
|
+
DOGE: new xchainDoge.Client(Object.assign(Object.assign({}, xchainDoge.defaultDogeParams), { network: xchainClient.Network.Mainnet })),
|
|
186
|
+
ETH: new xchainEthereum.Client(Object.assign(Object.assign({}, xchainEthereum.defaultEthParams), { network: xchainClient.Network.Mainnet })),
|
|
187
|
+
AVAX: new xchainAvax.Client(Object.assign(Object.assign({}, xchainAvax.defaultAvaxParams), { network: xchainClient.Network.Mainnet })),
|
|
188
|
+
BSC: new xchainBsc.Client(Object.assign(Object.assign({}, xchainBsc.defaultBscParams), { network: xchainClient.Network.Mainnet })),
|
|
189
|
+
GAIA: new xchainCosmos.Client({ network: xchainClient.Network.Mainnet }),
|
|
190
|
+
BNB: new xchainBinance.Client({ network: xchainClient.Network.Mainnet }),
|
|
191
|
+
THOR: new xchainThorchain.Client(Object.assign(Object.assign({}, xchainThorchain.defaultClientConfig), { network: xchainClient.Network.Mainnet })),
|
|
192
|
+
})) {
|
|
857
193
|
this.thorchainQuery = thorchainQuery;
|
|
194
|
+
this.wallet = wallet;
|
|
858
195
|
}
|
|
859
196
|
/**
|
|
860
|
-
* Provides
|
|
861
|
-
*
|
|
862
|
-
*
|
|
863
|
-
*
|
|
197
|
+
* * Provides an estimate for a swap based on the given swap details.
|
|
198
|
+
* Checks the parameters for errors before attempting to retrieve the estimate.
|
|
199
|
+
* Utilizes current pool data to calculate inbound and outbound fees, affiliate fees,
|
|
200
|
+
* and the expected wait time for the swap (inbound and outbound).
|
|
201
|
+
* @param params Parameters for the swap, including the amount to swap.
|
|
864
202
|
|
|
865
|
-
* @returns The
|
|
203
|
+
* @returns The estimated swap details.
|
|
866
204
|
*/
|
|
867
|
-
estimateSwap({ fromAsset, amount, destinationAsset, destinationAddress, affiliateAddress = '',
|
|
205
|
+
estimateSwap({ fromAddress, fromAsset, amount, destinationAsset, destinationAddress, affiliateAddress = '', affiliateBps = 0, toleranceBps, }) {
|
|
868
206
|
return __awaiter(this, void 0, void 0, function* () {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
waitTimeSeconds: 100,
|
|
877
|
-
walletIndex,
|
|
878
|
-
};
|
|
879
|
-
errors = yield wallet.validateSwap(params);
|
|
880
|
-
}
|
|
207
|
+
const errors = yield this.validateSwap({
|
|
208
|
+
fromAddress,
|
|
209
|
+
fromAsset,
|
|
210
|
+
amount,
|
|
211
|
+
destinationAsset,
|
|
212
|
+
destinationAddress,
|
|
213
|
+
});
|
|
881
214
|
const estimate = yield this.thorchainQuery.quoteSwap({
|
|
882
215
|
fromAsset,
|
|
883
216
|
amount,
|
|
884
217
|
destinationAsset,
|
|
885
218
|
destinationAddress,
|
|
886
219
|
affiliateAddress,
|
|
887
|
-
interfaceID,
|
|
888
220
|
affiliateBps,
|
|
889
221
|
toleranceBps,
|
|
890
222
|
});
|
|
223
|
+
// Add any validation errors to the estimate
|
|
891
224
|
estimate.txEstimate.errors.push(...errors);
|
|
892
|
-
estimate.txEstimate.canSwap = errors.length
|
|
225
|
+
estimate.txEstimate.canSwap = estimate.txEstimate.errors.length === 0;
|
|
893
226
|
return estimate;
|
|
894
227
|
});
|
|
895
228
|
}
|
|
896
229
|
/**
|
|
897
|
-
*
|
|
230
|
+
* Validate swap params
|
|
231
|
+
* @param {QuoteSwapParams} quoteSwapParams Swap params
|
|
232
|
+
* @returns {string[]} the reasons the swap can not be done. If it is empty there are no reason to avoid the swap
|
|
233
|
+
*/
|
|
234
|
+
validateSwap({ fromAsset, fromAddress, destinationAsset, destinationAddress, amount, affiliateAddress, affiliateBps, }) {
|
|
235
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
236
|
+
const errors = [];
|
|
237
|
+
if (destinationAddress && !this.wallet.validateAddress(destinationAsset.chain, destinationAddress)) {
|
|
238
|
+
errors.push(`destinationAddress ${destinationAddress} is not a valid address`);
|
|
239
|
+
}
|
|
240
|
+
if (affiliateAddress) {
|
|
241
|
+
const isThorAddress = this.wallet.validateAddress(xchainThorchain.THORChain, affiliateAddress);
|
|
242
|
+
const isThorname = !!(yield this.thorchainQuery.thorchainCache.midgardQuery.midgardCache.midgard.getTHORNameDetails(affiliateAddress));
|
|
243
|
+
if (!(isThorAddress || isThorname))
|
|
244
|
+
errors.push(`affiliateAddress ${affiliateAddress} is not a valid THOR address`);
|
|
245
|
+
}
|
|
246
|
+
if (affiliateBps && (affiliateBps < 0 || affiliateBps > 10000)) {
|
|
247
|
+
errors.push(`affiliateBps ${affiliateBps} out of range [0 - 10000]`);
|
|
248
|
+
}
|
|
249
|
+
if (isProtocolERC20Asset(fromAsset) && fromAddress) {
|
|
250
|
+
const approveErrors = yield this.isRouterApprovedToSpend({
|
|
251
|
+
asset: fromAsset,
|
|
252
|
+
address: fromAddress,
|
|
253
|
+
amount,
|
|
254
|
+
});
|
|
255
|
+
errors.push(...approveErrors);
|
|
256
|
+
}
|
|
257
|
+
return errors;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Conducts a swap with the given inputs. This method should be called after estimateSwap() to ensure the swap is valid.
|
|
898
262
|
*
|
|
899
|
-
* @param wallet - wallet to use
|
|
900
|
-
* @param params - swap
|
|
901
|
-
* @returns {SwapSubmitted} -
|
|
263
|
+
* @param wallet - The wallet to use for the swap.
|
|
264
|
+
* @param params - The swap parameters.
|
|
265
|
+
* @returns {SwapSubmitted} - The transaction hash, URL of BlockExplorer, and expected wait time.
|
|
902
266
|
*/
|
|
903
|
-
doSwap(
|
|
267
|
+
doSwap({ fromAsset, fromAddress, amount, destinationAsset, destinationAddress, affiliateAddress, affiliateBps, toleranceBps, }) {
|
|
904
268
|
return __awaiter(this, void 0, void 0, function* () {
|
|
905
|
-
//
|
|
906
|
-
const txDetails = yield this.thorchainQuery.quoteSwap(
|
|
269
|
+
// Retrieve swap details from ThorchainQuery to ensure validity
|
|
270
|
+
const txDetails = yield this.thorchainQuery.quoteSwap({
|
|
271
|
+
fromAsset,
|
|
272
|
+
fromAddress,
|
|
273
|
+
amount,
|
|
274
|
+
destinationAsset,
|
|
275
|
+
destinationAddress,
|
|
276
|
+
affiliateAddress,
|
|
277
|
+
affiliateBps,
|
|
278
|
+
toleranceBps,
|
|
279
|
+
});
|
|
907
280
|
if (!txDetails.txEstimate.canSwap) {
|
|
908
281
|
throw Error(txDetails.txEstimate.errors.join('\n'));
|
|
909
282
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
283
|
+
// Execute the swap using Thorchain action
|
|
284
|
+
return ThorchainAction.makeAction({
|
|
285
|
+
wallet: this.wallet,
|
|
286
|
+
assetAmount: amount,
|
|
914
287
|
memo: txDetails.memo,
|
|
915
|
-
|
|
916
|
-
feeOption: params.feeOption,
|
|
288
|
+
recipient: txDetails.toAddress,
|
|
917
289
|
});
|
|
918
290
|
});
|
|
919
291
|
}
|
|
920
292
|
/**
|
|
921
|
-
*
|
|
922
|
-
* @param
|
|
923
|
-
*
|
|
293
|
+
* Validate if the asset router is allowed to spend the asset amount in name of the address
|
|
294
|
+
* @param {IsApprovedParams} isApprovedParams contains the asset and the amount the router is supposed to spend
|
|
295
|
+
* int name of address
|
|
296
|
+
* @returns {string[]} the reasons the router of the asset is not allowed to spend the amount. If it is empty, the asset router is allowed to spend the amount
|
|
297
|
+
*/
|
|
298
|
+
isRouterApprovedToSpend({ asset, amount, address }) {
|
|
299
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
300
|
+
const errors = [];
|
|
301
|
+
const inboundDetails = yield this.thorchainQuery.getChainInboundDetails(asset.chain);
|
|
302
|
+
if (!inboundDetails.router)
|
|
303
|
+
throw Error(`Unknown router address for ${asset.chain}`);
|
|
304
|
+
const isApprovedResult = yield this.wallet.isApproved(asset, amount.baseAmount, address, inboundDetails.router);
|
|
305
|
+
if (!isApprovedResult)
|
|
306
|
+
errors.push('Thorchain router has not been approved to spend this amount');
|
|
307
|
+
return errors;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Wraps the estimate from ThorchainQuery for adding liquidity.
|
|
312
|
+
* @param params - The parameters for estimating adding liquidity.
|
|
313
|
+
* @returns - The estimated liquidity addition object.
|
|
924
314
|
*/
|
|
925
315
|
estimateAddLiquidity(params) {
|
|
926
316
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -928,9 +318,9 @@ class ThorchainAMM {
|
|
|
928
318
|
});
|
|
929
319
|
}
|
|
930
320
|
/**
|
|
931
|
-
* Wraps estimate
|
|
932
|
-
* @param params -
|
|
933
|
-
* @returns -
|
|
321
|
+
* Wraps the estimate from ThorchainQuery for withdrawing liquidity.
|
|
322
|
+
* @param params - The parameters for estimating withdrawing liquidity.
|
|
323
|
+
* @returns - The estimated liquidity withdrawal object.
|
|
934
324
|
*/
|
|
935
325
|
estimateWithdrawLiquidity(params) {
|
|
936
326
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -938,36 +328,75 @@ class ThorchainAMM {
|
|
|
938
328
|
});
|
|
939
329
|
}
|
|
940
330
|
/**
|
|
941
|
-
*
|
|
942
|
-
* @param wallet -
|
|
943
|
-
* @param params -
|
|
331
|
+
* If there is no existing liquidity position, it is created automatically.
|
|
332
|
+
* @param wallet - Wallet class
|
|
333
|
+
* @param params - Liquidity parameter
|
|
944
334
|
* @returns
|
|
945
335
|
*/
|
|
946
|
-
addLiquidityPosition(
|
|
336
|
+
addLiquidityPosition(params) {
|
|
947
337
|
return __awaiter(this, void 0, void 0, function* () {
|
|
948
338
|
// Check amounts are greater than fees and use return estimated wait
|
|
949
339
|
const checkLPAdd = yield this.thorchainQuery.estimateAddLP(params);
|
|
950
340
|
if (!checkLPAdd.canAdd)
|
|
951
341
|
throw Error(`${checkLPAdd.errors}`);
|
|
952
|
-
|
|
342
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain]
|
|
343
|
+
.address;
|
|
344
|
+
const addressRune = yield this.wallet.getAddress(xchainThorchain.THORChain);
|
|
345
|
+
const addressAsset = yield this.wallet.getAddress(params.asset.asset.chain);
|
|
346
|
+
// const waitTimeSeconds = params.waitTimeSeconds
|
|
347
|
+
const txSubmitted = [];
|
|
348
|
+
const addLiquidity = {
|
|
953
349
|
asset: params.asset,
|
|
954
350
|
rune: params.rune,
|
|
955
351
|
waitTimeSeconds: checkLPAdd.estimatedWaitSeconds,
|
|
956
352
|
assetPool: checkLPAdd.assetPool,
|
|
957
|
-
}
|
|
353
|
+
};
|
|
354
|
+
// symmetrical add
|
|
355
|
+
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
356
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
357
|
+
wallet: this.wallet,
|
|
358
|
+
memo: `+:${checkLPAdd.assetPool}:${addressRune}`,
|
|
359
|
+
assetAmount: addLiquidity.asset,
|
|
360
|
+
recipient: inboundAsgard,
|
|
361
|
+
}));
|
|
362
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
363
|
+
wallet: this.wallet,
|
|
364
|
+
memo: `+:${checkLPAdd.assetPool}:${addressAsset}`,
|
|
365
|
+
assetAmount: addLiquidity.rune,
|
|
366
|
+
}));
|
|
367
|
+
return txSubmitted;
|
|
368
|
+
}
|
|
369
|
+
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
370
|
+
// asymmetrical asset only
|
|
371
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
372
|
+
wallet: this.wallet,
|
|
373
|
+
memo: `+:${checkLPAdd.assetPool}`,
|
|
374
|
+
assetAmount: addLiquidity.asset,
|
|
375
|
+
recipient: inboundAsgard,
|
|
376
|
+
}));
|
|
377
|
+
return txSubmitted;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
// asymmetrical rune only
|
|
381
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
382
|
+
wallet: this.wallet,
|
|
383
|
+
memo: `+:${checkLPAdd.assetPool}`,
|
|
384
|
+
assetAmount: addLiquidity.asset,
|
|
385
|
+
}));
|
|
386
|
+
return txSubmitted;
|
|
387
|
+
}
|
|
958
388
|
});
|
|
959
389
|
}
|
|
960
390
|
/**
|
|
961
|
-
*
|
|
962
|
-
* @param params -
|
|
963
|
-
* @
|
|
964
|
-
* @return
|
|
391
|
+
* Withdraws liquidity from a position.
|
|
392
|
+
* @param params - The wallet to perform the transaction.
|
|
393
|
+
* @return - The array of transaction submissions.
|
|
965
394
|
*/
|
|
966
|
-
withdrawLiquidityPosition(
|
|
395
|
+
withdrawLiquidityPosition(params) {
|
|
967
396
|
return __awaiter(this, void 0, void 0, function* () {
|
|
968
|
-
// Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
|
|
397
|
+
// Caution Dust Limits: BTC, BCH, LTC chains: 10k sats; DOGE: 1m Sats; ETH: 0 wei; THOR: 0 RUNE.
|
|
969
398
|
const withdrawParams = yield this.thorchainQuery.estimateWithdrawLP(params);
|
|
970
|
-
|
|
399
|
+
const withdrawLiquidity = {
|
|
971
400
|
assetFee: withdrawParams.inbound.fees.asset,
|
|
972
401
|
runeFee: withdrawParams.inbound.fees.rune,
|
|
973
402
|
waitTimeSeconds: withdrawParams.estimatedWaitSeconds,
|
|
@@ -975,13 +404,50 @@ class ThorchainAMM {
|
|
|
975
404
|
assetPool: withdrawParams.assetPool,
|
|
976
405
|
assetAddress: withdrawParams.assetAddress,
|
|
977
406
|
runeAddress: withdrawParams.runeAddress,
|
|
978
|
-
}
|
|
407
|
+
};
|
|
408
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[withdrawLiquidity.assetFee.asset.chain].address;
|
|
409
|
+
// const waitTimeSeconds = params.waitTimeSeconds
|
|
410
|
+
const basisPoints = (withdrawLiquidity.percentage * 100).toFixed(); // convert to basis points
|
|
411
|
+
const txSubmitted = [];
|
|
412
|
+
if (withdrawLiquidity.assetAddress && withdrawLiquidity.runeAddress) {
|
|
413
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
414
|
+
wallet: this.wallet,
|
|
415
|
+
memo: `-:${withdrawLiquidity.assetPool}:${basisPoints}`,
|
|
416
|
+
assetAmount: withdrawLiquidity.assetFee,
|
|
417
|
+
recipient: inboundAsgard,
|
|
418
|
+
}));
|
|
419
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
420
|
+
wallet: this.wallet,
|
|
421
|
+
memo: `-:${withdrawLiquidity.assetPool}:${basisPoints}`,
|
|
422
|
+
assetAmount: withdrawLiquidity.runeFee,
|
|
423
|
+
}));
|
|
424
|
+
return txSubmitted;
|
|
425
|
+
}
|
|
426
|
+
else if (withdrawLiquidity.assetAddress && !withdrawLiquidity.runeAddress) {
|
|
427
|
+
// asymmetrical asset only
|
|
428
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
429
|
+
wallet: this.wallet,
|
|
430
|
+
memo: `-:${withdrawLiquidity.assetPool}:${basisPoints}`,
|
|
431
|
+
assetAmount: withdrawLiquidity.assetFee,
|
|
432
|
+
recipient: inboundAsgard,
|
|
433
|
+
}));
|
|
434
|
+
return txSubmitted;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
// asymmetrical rune only
|
|
438
|
+
txSubmitted.push(yield ThorchainAction.makeAction({
|
|
439
|
+
wallet: this.wallet,
|
|
440
|
+
memo: `-:${withdrawLiquidity.assetPool}:${basisPoints}`,
|
|
441
|
+
assetAmount: withdrawLiquidity.runeFee,
|
|
442
|
+
}));
|
|
443
|
+
return txSubmitted;
|
|
444
|
+
}
|
|
979
445
|
});
|
|
980
446
|
}
|
|
981
447
|
/**
|
|
982
|
-
*
|
|
983
|
-
* @param addAssetAmount
|
|
984
|
-
* @returns
|
|
448
|
+
* Estimates adding to a saver.
|
|
449
|
+
* @param addAssetAmount The amount to add to the saver.
|
|
450
|
+
* @returns The estimated addition to the saver object.
|
|
985
451
|
*/
|
|
986
452
|
estimateAddSaver(addAssetAmount) {
|
|
987
453
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -989,9 +455,9 @@ class ThorchainAMM {
|
|
|
989
455
|
});
|
|
990
456
|
}
|
|
991
457
|
/**
|
|
992
|
-
*
|
|
993
|
-
* @param withdrawParams
|
|
994
|
-
* @returns
|
|
458
|
+
* Estimates withdrawing from a saver.
|
|
459
|
+
* @param withdrawParams The parameters for withdrawing from the saver.
|
|
460
|
+
* @returns The estimated withdrawal from the saver object.
|
|
995
461
|
*/
|
|
996
462
|
estimateWithdrawSaver(withdrawParams) {
|
|
997
463
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -999,9 +465,9 @@ class ThorchainAMM {
|
|
|
999
465
|
});
|
|
1000
466
|
}
|
|
1001
467
|
/**
|
|
1002
|
-
*
|
|
1003
|
-
* @param getsaver
|
|
1004
|
-
* @returns
|
|
468
|
+
* Retrieves the position of a saver.
|
|
469
|
+
* @param getsaver The parameters to retrieve the saver position.
|
|
470
|
+
* @returns The saver position object.
|
|
1005
471
|
*/
|
|
1006
472
|
getSaverPosition(getsaver) {
|
|
1007
473
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1009,37 +475,46 @@ class ThorchainAMM {
|
|
|
1009
475
|
});
|
|
1010
476
|
}
|
|
1011
477
|
/**
|
|
1012
|
-
*
|
|
478
|
+
* Adds assets to a saver.
|
|
1013
479
|
* @param wallet - wallet needed to execute tx
|
|
1014
|
-
* @param addAssetAmount -
|
|
1015
|
-
* @returns - submitted
|
|
480
|
+
* @param addAssetAmount - The amount to add to the saver.
|
|
481
|
+
* @returns - The submitted transaction.
|
|
1016
482
|
*/
|
|
1017
|
-
addSaver(
|
|
483
|
+
addSaver(addAssetAmount) {
|
|
1018
484
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1019
485
|
const addEstimate = yield this.thorchainQuery.estimateAddSaver(addAssetAmount);
|
|
1020
486
|
if (!addEstimate.canAddSaver)
|
|
1021
487
|
throw Error(`Cannot add to savers`);
|
|
1022
|
-
return
|
|
488
|
+
return ThorchainAction.makeAction({
|
|
489
|
+
wallet: this.wallet,
|
|
490
|
+
recipient: addEstimate.toAddress,
|
|
491
|
+
assetAmount: addAssetAmount,
|
|
492
|
+
memo: addEstimate.memo,
|
|
493
|
+
});
|
|
1023
494
|
});
|
|
1024
495
|
}
|
|
1025
496
|
/**
|
|
1026
|
-
*
|
|
1027
|
-
* @param
|
|
1028
|
-
* @
|
|
1029
|
-
* @returns
|
|
497
|
+
* Withdraws assets from a saver.
|
|
498
|
+
* @param withdrawParams - The parameters for withdrawing from the saver.
|
|
499
|
+
* @returns The submitted transaction.
|
|
1030
500
|
*/
|
|
1031
|
-
withdrawSaver(
|
|
501
|
+
withdrawSaver(withdrawParams) {
|
|
1032
502
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1033
503
|
const withdrawEstimate = yield this.thorchainQuery.estimateWithdrawSaver(withdrawParams);
|
|
1034
504
|
if (withdrawEstimate.errors.length > 0)
|
|
1035
505
|
throw Error(`${withdrawEstimate.errors}`);
|
|
1036
|
-
return
|
|
506
|
+
return ThorchainAction.makeAction({
|
|
507
|
+
wallet: this.wallet,
|
|
508
|
+
recipient: withdrawEstimate.toAddress,
|
|
509
|
+
assetAmount: withdrawEstimate.dustAmount,
|
|
510
|
+
memo: withdrawEstimate.memo,
|
|
511
|
+
});
|
|
1037
512
|
});
|
|
1038
513
|
}
|
|
1039
514
|
/**
|
|
1040
|
-
*
|
|
1041
|
-
* @param loanOpenParams
|
|
1042
|
-
* @returns
|
|
515
|
+
* Retrieves a quote for opening a loan.
|
|
516
|
+
* @param loanOpenParams The parameters for opening the loan.
|
|
517
|
+
* @returns The quote for opening the loan.
|
|
1043
518
|
*/
|
|
1044
519
|
getLoanQuoteOpen(loanOpenParams) {
|
|
1045
520
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1047,9 +522,9 @@ class ThorchainAMM {
|
|
|
1047
522
|
});
|
|
1048
523
|
}
|
|
1049
524
|
/**
|
|
1050
|
-
*
|
|
1051
|
-
* @param loanCloseParams
|
|
1052
|
-
* @returns
|
|
525
|
+
* Retrieves a quote for closing a loan.
|
|
526
|
+
* @param loanCloseParams The parameters for closing the loan.
|
|
527
|
+
* @returns The quote for closing the loan.
|
|
1053
528
|
*/
|
|
1054
529
|
getLoanQuoteClose(loanCloseParams) {
|
|
1055
530
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1057,45 +532,46 @@ class ThorchainAMM {
|
|
|
1057
532
|
});
|
|
1058
533
|
}
|
|
1059
534
|
/**
|
|
1060
|
-
*
|
|
1061
|
-
* @param
|
|
1062
|
-
* @
|
|
1063
|
-
* @returns - submitted tx
|
|
535
|
+
* Opens a loan.
|
|
536
|
+
* @param loanOpenParams - The parameters for opening the loan.
|
|
537
|
+
* @returns - The submitted transaction.
|
|
1064
538
|
*/
|
|
1065
|
-
addLoan(
|
|
539
|
+
addLoan(loanOpenParams) {
|
|
1066
540
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1067
541
|
const loanOpen = yield this.thorchainQuery.getLoanQuoteOpen(loanOpenParams);
|
|
1068
542
|
if (loanOpen.errors.length > 0)
|
|
1069
543
|
throw Error(`${loanOpen.errors}`);
|
|
1070
|
-
return
|
|
544
|
+
return ThorchainAction.makeAction({
|
|
545
|
+
wallet: this.wallet,
|
|
1071
546
|
memo: `${loanOpen.memo}`,
|
|
1072
|
-
|
|
1073
|
-
|
|
547
|
+
recipient: `${loanOpen.inboundAddress}`,
|
|
548
|
+
assetAmount: loanOpenParams.amount,
|
|
1074
549
|
});
|
|
1075
550
|
});
|
|
1076
551
|
}
|
|
1077
552
|
/**
|
|
1078
|
-
*
|
|
1079
|
-
* @param
|
|
1080
|
-
* @
|
|
1081
|
-
* @returns
|
|
553
|
+
* Withdraws assets from a loan.
|
|
554
|
+
* @param loanCloseParams - The parameters for withdrawing from the loan.
|
|
555
|
+
* @returns The submitted transaction.
|
|
1082
556
|
*/
|
|
1083
|
-
withdrawLoan(
|
|
557
|
+
withdrawLoan(loanCloseParams) {
|
|
1084
558
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1085
559
|
const withdrawLoan = yield this.thorchainQuery.getLoanQuoteClose(loanCloseParams);
|
|
560
|
+
// Checks if there are any errors in the quote
|
|
1086
561
|
if (withdrawLoan.errors.length > 0)
|
|
1087
562
|
throw Error(`${withdrawLoan.errors}`);
|
|
1088
|
-
return
|
|
563
|
+
return ThorchainAction.makeAction({
|
|
564
|
+
wallet: this.wallet,
|
|
1089
565
|
memo: `${withdrawLoan.memo}`,
|
|
1090
|
-
|
|
1091
|
-
|
|
566
|
+
recipient: `${withdrawLoan.inboundAddress}`,
|
|
567
|
+
assetAmount: loanCloseParams.amount,
|
|
1092
568
|
});
|
|
1093
569
|
});
|
|
1094
570
|
}
|
|
1095
571
|
/**
|
|
1096
|
-
*
|
|
1097
|
-
* @param address - address
|
|
1098
|
-
* @returns
|
|
572
|
+
* Retrieves all Thornames and their associated data owned by an address.
|
|
573
|
+
* @param address - The address to retrieve Thornames for.
|
|
574
|
+
* @returns The Thornames data.
|
|
1099
575
|
*/
|
|
1100
576
|
getThornamesByAddress(address) {
|
|
1101
577
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1105,4 +581,3 @@ class ThorchainAMM {
|
|
|
1105
581
|
}
|
|
1106
582
|
|
|
1107
583
|
exports.ThorchainAMM = ThorchainAMM;
|
|
1108
|
-
exports.Wallet = Wallet;
|