@xchainjs/xchain-thorchain-amm 0.1.0-beta4 → 0.2.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/README.md +19 -17
- package/lib/index.esm.js +197 -4
- package/lib/index.js +197 -4
- package/lib/thorchain-amm.d.ts +17 -3
- package/lib/types.d.ts +22 -8
- package/lib/wallet.d.ts +31 -2
- package/package.json +13 -11
package/README.md
CHANGED
|
@@ -15,23 +15,26 @@ Following peer dependencies have to be installed into your project. These are no
|
|
|
15
15
|
```bash
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@binance-chain/javascript-sdk": "^4.2.0",
|
|
18
|
-
"@cosmos-client/core": "
|
|
18
|
+
"@cosmos-client/core": "0.45.13",
|
|
19
19
|
"@psf/bitcoincashjs-lib": "^4.0.2",
|
|
20
|
-
"@terra-money/terra.js": "^3.
|
|
21
|
-
"@xchainjs/xchain-binance": "^5.
|
|
22
|
-
"@xchainjs/xchain-bitcoin": "^0.
|
|
23
|
-
"@xchainjs/xchain-bitcoincash": "^0.
|
|
24
|
-
"@xchainjs/xchain-client": "^0.
|
|
25
|
-
"@xchainjs/xchain-cosmos": "^0.
|
|
20
|
+
"@terra-money/terra.js": "^3.0.2",
|
|
21
|
+
"@xchainjs/xchain-binance": "^5.6.0",
|
|
22
|
+
"@xchainjs/xchain-bitcoin": "^0.20.0",
|
|
23
|
+
"@xchainjs/xchain-bitcoincash": "^0.15.0",
|
|
24
|
+
"@xchainjs/xchain-client": "^0.13.0",
|
|
25
|
+
"@xchainjs/xchain-cosmos": "^0.20.0",
|
|
26
26
|
"@xchainjs/xchain-crypto": "^0.2.6",
|
|
27
|
-
"@xchainjs/xchain-doge": "^0.
|
|
28
|
-
"@xchainjs/xchain-ethereum": "^0.
|
|
29
|
-
"@xchainjs/xchain-
|
|
30
|
-
"@xchainjs/xchain-
|
|
31
|
-
"@xchainjs/xchain-
|
|
32
|
-
"@xchainjs/xchain-
|
|
33
|
-
"@xchainjs/xchain-
|
|
34
|
-
"@xchainjs/xchain-
|
|
27
|
+
"@xchainjs/xchain-doge": "^0.5.0",
|
|
28
|
+
"@xchainjs/xchain-ethereum": "^0.27.0",
|
|
29
|
+
"@xchainjs/xchain-evm": "^0.1.0-alpha2",
|
|
30
|
+
"@xchainjs/xchain-avax": "^0.1.0-alpha3",
|
|
31
|
+
"@xchainjs/xchain-litecoin": "^0.10.0",
|
|
32
|
+
"@xchainjs/xchain-midgard": "^0.1.0",
|
|
33
|
+
"@xchainjs/xchain-terra": "^0.3.0",
|
|
34
|
+
"@xchainjs/xchain-thorchain": "^0.26.0",
|
|
35
|
+
"@xchainjs/xchain-thorchain-query": "^0.1.0",
|
|
36
|
+
"@xchainjs/xchain-thornode": "^0.1.0",
|
|
37
|
+
"@xchainjs/xchain-util": "^0.9.0",
|
|
35
38
|
"axios": "^0.27.2",
|
|
36
39
|
"axios-retry": "^3.3.1",
|
|
37
40
|
"bchaddrjs": "^0.5.2",
|
|
@@ -42,9 +45,8 @@ Following peer dependencies have to be installed into your project. These are no
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
```
|
|
45
|
-
## Examples
|
|
46
|
-
|
|
47
48
|
|
|
49
|
+
## Examples
|
|
48
50
|
|
|
49
51
|
## Documentation
|
|
50
52
|
|
package/lib/index.esm.js
CHANGED
|
@@ -423,10 +423,13 @@ class EthHelper {
|
|
|
423
423
|
*/
|
|
424
424
|
sendDeposit(params) {
|
|
425
425
|
return __awaiter(this, void 0, void 0, function* () {
|
|
426
|
-
const inboundAsgard = (yield this.thorchainCache.
|
|
426
|
+
const inboundAsgard = (yield this.thorchainCache.getInboundAddresses())[params.asset.chain];
|
|
427
427
|
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router)) {
|
|
428
428
|
throw new Error('router address is not defined');
|
|
429
429
|
}
|
|
430
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
431
|
+
throw new Error('Vault address is not defined');
|
|
432
|
+
}
|
|
430
433
|
const address = this.client.getAddress(params.walletIndex);
|
|
431
434
|
const gasPrice = yield this.ethClient.estimateGasPrices();
|
|
432
435
|
if (eqAsset(params.asset, AssetETH)) {
|
|
@@ -515,10 +518,13 @@ class EvmHelper {
|
|
|
515
518
|
*/
|
|
516
519
|
sendDeposit(params) {
|
|
517
520
|
return __awaiter(this, void 0, void 0, function* () {
|
|
518
|
-
const inboundAsgard = (yield this.thorchainCache.
|
|
521
|
+
const inboundAsgard = (yield this.thorchainCache.getInboundAddresses())[params.asset.chain];
|
|
519
522
|
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router)) {
|
|
520
523
|
throw new Error('router address is not defined');
|
|
521
524
|
}
|
|
525
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
526
|
+
throw new Error('Vault address is not defined');
|
|
527
|
+
}
|
|
522
528
|
const address = this.client.getAddress(params.walletIndex);
|
|
523
529
|
const gasPrice = yield this.evmClient.estimateGasPrices();
|
|
524
530
|
if (eqAsset(params.asset, this.evmClient.config.gasAsset)) {
|
|
@@ -704,7 +710,9 @@ class Wallet {
|
|
|
704
710
|
return __awaiter(this, void 0, void 0, function* () {
|
|
705
711
|
const client = this.clients[swap.input.asset.chain];
|
|
706
712
|
const waitTimeSeconds = swap.waitTimeSeconds;
|
|
707
|
-
const
|
|
713
|
+
const inbound = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[swap.input.asset.chain];
|
|
714
|
+
if (!(inbound === null || inbound === void 0 ? void 0 : inbound.address))
|
|
715
|
+
throw Error(`no asgard address found for ${swap.input.asset.chain}`);
|
|
708
716
|
if (swap.input.asset.chain === Chain.Ethereum) {
|
|
709
717
|
const params = {
|
|
710
718
|
walletIndex: 0,
|
|
@@ -733,7 +741,7 @@ class Wallet {
|
|
|
733
741
|
walletIndex: 0,
|
|
734
742
|
asset: swap.input.asset,
|
|
735
743
|
amount: swap.input.baseAmount,
|
|
736
|
-
recipient:
|
|
744
|
+
recipient: inbound.address,
|
|
737
745
|
memo: this.constructSwapMemo(swap),
|
|
738
746
|
};
|
|
739
747
|
const hash = yield client.transfer(params);
|
|
@@ -741,6 +749,156 @@ class Wallet {
|
|
|
741
749
|
}
|
|
742
750
|
});
|
|
743
751
|
}
|
|
752
|
+
/** BASED OFF https://dev.thorchain.or›g/thorchain-dev/network/memos
|
|
753
|
+
*
|
|
754
|
+
* @param params input parameters needed to add liquidity
|
|
755
|
+
* @returns transaction details submitted
|
|
756
|
+
*/
|
|
757
|
+
addLiquidity(params) {
|
|
758
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
759
|
+
const assetClient = this.clients[params.asset.asset.chain];
|
|
760
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain]
|
|
761
|
+
.address;
|
|
762
|
+
const thorchainClient = this.clients[params.rune.asset.chain];
|
|
763
|
+
const addressRune = thorchainClient.getAddress();
|
|
764
|
+
const addressAsset = assetClient.getAddress();
|
|
765
|
+
const waitTimeSeconds = params.waitTimeSeconds;
|
|
766
|
+
let constructedMemo = '';
|
|
767
|
+
const txSubmitted = [];
|
|
768
|
+
// symmetrical add
|
|
769
|
+
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
770
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}:${addressRune}`;
|
|
771
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard));
|
|
772
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}:${addressAsset}`;
|
|
773
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
774
|
+
return txSubmitted;
|
|
775
|
+
}
|
|
776
|
+
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
777
|
+
// asymmetrical asset only
|
|
778
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}`;
|
|
779
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard));
|
|
780
|
+
return txSubmitted;
|
|
781
|
+
}
|
|
782
|
+
else {
|
|
783
|
+
// asymmetrical rune only
|
|
784
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}`;
|
|
785
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
786
|
+
return txSubmitted;
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
*
|
|
792
|
+
* @param params - parameters required for liquidity position
|
|
793
|
+
* @returns object with tx response, url and wait time in seconds
|
|
794
|
+
*/
|
|
795
|
+
removeLiquidity(params) {
|
|
796
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
797
|
+
const assetClient = this.clients[params.asset.asset.chain];
|
|
798
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain];
|
|
799
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
800
|
+
throw new Error('Vault address is not defined');
|
|
801
|
+
}
|
|
802
|
+
const waitTimeSeconds = params.waitTimeSeconds;
|
|
803
|
+
const thorchainClient = this.clients[params.rune.asset.chain];
|
|
804
|
+
const basisPoints = (params.percentage * 100).toFixed(); // convert to basis points
|
|
805
|
+
let constructedMemo = '';
|
|
806
|
+
const txSubmitted = [];
|
|
807
|
+
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
808
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
809
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard.address));
|
|
810
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
811
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
812
|
+
return txSubmitted;
|
|
813
|
+
}
|
|
814
|
+
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
815
|
+
// asymmetrical asset only
|
|
816
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
817
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard.address));
|
|
818
|
+
return txSubmitted;
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
// asymmetrical rune only
|
|
822
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
823
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
824
|
+
return txSubmitted;
|
|
825
|
+
}
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
*
|
|
830
|
+
* @param params - parameters for add liquidity
|
|
831
|
+
* @param constructedMemo - memo needed for thorchain
|
|
832
|
+
* @param waitTimeSeconds - wait time for the tx to be confirmed
|
|
833
|
+
* @param assetClient - passing XchainClient
|
|
834
|
+
* @param inboundAsgard - inbound Asgard address for the LP
|
|
835
|
+
* @returns - tx object
|
|
836
|
+
*/
|
|
837
|
+
addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard) {
|
|
838
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
839
|
+
if (params.asset.asset.chain === Chain.Ethereum) {
|
|
840
|
+
const addParams = {
|
|
841
|
+
wallIndex: 0,
|
|
842
|
+
asset: params.asset.asset,
|
|
843
|
+
amount: params.asset.baseAmount,
|
|
844
|
+
feeOption: FeeOption.Fast,
|
|
845
|
+
memo: constructedMemo,
|
|
846
|
+
};
|
|
847
|
+
console.log(addParams.amount.amount().toNumber());
|
|
848
|
+
const hash = yield this.ethHelper.sendDeposit(addParams);
|
|
849
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
850
|
+
}
|
|
851
|
+
else if (params.asset.asset.chain === Chain.Avalanche) {
|
|
852
|
+
const addParams = {
|
|
853
|
+
wallIndex: 0,
|
|
854
|
+
asset: params.asset.asset,
|
|
855
|
+
amount: params.asset.baseAmount,
|
|
856
|
+
feeOption: FeeOption.Fast,
|
|
857
|
+
memo: constructedMemo,
|
|
858
|
+
};
|
|
859
|
+
const evmHelper = new EvmHelper(this.clients.AVAX, this.thorchainQuery.thorchainCache);
|
|
860
|
+
const hash = yield evmHelper.sendDeposit(addParams);
|
|
861
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
862
|
+
}
|
|
863
|
+
else {
|
|
864
|
+
const addParams = {
|
|
865
|
+
wallIndex: 0,
|
|
866
|
+
asset: params.asset.asset,
|
|
867
|
+
amount: params.asset.baseAmount,
|
|
868
|
+
recipient: inboundAsgard,
|
|
869
|
+
memo: constructedMemo,
|
|
870
|
+
};
|
|
871
|
+
try {
|
|
872
|
+
console.log(addParams);
|
|
873
|
+
const hash = yield assetClient.transfer(addParams);
|
|
874
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
875
|
+
}
|
|
876
|
+
catch (err) {
|
|
877
|
+
const hash = JSON.stringify(err);
|
|
878
|
+
return { hash, url: assetClient.getExplorerAddressUrl(assetClient.getAddress()), waitTimeSeconds };
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
*
|
|
885
|
+
* @param params - deposit parameters
|
|
886
|
+
* @param memo - memo needed to withdraw lp
|
|
887
|
+
* @returns - tx object
|
|
888
|
+
*/
|
|
889
|
+
addOrRemoveRuneLP(params, memo, thorchainClient, waitTimeSeconds) {
|
|
890
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
891
|
+
const thorClient = this.clients.THOR;
|
|
892
|
+
const addParams = {
|
|
893
|
+
asset: params.rune.asset,
|
|
894
|
+
amount: params.rune.baseAmount,
|
|
895
|
+
memo: memo,
|
|
896
|
+
};
|
|
897
|
+
console.log(addParams);
|
|
898
|
+
const hash = yield thorClient.deposit(addParams);
|
|
899
|
+
return { hash, url: thorchainClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
900
|
+
});
|
|
901
|
+
}
|
|
744
902
|
}
|
|
745
903
|
|
|
746
904
|
const BN_1 = new BigNumber(1);
|
|
@@ -813,6 +971,41 @@ class ThorchainAMM {
|
|
|
813
971
|
});
|
|
814
972
|
});
|
|
815
973
|
}
|
|
974
|
+
/**
|
|
975
|
+
*
|
|
976
|
+
* @param wallet - wallet class
|
|
977
|
+
* @param params - liquidity parameters
|
|
978
|
+
* @returns
|
|
979
|
+
*/
|
|
980
|
+
addLiquidityPosition(wallet, params) {
|
|
981
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
982
|
+
// Check amounts are greater than fees and use return estimated wait
|
|
983
|
+
const checkLPAdd = yield this.thorchainQuery.estimateAddLP(params);
|
|
984
|
+
return wallet.addLiquidity({
|
|
985
|
+
asset: params.asset,
|
|
986
|
+
rune: params.rune,
|
|
987
|
+
waitTimeSeconds: checkLPAdd.estimatedWaitSeconds,
|
|
988
|
+
});
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
*
|
|
993
|
+
* @param params - liquidity parameters
|
|
994
|
+
* @param wallet - wallet needed to perform tx
|
|
995
|
+
* @return
|
|
996
|
+
*/
|
|
997
|
+
removeLiquidityPosition(wallet, params) {
|
|
998
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
999
|
+
// Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
|
|
1000
|
+
const estimateWithrawLp = yield this.thorchainQuery.estimateWithdrawLP(params);
|
|
1001
|
+
return wallet.removeLiquidity({
|
|
1002
|
+
asset: estimateWithrawLp.transactionFee.assetFee,
|
|
1003
|
+
rune: estimateWithrawLp.transactionFee.runeFee,
|
|
1004
|
+
percentage: params.percentage,
|
|
1005
|
+
waitTimeSeconds: estimateWithrawLp.estimatedWaitSeconds,
|
|
1006
|
+
});
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
816
1009
|
}
|
|
817
1010
|
|
|
818
1011
|
export { ThorchainAMM, Wallet };
|
package/lib/index.js
CHANGED
|
@@ -427,10 +427,13 @@ class EthHelper {
|
|
|
427
427
|
*/
|
|
428
428
|
sendDeposit(params) {
|
|
429
429
|
return __awaiter(this, void 0, void 0, function* () {
|
|
430
|
-
const inboundAsgard = (yield this.thorchainCache.
|
|
430
|
+
const inboundAsgard = (yield this.thorchainCache.getInboundAddresses())[params.asset.chain];
|
|
431
431
|
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router)) {
|
|
432
432
|
throw new Error('router address is not defined');
|
|
433
433
|
}
|
|
434
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
435
|
+
throw new Error('Vault address is not defined');
|
|
436
|
+
}
|
|
434
437
|
const address = this.client.getAddress(params.walletIndex);
|
|
435
438
|
const gasPrice = yield this.ethClient.estimateGasPrices();
|
|
436
439
|
if (xchainUtil.eqAsset(params.asset, xchainUtil.AssetETH)) {
|
|
@@ -519,10 +522,13 @@ class EvmHelper {
|
|
|
519
522
|
*/
|
|
520
523
|
sendDeposit(params) {
|
|
521
524
|
return __awaiter(this, void 0, void 0, function* () {
|
|
522
|
-
const inboundAsgard = (yield this.thorchainCache.
|
|
525
|
+
const inboundAsgard = (yield this.thorchainCache.getInboundAddresses())[params.asset.chain];
|
|
523
526
|
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.router)) {
|
|
524
527
|
throw new Error('router address is not defined');
|
|
525
528
|
}
|
|
529
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
530
|
+
throw new Error('Vault address is not defined');
|
|
531
|
+
}
|
|
526
532
|
const address = this.client.getAddress(params.walletIndex);
|
|
527
533
|
const gasPrice = yield this.evmClient.estimateGasPrices();
|
|
528
534
|
if (xchainUtil.eqAsset(params.asset, this.evmClient.config.gasAsset)) {
|
|
@@ -708,7 +714,9 @@ class Wallet {
|
|
|
708
714
|
return __awaiter(this, void 0, void 0, function* () {
|
|
709
715
|
const client = this.clients[swap.input.asset.chain];
|
|
710
716
|
const waitTimeSeconds = swap.waitTimeSeconds;
|
|
711
|
-
const
|
|
717
|
+
const inbound = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[swap.input.asset.chain];
|
|
718
|
+
if (!(inbound === null || inbound === void 0 ? void 0 : inbound.address))
|
|
719
|
+
throw Error(`no asgard address found for ${swap.input.asset.chain}`);
|
|
712
720
|
if (swap.input.asset.chain === xchainUtil.Chain.Ethereum) {
|
|
713
721
|
const params = {
|
|
714
722
|
walletIndex: 0,
|
|
@@ -737,7 +745,7 @@ class Wallet {
|
|
|
737
745
|
walletIndex: 0,
|
|
738
746
|
asset: swap.input.asset,
|
|
739
747
|
amount: swap.input.baseAmount,
|
|
740
|
-
recipient:
|
|
748
|
+
recipient: inbound.address,
|
|
741
749
|
memo: this.constructSwapMemo(swap),
|
|
742
750
|
};
|
|
743
751
|
const hash = yield client.transfer(params);
|
|
@@ -745,6 +753,156 @@ class Wallet {
|
|
|
745
753
|
}
|
|
746
754
|
});
|
|
747
755
|
}
|
|
756
|
+
/** BASED OFF https://dev.thorchain.or›g/thorchain-dev/network/memos
|
|
757
|
+
*
|
|
758
|
+
* @param params input parameters needed to add liquidity
|
|
759
|
+
* @returns transaction details submitted
|
|
760
|
+
*/
|
|
761
|
+
addLiquidity(params) {
|
|
762
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
763
|
+
const assetClient = this.clients[params.asset.asset.chain];
|
|
764
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain]
|
|
765
|
+
.address;
|
|
766
|
+
const thorchainClient = this.clients[params.rune.asset.chain];
|
|
767
|
+
const addressRune = thorchainClient.getAddress();
|
|
768
|
+
const addressAsset = assetClient.getAddress();
|
|
769
|
+
const waitTimeSeconds = params.waitTimeSeconds;
|
|
770
|
+
let constructedMemo = '';
|
|
771
|
+
const txSubmitted = [];
|
|
772
|
+
// symmetrical add
|
|
773
|
+
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
774
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}:${addressRune}`;
|
|
775
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard));
|
|
776
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}:${addressAsset}`;
|
|
777
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
778
|
+
return txSubmitted;
|
|
779
|
+
}
|
|
780
|
+
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
781
|
+
// asymmetrical asset only
|
|
782
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}`;
|
|
783
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard));
|
|
784
|
+
return txSubmitted;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
// asymmetrical rune only
|
|
788
|
+
constructedMemo = `+:${params.asset.asset.chain}.${params.asset.asset.symbol}`;
|
|
789
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
790
|
+
return txSubmitted;
|
|
791
|
+
}
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
/**
|
|
795
|
+
*
|
|
796
|
+
* @param params - parameters required for liquidity position
|
|
797
|
+
* @returns object with tx response, url and wait time in seconds
|
|
798
|
+
*/
|
|
799
|
+
removeLiquidity(params) {
|
|
800
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
801
|
+
const assetClient = this.clients[params.asset.asset.chain];
|
|
802
|
+
const inboundAsgard = (yield this.thorchainQuery.thorchainCache.getInboundDetails())[params.asset.asset.chain];
|
|
803
|
+
if (!(inboundAsgard === null || inboundAsgard === void 0 ? void 0 : inboundAsgard.address)) {
|
|
804
|
+
throw new Error('Vault address is not defined');
|
|
805
|
+
}
|
|
806
|
+
const waitTimeSeconds = params.waitTimeSeconds;
|
|
807
|
+
const thorchainClient = this.clients[params.rune.asset.chain];
|
|
808
|
+
const basisPoints = (params.percentage * 100).toFixed(); // convert to basis points
|
|
809
|
+
let constructedMemo = '';
|
|
810
|
+
const txSubmitted = [];
|
|
811
|
+
if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.gt(0)) {
|
|
812
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
813
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard.address));
|
|
814
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
815
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
816
|
+
return txSubmitted;
|
|
817
|
+
}
|
|
818
|
+
else if (params.asset.assetAmount.gt(0) && params.rune.assetAmount.eq(0)) {
|
|
819
|
+
// asymmetrical asset only
|
|
820
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
821
|
+
txSubmitted.push(yield this.addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard.address));
|
|
822
|
+
return txSubmitted;
|
|
823
|
+
}
|
|
824
|
+
else {
|
|
825
|
+
// asymmetrical rune only
|
|
826
|
+
constructedMemo = `-:${params.asset.asset.chain}.${params.asset.asset.symbol}:${basisPoints}`;
|
|
827
|
+
txSubmitted.push(yield this.addOrRemoveRuneLP(params, constructedMemo, thorchainClient, waitTimeSeconds));
|
|
828
|
+
return txSubmitted;
|
|
829
|
+
}
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
*
|
|
834
|
+
* @param params - parameters for add liquidity
|
|
835
|
+
* @param constructedMemo - memo needed for thorchain
|
|
836
|
+
* @param waitTimeSeconds - wait time for the tx to be confirmed
|
|
837
|
+
* @param assetClient - passing XchainClient
|
|
838
|
+
* @param inboundAsgard - inbound Asgard address for the LP
|
|
839
|
+
* @returns - tx object
|
|
840
|
+
*/
|
|
841
|
+
addOrRemoveAssetLP(params, constructedMemo, assetClient, waitTimeSeconds, inboundAsgard) {
|
|
842
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
843
|
+
if (params.asset.asset.chain === xchainUtil.Chain.Ethereum) {
|
|
844
|
+
const addParams = {
|
|
845
|
+
wallIndex: 0,
|
|
846
|
+
asset: params.asset.asset,
|
|
847
|
+
amount: params.asset.baseAmount,
|
|
848
|
+
feeOption: xchainClient.FeeOption.Fast,
|
|
849
|
+
memo: constructedMemo,
|
|
850
|
+
};
|
|
851
|
+
console.log(addParams.amount.amount().toNumber());
|
|
852
|
+
const hash = yield this.ethHelper.sendDeposit(addParams);
|
|
853
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
854
|
+
}
|
|
855
|
+
else if (params.asset.asset.chain === xchainUtil.Chain.Avalanche) {
|
|
856
|
+
const addParams = {
|
|
857
|
+
wallIndex: 0,
|
|
858
|
+
asset: params.asset.asset,
|
|
859
|
+
amount: params.asset.baseAmount,
|
|
860
|
+
feeOption: xchainClient.FeeOption.Fast,
|
|
861
|
+
memo: constructedMemo,
|
|
862
|
+
};
|
|
863
|
+
const evmHelper = new EvmHelper(this.clients.AVAX, this.thorchainQuery.thorchainCache);
|
|
864
|
+
const hash = yield evmHelper.sendDeposit(addParams);
|
|
865
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
const addParams = {
|
|
869
|
+
wallIndex: 0,
|
|
870
|
+
asset: params.asset.asset,
|
|
871
|
+
amount: params.asset.baseAmount,
|
|
872
|
+
recipient: inboundAsgard,
|
|
873
|
+
memo: constructedMemo,
|
|
874
|
+
};
|
|
875
|
+
try {
|
|
876
|
+
console.log(addParams);
|
|
877
|
+
const hash = yield assetClient.transfer(addParams);
|
|
878
|
+
return { hash, url: assetClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
879
|
+
}
|
|
880
|
+
catch (err) {
|
|
881
|
+
const hash = JSON.stringify(err);
|
|
882
|
+
return { hash, url: assetClient.getExplorerAddressUrl(assetClient.getAddress()), waitTimeSeconds };
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
*
|
|
889
|
+
* @param params - deposit parameters
|
|
890
|
+
* @param memo - memo needed to withdraw lp
|
|
891
|
+
* @returns - tx object
|
|
892
|
+
*/
|
|
893
|
+
addOrRemoveRuneLP(params, memo, thorchainClient, waitTimeSeconds) {
|
|
894
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
895
|
+
const thorClient = this.clients.THOR;
|
|
896
|
+
const addParams = {
|
|
897
|
+
asset: params.rune.asset,
|
|
898
|
+
amount: params.rune.baseAmount,
|
|
899
|
+
memo: memo,
|
|
900
|
+
};
|
|
901
|
+
console.log(addParams);
|
|
902
|
+
const hash = yield thorClient.deposit(addParams);
|
|
903
|
+
return { hash, url: thorchainClient.getExplorerTxUrl(hash), waitTimeSeconds };
|
|
904
|
+
});
|
|
905
|
+
}
|
|
748
906
|
}
|
|
749
907
|
|
|
750
908
|
const BN_1 = new bignumber_js.BigNumber(1);
|
|
@@ -817,6 +975,41 @@ class ThorchainAMM {
|
|
|
817
975
|
});
|
|
818
976
|
});
|
|
819
977
|
}
|
|
978
|
+
/**
|
|
979
|
+
*
|
|
980
|
+
* @param wallet - wallet class
|
|
981
|
+
* @param params - liquidity parameters
|
|
982
|
+
* @returns
|
|
983
|
+
*/
|
|
984
|
+
addLiquidityPosition(wallet, params) {
|
|
985
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
986
|
+
// Check amounts are greater than fees and use return estimated wait
|
|
987
|
+
const checkLPAdd = yield this.thorchainQuery.estimateAddLP(params);
|
|
988
|
+
return wallet.addLiquidity({
|
|
989
|
+
asset: params.asset,
|
|
990
|
+
rune: params.rune,
|
|
991
|
+
waitTimeSeconds: checkLPAdd.estimatedWaitSeconds,
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
*
|
|
997
|
+
* @param params - liquidity parameters
|
|
998
|
+
* @param wallet - wallet needed to perform tx
|
|
999
|
+
* @return
|
|
1000
|
+
*/
|
|
1001
|
+
removeLiquidityPosition(wallet, params) {
|
|
1002
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1003
|
+
// Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
|
|
1004
|
+
const estimateWithrawLp = yield this.thorchainQuery.estimateWithdrawLP(params);
|
|
1005
|
+
return wallet.removeLiquidity({
|
|
1006
|
+
asset: estimateWithrawLp.transactionFee.assetFee,
|
|
1007
|
+
rune: estimateWithrawLp.transactionFee.runeFee,
|
|
1008
|
+
percentage: params.percentage,
|
|
1009
|
+
waitTimeSeconds: estimateWithrawLp.estimatedWaitSeconds,
|
|
1010
|
+
});
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
820
1013
|
}
|
|
821
1014
|
|
|
822
1015
|
exports.ThorchainAMM = ThorchainAMM;
|
package/lib/thorchain-amm.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EstimateSwapParams, ThorchainQuery, TxDetails } from '@xchainjs/xchain-thorchain-query';
|
|
2
|
-
import {
|
|
1
|
+
import { AddliquidityPosition, EstimateSwapParams, RemoveLiquidityPosition, ThorchainQuery, TxDetails } from '@xchainjs/xchain-thorchain-query';
|
|
2
|
+
import { TxSubmitted } from './types';
|
|
3
3
|
import { Wallet } from './wallet';
|
|
4
4
|
/**
|
|
5
5
|
* THORChain Class for interacting with THORChain.
|
|
@@ -31,5 +31,19 @@ export declare class ThorchainAMM {
|
|
|
31
31
|
* @param params - swap params
|
|
32
32
|
* @returns {SwapSubmitted} - Tx Hash, URL of BlockExplorer and expected wait time.
|
|
33
33
|
*/
|
|
34
|
-
doSwap(wallet: Wallet, params: EstimateSwapParams): Promise<
|
|
34
|
+
doSwap(wallet: Wallet, params: EstimateSwapParams): Promise<TxSubmitted>;
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param wallet - wallet class
|
|
38
|
+
* @param params - liquidity parameters
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
addLiquidityPosition(wallet: Wallet, params: AddliquidityPosition): Promise<TxSubmitted[]>;
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param params - liquidity parameters
|
|
45
|
+
* @param wallet - wallet needed to perform tx
|
|
46
|
+
* @return
|
|
47
|
+
*/
|
|
48
|
+
removeLiquidityPosition(wallet: Wallet, params: RemoveLiquidityPosition): Promise<TxSubmitted[]>;
|
|
35
49
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FeeOption } from '@xchainjs/xchain-client';
|
|
2
|
-
import { CryptoAmount } from '@xchainjs/xchain-thorchain-query';
|
|
2
|
+
import { CryptoAmount, LiquidityPool } from '@xchainjs/xchain-thorchain-query';
|
|
3
3
|
import { Address, Asset, BaseAmount } from '@xchainjs/xchain-util';
|
|
4
4
|
import { BigNumber } from 'bignumber.js';
|
|
5
5
|
export declare type MidgardConfig = {
|
|
@@ -17,11 +17,29 @@ export declare type ExecuteSwap = {
|
|
|
17
17
|
interfaceID: number;
|
|
18
18
|
waitTimeSeconds: number;
|
|
19
19
|
};
|
|
20
|
-
export declare type
|
|
20
|
+
export declare type TxSubmitted = {
|
|
21
21
|
hash: string;
|
|
22
22
|
url: string;
|
|
23
23
|
waitTimeSeconds: number;
|
|
24
24
|
};
|
|
25
|
+
export declare type AddLiquidity = {
|
|
26
|
+
asset: CryptoAmount;
|
|
27
|
+
rune: CryptoAmount;
|
|
28
|
+
waitTimeSeconds: number;
|
|
29
|
+
};
|
|
30
|
+
export declare type LiquidityPosition = {
|
|
31
|
+
assetPool: LiquidityPool;
|
|
32
|
+
assetAmount: CryptoAmount;
|
|
33
|
+
runeAmount: CryptoAmount;
|
|
34
|
+
impermanentLossProtection: number;
|
|
35
|
+
};
|
|
36
|
+
export declare type RemoveLiquidity = {
|
|
37
|
+
asset: CryptoAmount;
|
|
38
|
+
rune: CryptoAmount;
|
|
39
|
+
percentage: number;
|
|
40
|
+
waitTimeSeconds: number;
|
|
41
|
+
asymmetricalWithdraw?: Asset;
|
|
42
|
+
};
|
|
25
43
|
export declare type DepositParams = {
|
|
26
44
|
walletIndex?: number;
|
|
27
45
|
asset: Asset;
|
|
@@ -35,10 +53,6 @@ export declare type SwapOutput = {
|
|
|
35
53
|
slip: BigNumber;
|
|
36
54
|
};
|
|
37
55
|
export declare type UnitData = {
|
|
38
|
-
liquidityUnits:
|
|
39
|
-
totalUnits:
|
|
40
|
-
};
|
|
41
|
-
export declare type LiquidityData = {
|
|
42
|
-
rune: BaseAmount;
|
|
43
|
-
asset: BaseAmount;
|
|
56
|
+
liquidityUnits: BigNumber;
|
|
57
|
+
totalUnits: BigNumber;
|
|
44
58
|
};
|
package/lib/wallet.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Balance, XChainClient } from '@xchainjs/xchain-client';
|
|
2
2
|
import { ThorchainQuery } from '@xchainjs/xchain-thorchain-query';
|
|
3
3
|
import { Chain } from '@xchainjs/xchain-util';
|
|
4
|
-
import { ExecuteSwap,
|
|
4
|
+
import { AddLiquidity, ExecuteSwap, RemoveLiquidity, TxSubmitted } from './types';
|
|
5
5
|
declare type AllBalances = {
|
|
6
6
|
chain: Chain;
|
|
7
7
|
address: string;
|
|
@@ -35,10 +35,39 @@ export declare class Wallet {
|
|
|
35
35
|
* @returns transaction details and explorer url
|
|
36
36
|
* @see ThorchainAMM.doSwap()
|
|
37
37
|
*/
|
|
38
|
-
executeSwap(swap: ExecuteSwap): Promise<
|
|
38
|
+
executeSwap(swap: ExecuteSwap): Promise<TxSubmitted>;
|
|
39
39
|
private constructSwapMemo;
|
|
40
40
|
private validateSwap;
|
|
41
41
|
private swapRuneTo;
|
|
42
42
|
private swapNonRune;
|
|
43
|
+
/** BASED OFF https://dev.thorchain.or›g/thorchain-dev/network/memos
|
|
44
|
+
*
|
|
45
|
+
* @param params input parameters needed to add liquidity
|
|
46
|
+
* @returns transaction details submitted
|
|
47
|
+
*/
|
|
48
|
+
addLiquidity(params: AddLiquidity): Promise<TxSubmitted[]>;
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param params - parameters required for liquidity position
|
|
52
|
+
* @returns object with tx response, url and wait time in seconds
|
|
53
|
+
*/
|
|
54
|
+
removeLiquidity(params: RemoveLiquidity): Promise<TxSubmitted[]>;
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param params - parameters for add liquidity
|
|
58
|
+
* @param constructedMemo - memo needed for thorchain
|
|
59
|
+
* @param waitTimeSeconds - wait time for the tx to be confirmed
|
|
60
|
+
* @param assetClient - passing XchainClient
|
|
61
|
+
* @param inboundAsgard - inbound Asgard address for the LP
|
|
62
|
+
* @returns - tx object
|
|
63
|
+
*/
|
|
64
|
+
private addOrRemoveAssetLP;
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
* @param params - deposit parameters
|
|
68
|
+
* @param memo - memo needed to withdraw lp
|
|
69
|
+
* @returns - tx object
|
|
70
|
+
*/
|
|
71
|
+
private addOrRemoveRuneLP;
|
|
43
72
|
}
|
|
44
73
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xchainjs/xchain-thorchain-amm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "module that exposes estimating & swappping cryptocurrency assets on thorchain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"THORChain",
|
|
@@ -43,19 +43,20 @@
|
|
|
43
43
|
"@xchainjs/xchain-binance": "^5.6.0",
|
|
44
44
|
"@xchainjs/xchain-bitcoin": "^0.20.0",
|
|
45
45
|
"@xchainjs/xchain-bitcoincash": "^0.15.0",
|
|
46
|
-
"@xchainjs/xchain-client": "^0.13.
|
|
46
|
+
"@xchainjs/xchain-client": "^0.13.1",
|
|
47
47
|
"@xchainjs/xchain-cosmos": "^0.20.0",
|
|
48
48
|
"@xchainjs/xchain-crypto": "^0.2.6",
|
|
49
49
|
"@xchainjs/xchain-doge": "^0.5.0",
|
|
50
50
|
"@xchainjs/xchain-ethereum": "^0.27.0",
|
|
51
51
|
"@xchainjs/xchain-evm": "^0.1.0-alpha2",
|
|
52
|
-
"@xchainjs/xchain-avax": "^0.1.0-
|
|
52
|
+
"@xchainjs/xchain-avax": "^0.1.0-alpha3",
|
|
53
53
|
"@xchainjs/xchain-litecoin": "^0.10.0",
|
|
54
|
-
"@xchainjs/xchain-midgard": "0.1.0
|
|
54
|
+
"@xchainjs/xchain-midgard": "0.1.0",
|
|
55
55
|
"@xchainjs/xchain-terra": "^0.3.0",
|
|
56
56
|
"@xchainjs/xchain-thorchain": "^0.26.0",
|
|
57
|
-
"@xchainjs/xchain-thorchain-query": "^0.1.0
|
|
58
|
-
"@xchainjs/xchain-
|
|
57
|
+
"@xchainjs/xchain-thorchain-query": "^0.1.0",
|
|
58
|
+
"@xchainjs/xchain-thornode": "^0.1.0",
|
|
59
|
+
"@xchainjs/xchain-util": "^0.10.0",
|
|
59
60
|
"axios": "^0.25.0",
|
|
60
61
|
"axios-retry": "^3.2.5",
|
|
61
62
|
"bchaddrjs": "^0.5.2",
|
|
@@ -77,19 +78,20 @@
|
|
|
77
78
|
"@xchainjs/xchain-binance": "^5.6.0",
|
|
78
79
|
"@xchainjs/xchain-bitcoin": "^0.20.0",
|
|
79
80
|
"@xchainjs/xchain-bitcoincash": "^0.15.0",
|
|
80
|
-
"@xchainjs/xchain-client": "^0.13.
|
|
81
|
+
"@xchainjs/xchain-client": "^0.13.1",
|
|
81
82
|
"@xchainjs/xchain-cosmos": "^0.20.0",
|
|
82
83
|
"@xchainjs/xchain-crypto": "^0.2.6",
|
|
83
84
|
"@xchainjs/xchain-doge": "^0.5.0",
|
|
84
85
|
"@xchainjs/xchain-ethereum": "^0.27.0",
|
|
85
86
|
"@xchainjs/xchain-evm": "^0.1.0-alpha2",
|
|
86
|
-
"@xchainjs/xchain-avax": "^0.1.0-
|
|
87
|
+
"@xchainjs/xchain-avax": "^0.1.0-alpha3",
|
|
87
88
|
"@xchainjs/xchain-litecoin": "^0.10.0",
|
|
88
|
-
"@xchainjs/xchain-midgard": "0.1.0
|
|
89
|
+
"@xchainjs/xchain-midgard": "0.1.0",
|
|
90
|
+
"@xchainjs/xchain-thornode": "^0.1.0",
|
|
89
91
|
"@xchainjs/xchain-terra": "^0.3.0",
|
|
90
92
|
"@xchainjs/xchain-thorchain": "^0.26.0",
|
|
91
|
-
"@xchainjs/xchain-thorchain-query":"^0.1.0
|
|
92
|
-
"@xchainjs/xchain-util": "^0.
|
|
93
|
+
"@xchainjs/xchain-thorchain-query": "^0.1.0",
|
|
94
|
+
"@xchainjs/xchain-util": "^0.10.0",
|
|
93
95
|
"axios": "^0.25.0",
|
|
94
96
|
"axios-retry": "^3.2.5",
|
|
95
97
|
"bchaddrjs": "^0.5.2",
|