@xchainjs/xchain-thorchain-query 0.7.2 → 0.7.4
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.esm.js +463 -180
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +463 -180
- package/lib/index.js.map +1 -1
- package/lib/liquidity-pool.d.ts +5 -1
- package/lib/thorchain-cache.d.ts +31 -31
- package/lib/thorchain-checktx.d.ts +121 -7
- package/lib/thorchain-query.d.ts +60 -44
- package/lib/types.d.ts +121 -0
- package/package.json +3 -3
package/lib/index.esm.js
CHANGED
|
@@ -31,55 +31,56 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
// Default attributes for each chain
|
|
34
35
|
const DefaultChainAttributes = {
|
|
35
36
|
BCH: {
|
|
36
37
|
blockReward: 6.25,
|
|
37
|
-
avgBlockTimeInSecs: 600,
|
|
38
|
+
avgBlockTimeInSecs: 600, // Average block time for Bitcoin Cash in seconds
|
|
38
39
|
},
|
|
39
40
|
BTC: {
|
|
40
41
|
blockReward: 6.25,
|
|
41
|
-
avgBlockTimeInSecs: 600,
|
|
42
|
+
avgBlockTimeInSecs: 600, // Average block time for Bitcoin in seconds
|
|
42
43
|
},
|
|
43
44
|
ETH: {
|
|
44
45
|
blockReward: 2,
|
|
45
|
-
avgBlockTimeInSecs: 13,
|
|
46
|
+
avgBlockTimeInSecs: 13, // Average block time for Ethereum in seconds
|
|
46
47
|
},
|
|
47
48
|
AVAX: {
|
|
48
49
|
blockReward: 2,
|
|
49
|
-
avgBlockTimeInSecs: 3,
|
|
50
|
+
avgBlockTimeInSecs: 3, // Average block time for Avalanche in seconds
|
|
50
51
|
},
|
|
51
52
|
LTC: {
|
|
52
53
|
blockReward: 12.5,
|
|
53
|
-
avgBlockTimeInSecs: 150,
|
|
54
|
+
avgBlockTimeInSecs: 150, // Average block time for Litecoin in seconds
|
|
54
55
|
},
|
|
55
56
|
DOGE: {
|
|
56
57
|
blockReward: 10000,
|
|
57
|
-
avgBlockTimeInSecs: 60,
|
|
58
|
+
avgBlockTimeInSecs: 60, // Average block time for Dogecoin in seconds
|
|
58
59
|
},
|
|
59
60
|
GAIA: {
|
|
60
61
|
blockReward: 0,
|
|
61
|
-
avgBlockTimeInSecs: 6,
|
|
62
|
+
avgBlockTimeInSecs: 6, // Average block time for Gaia in seconds
|
|
62
63
|
},
|
|
63
64
|
BNB: {
|
|
64
65
|
blockReward: 0,
|
|
65
|
-
avgBlockTimeInSecs: 6,
|
|
66
|
+
avgBlockTimeInSecs: 6, // Average block time for Binance Coin in seconds
|
|
66
67
|
},
|
|
67
68
|
THOR: {
|
|
68
69
|
blockReward: 0,
|
|
69
|
-
avgBlockTimeInSecs: 6,
|
|
70
|
+
avgBlockTimeInSecs: 6, // Average block time for THORChain in seconds
|
|
70
71
|
},
|
|
71
72
|
BSC: {
|
|
72
73
|
blockReward: 0,
|
|
73
|
-
avgBlockTimeInSecs: 3,
|
|
74
|
+
avgBlockTimeInSecs: 3, // Average block time for Binance Smart Chain in seconds
|
|
74
75
|
},
|
|
75
76
|
MAYA: {
|
|
76
77
|
blockReward: 0,
|
|
77
|
-
avgBlockTimeInSecs: 6,
|
|
78
|
+
avgBlockTimeInSecs: 6, // Average block time for MAYAChain in seconds
|
|
78
79
|
},
|
|
79
80
|
};
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
|
-
*
|
|
83
|
+
* Represents a Liquidity Pool in Thorchain
|
|
83
84
|
*/
|
|
84
85
|
class LiquidityPool {
|
|
85
86
|
constructor(thornodeDetails) {
|
|
@@ -92,9 +93,14 @@ class LiquidityPool {
|
|
|
92
93
|
this.assetString = this.thornodeDetails.asset;
|
|
93
94
|
this.assetBalance = baseAmount(this.thornodeDetails.balance_asset);
|
|
94
95
|
this.runeBalance = baseAmount(this.thornodeDetails.balance_rune);
|
|
96
|
+
// Calculate the ratio of Rune to the asset and the ratio of the asset to Rune
|
|
95
97
|
this.runeToAssetRatio = this.runeBalance.amount().div(this.assetBalance.amount());
|
|
96
98
|
this.assetToRuneRatio = this.assetBalance.amount().div(this.runeBalance.amount());
|
|
97
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Checks if the liquidity pool is available
|
|
102
|
+
* @returns {boolean} True if the liquidity pool is available, otherwise false
|
|
103
|
+
*/
|
|
98
104
|
isAvailable() {
|
|
99
105
|
return this.thornodeDetails.status.toLowerCase() === 'available';
|
|
100
106
|
}
|
|
@@ -809,36 +815,37 @@ class Thornode {
|
|
|
809
815
|
}
|
|
810
816
|
}
|
|
811
817
|
|
|
818
|
+
// Constants
|
|
812
819
|
const SAME_ASSET_EXCHANGE_RATE = new BigNumber(1);
|
|
813
820
|
const TEN_MINUTES = 10 * 60 * 1000;
|
|
821
|
+
// Default instances
|
|
814
822
|
const defaultThornode = new Thornode();
|
|
815
823
|
const defaultMidgardQuery = new MidgardQuery();
|
|
816
824
|
/**
|
|
817
|
-
* This class manages retrieving information from up
|
|
825
|
+
* This class manages retrieving information from up-to-date Thorchain.
|
|
818
826
|
*/
|
|
819
827
|
class ThorchainCache {
|
|
820
828
|
/**
|
|
821
829
|
* Constructor to create a ThorchainCache
|
|
822
|
-
*
|
|
823
|
-
* @param
|
|
824
|
-
* @param
|
|
825
|
-
* @param
|
|
826
|
-
* @param
|
|
827
|
-
* @param expireNetworkValuesCacheMillis - how long should the Mimir/Constants be cached before expiry
|
|
830
|
+
* @param thornode - An instance of the Thornode API (could be pointing to stagenet, testnet, or mainnet).
|
|
831
|
+
* @param midgardQuery - An instance of the MidgardQuery class (could be pointing to stagenet, testnet, or mainnet).
|
|
832
|
+
* @param expirePoolCacheMillis - How long the pools should be cached before expiry.
|
|
833
|
+
* @param expireInboundDetailsCacheMillis - How long the InboundDetails should be cached before expiry.
|
|
834
|
+
* @param expireNetworkValuesCacheMillis - How long the Mimir/Constants should be cached before expiry.
|
|
828
835
|
* @returns ThorchainCache
|
|
829
836
|
*/
|
|
830
837
|
constructor(thornode = defaultThornode, midgardQuery = defaultMidgardQuery, expirePoolCacheMillis = 6000, expireInboundDetailsCacheMillis = 6000, expireNetworkValuesCacheMillis = TEN_MINUTES) {
|
|
831
838
|
this.thornode = thornode;
|
|
832
839
|
this.midgardQuery = midgardQuery;
|
|
840
|
+
// Initialize cached values
|
|
833
841
|
this.poolCache = new CachedValue(() => this.refreshPoolCache(), expirePoolCacheMillis);
|
|
834
842
|
this.inboundDetailCache = new CachedValue(() => this.refreshInboundDetailCache(), expireInboundDetailsCacheMillis);
|
|
835
843
|
this.networkValuesCache = new CachedValue(() => thornode.getNetworkValues(), expireNetworkValuesCacheMillis);
|
|
836
844
|
}
|
|
837
845
|
/**
|
|
838
|
-
* Gets the exchange rate of the from asset in terms
|
|
839
|
-
*
|
|
840
|
-
* @
|
|
841
|
-
* @returns Promise<BigNumber>
|
|
846
|
+
* Gets the exchange rate of the `from` asset in terms of the `to` asset.
|
|
847
|
+
* @param asset - The asset to swap from.
|
|
848
|
+
* @returns Promise<BigNumber> - The exchange rate.
|
|
842
849
|
*/
|
|
843
850
|
getExchangeRate(from, to) {
|
|
844
851
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -868,10 +875,9 @@ class ThorchainCache {
|
|
|
868
875
|
});
|
|
869
876
|
}
|
|
870
877
|
/**
|
|
871
|
-
* Gets the Liquidity Pool for a given Asset
|
|
872
|
-
*
|
|
873
|
-
* @
|
|
874
|
-
* @returns Promise<LiquidityPool>
|
|
878
|
+
* Gets the Liquidity Pool for a given Asset.
|
|
879
|
+
* @param asset - The asset to retrieve the pool for.
|
|
880
|
+
* @returns Promise<LiquidityPool> - The liquidity pool.
|
|
875
881
|
*/
|
|
876
882
|
getPoolForAsset(asset) {
|
|
877
883
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -889,9 +895,8 @@ class ThorchainCache {
|
|
|
889
895
|
}
|
|
890
896
|
/**
|
|
891
897
|
* Get all the Liquidity Pools currently cached.
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
* @returns Promise<Record<string, LiquidityPool>>
|
|
898
|
+
* If the cache is expired, the pools will be re-fetched from Thornode.
|
|
899
|
+
* @returns Promise<Record<string, LiquidityPool>> - The liquidity pools.
|
|
895
900
|
*/
|
|
896
901
|
getPools() {
|
|
897
902
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -905,7 +910,8 @@ class ThorchainCache {
|
|
|
905
910
|
});
|
|
906
911
|
}
|
|
907
912
|
/**
|
|
908
|
-
* Refreshes the Pool Cache
|
|
913
|
+
* Refreshes the Pool Cache.
|
|
914
|
+
* @returns Promise<Record<string, LiquidityPool> |
|
|
909
915
|
*/
|
|
910
916
|
refreshPoolCache() {
|
|
911
917
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -935,14 +941,17 @@ class ThorchainCache {
|
|
|
935
941
|
});
|
|
936
942
|
}
|
|
937
943
|
/**
|
|
938
|
-
* Refreshes the InboundDetailCache Cache
|
|
944
|
+
* Refreshes the InboundDetailCache Cache.
|
|
945
|
+
* @returns Promise<Record<string, InboundDetail>> - The refreshed inbound detail cache.
|
|
939
946
|
*/
|
|
940
947
|
refreshInboundDetailCache() {
|
|
941
948
|
return __awaiter(this, void 0, void 0, function* () {
|
|
949
|
+
// Fetching mimir details and all inbound addresses concurrently
|
|
942
950
|
const [mimirDetails, allInboundAddresses] = yield Promise.all([
|
|
943
951
|
this.thornode.getMimir(),
|
|
944
952
|
this.thornode.getInboundAddresses(),
|
|
945
953
|
]);
|
|
954
|
+
// Mapping inbound details
|
|
946
955
|
const inboundDetails = {};
|
|
947
956
|
for (const inbound of allInboundAddresses) {
|
|
948
957
|
const chain = inbound.chain;
|
|
@@ -954,6 +963,7 @@ class ThorchainCache {
|
|
|
954
963
|
!inbound.outbound_fee ||
|
|
955
964
|
!inbound.gas_rate_units)
|
|
956
965
|
throw new Error(`Missing required inbound info`);
|
|
966
|
+
// Adding mock THORCHAIN inbound details
|
|
957
967
|
const details = {
|
|
958
968
|
chain: chain,
|
|
959
969
|
address: inbound.address,
|
|
@@ -986,13 +996,10 @@ class ThorchainCache {
|
|
|
986
996
|
});
|
|
987
997
|
}
|
|
988
998
|
/**
|
|
989
|
-
* Returns the exchange of a CryptoAmount to a different Asset
|
|
990
|
-
*
|
|
991
|
-
*
|
|
992
|
-
*
|
|
993
|
-
* @param input - amount/asset to convert to outAsset
|
|
994
|
-
* @param outAsset - the Asset you want to convert to
|
|
995
|
-
* @returns CryptoAmount of input
|
|
999
|
+
* Returns the exchange of a CryptoAmount to a different Asset.
|
|
1000
|
+
* @param input - The amount/asset to convert.
|
|
1001
|
+
* @param outAsset - The asset you want to convert to.
|
|
1002
|
+
* @returns Promise<CryptoAmount> - The converted amount.
|
|
996
1003
|
*/
|
|
997
1004
|
convert(input, outAsset) {
|
|
998
1005
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1007,6 +1014,11 @@ class ThorchainCache {
|
|
|
1007
1014
|
return result;
|
|
1008
1015
|
});
|
|
1009
1016
|
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Gets the router address for a given chain.
|
|
1019
|
+
* @param chain - The chain to get the router address for.
|
|
1020
|
+
* @returns Promise<Address> - The router address.
|
|
1021
|
+
*/
|
|
1010
1022
|
getRouterAddressForChain(chain) {
|
|
1011
1023
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1012
1024
|
const inboundAsgard = (yield this.getInboundDetails())[chain];
|
|
@@ -1017,8 +1029,8 @@ class ThorchainCache {
|
|
|
1017
1029
|
});
|
|
1018
1030
|
}
|
|
1019
1031
|
/**
|
|
1020
|
-
*
|
|
1021
|
-
* @returns - inbound details
|
|
1032
|
+
* Gets the inbound details.
|
|
1033
|
+
* @returns Promise<Record<string, InboundDetail>> - The inbound details.
|
|
1022
1034
|
*/
|
|
1023
1035
|
getInboundDetails() {
|
|
1024
1036
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1031,8 +1043,8 @@ class ThorchainCache {
|
|
|
1031
1043
|
});
|
|
1032
1044
|
}
|
|
1033
1045
|
/**
|
|
1034
|
-
*
|
|
1035
|
-
* @returns - network values
|
|
1046
|
+
* Gets the network values.
|
|
1047
|
+
* @returns Promise<Record<string, number>> - The network values.
|
|
1036
1048
|
*/
|
|
1037
1049
|
getNetworkValues() {
|
|
1038
1050
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1048,7 +1060,7 @@ class ThorchainCache {
|
|
|
1048
1060
|
|
|
1049
1061
|
const defaultCache = new ThorchainCache();
|
|
1050
1062
|
/**
|
|
1051
|
-
*
|
|
1063
|
+
* ThorchainQuery Class for interacting with THORChain.
|
|
1052
1064
|
* Recommended main class to use for swapping with THORChain
|
|
1053
1065
|
* Has access to Midgard and THORNode data
|
|
1054
1066
|
*/
|
|
@@ -1064,14 +1076,14 @@ class ThorchainQuery {
|
|
|
1064
1076
|
this.thorchainCache = thorchainCache;
|
|
1065
1077
|
this.chainAttributes = chainAttributes;
|
|
1066
1078
|
}
|
|
1067
|
-
/**
|
|
1079
|
+
/** Quote a swap transaction.
|
|
1068
1080
|
*
|
|
1069
|
-
* @param quoteSwapParams -
|
|
1070
|
-
* @returns
|
|
1081
|
+
* @param quoteSwapParams - Input parameters for the swap quote.
|
|
1082
|
+
* @returns Transaction details including memo, address, fees, etc.
|
|
1071
1083
|
*/
|
|
1072
1084
|
quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height, }) {
|
|
1073
1085
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1074
|
-
//
|
|
1086
|
+
// Validates swap and pushes error if there is one
|
|
1075
1087
|
const errors = [];
|
|
1076
1088
|
const error = yield this.validateAmount(amount);
|
|
1077
1089
|
if (error)
|
|
@@ -1079,13 +1091,14 @@ class ThorchainQuery {
|
|
|
1079
1091
|
const fromAssetString = assetToString(fromAsset);
|
|
1080
1092
|
const toAssetString = assetToString(destinationAsset);
|
|
1081
1093
|
const inputAmount = getBaseAmountWithDiffDecimals(amount, 8);
|
|
1082
|
-
//
|
|
1094
|
+
// Fetch quote
|
|
1083
1095
|
const swapQuote = yield this.thorchainCache.thornode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height);
|
|
1084
|
-
//
|
|
1096
|
+
// Error handling for fetch response
|
|
1085
1097
|
const response = JSON.parse(JSON.stringify(swapQuote));
|
|
1086
1098
|
if (response.error)
|
|
1087
1099
|
errors.push(`Thornode request quote: ${response.error}`);
|
|
1088
1100
|
if (errors.length > 0) {
|
|
1101
|
+
// If there are errors, construct and return a transaction details object with error information
|
|
1089
1102
|
return {
|
|
1090
1103
|
memo: ``,
|
|
1091
1104
|
toAddress: ``,
|
|
@@ -1163,63 +1176,70 @@ class ThorchainQuery {
|
|
|
1163
1176
|
*/
|
|
1164
1177
|
validateAmount(cryptoAmount) {
|
|
1165
1178
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1179
|
+
// Get the number of decimals for the asset
|
|
1166
1180
|
const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(cryptoAmount.asset);
|
|
1181
|
+
// Check if the base amount decimal is equal to the asset's decimal
|
|
1167
1182
|
if (cryptoAmount.baseAmount.decimal !== assetDecimals)
|
|
1168
1183
|
return new Error(`Invalid number of decimals: ${assetToString(cryptoAmount.asset)} must have ${assetDecimals} decimals`);
|
|
1169
1184
|
});
|
|
1170
1185
|
}
|
|
1171
1186
|
/**
|
|
1172
1187
|
* Works out how long an outbound Tx will be held by THORChain before sending.
|
|
1173
|
-
*
|
|
1174
1188
|
* @param outboundAmount: CryptoAmount being sent.
|
|
1175
1189
|
* @returns required delay in seconds
|
|
1176
1190
|
* @see https://gitlab.com/thorchain/thornode/-/blob/develop/x/thorchain/manager_txout_current.go#L548
|
|
1177
1191
|
*/
|
|
1178
1192
|
outboundDelay(outboundAmount) {
|
|
1179
1193
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1194
|
+
// Retrieve network values
|
|
1180
1195
|
const networkValues = yield this.thorchainCache.getNetworkValues();
|
|
1196
|
+
// Create CryptoAmounts for minimum transaction out volume threshold and maximum transaction out offset
|
|
1181
1197
|
const minTxOutVolumeThreshold = new CryptoAmount(baseAmount(networkValues['MINTXOUTVOLUMETHRESHOLD']), AssetRuneNative);
|
|
1182
1198
|
const maxTxOutOffset = networkValues['MAXTXOUTOFFSET'];
|
|
1199
|
+
// Get the delay rate for outbound transactions
|
|
1183
1200
|
let txOutDelayRate = new CryptoAmount(baseAmount(networkValues['TXOUTDELAYRATE']), AssetRuneNative).assetAmount
|
|
1184
1201
|
.amount()
|
|
1185
1202
|
.toNumber();
|
|
1203
|
+
// Get the outbound queue
|
|
1186
1204
|
const getQueue = yield this.thorchainCache.thornode.getQueue();
|
|
1205
|
+
// Create a CryptoAmount for the scheduled outbound value
|
|
1187
1206
|
const outboundValue = new CryptoAmount(baseAmount(getQueue.scheduled_outbound_value), AssetRuneNative);
|
|
1207
|
+
// Get the average block time for THORChain
|
|
1188
1208
|
const thorChainblocktime = this.chainAttributes[THORChain].avgBlockTimeInSecs; // blocks required to confirm tx
|
|
1189
|
-
//
|
|
1209
|
+
// Convert the outbound amount to its value in RUNE
|
|
1190
1210
|
const runeValue = yield this.thorchainCache.convert(outboundAmount, AssetRuneNative);
|
|
1191
|
-
// Check rune value
|
|
1211
|
+
// Check if the rune value is less than the minimum transaction out volume threshold
|
|
1192
1212
|
if (runeValue.lt(minTxOutVolumeThreshold)) {
|
|
1193
1213
|
return thorChainblocktime;
|
|
1194
1214
|
}
|
|
1195
|
-
//
|
|
1215
|
+
// Check if the outbound value is undefined
|
|
1196
1216
|
if (outboundValue == undefined) {
|
|
1197
1217
|
throw new Error(`Could not return Scheduled Outbound Value`);
|
|
1198
1218
|
}
|
|
1199
|
-
//
|
|
1219
|
+
// Calculate the total outbound amount in rune
|
|
1200
1220
|
const outboundAmountTotal = runeValue.plus(outboundValue);
|
|
1201
|
-
//
|
|
1221
|
+
// Calculate the volume threshold
|
|
1202
1222
|
const volumeThreshold = outboundAmountTotal.div(minTxOutVolumeThreshold);
|
|
1203
|
-
//
|
|
1223
|
+
// Adjust the delay rate based on the volume threshold
|
|
1204
1224
|
txOutDelayRate = txOutDelayRate - volumeThreshold.assetAmount.amount().toNumber() <= 1 ? 1 : txOutDelayRate;
|
|
1205
|
-
//
|
|
1225
|
+
// Calculate the minimum number of blocks required for the transaction to be confirmed
|
|
1206
1226
|
let minBlocks = runeValue.assetAmount.amount().toNumber() / txOutDelayRate;
|
|
1207
1227
|
minBlocks = minBlocks > maxTxOutOffset ? maxTxOutOffset : minBlocks;
|
|
1228
|
+
// Return the required delay in seconds
|
|
1208
1229
|
return minBlocks * thorChainblocktime;
|
|
1209
1230
|
});
|
|
1210
1231
|
}
|
|
1211
1232
|
/**
|
|
1212
1233
|
* Convenience method to convert TotalFees to a different CryptoAmount
|
|
1213
|
-
*
|
|
1214
1234
|
* TotalFees are always calculated and returned in RUNE, this method can
|
|
1215
1235
|
* be used to show the equivalent fees in another Asset Type
|
|
1216
|
-
*
|
|
1217
1236
|
* @param fees: TotalFees - the fees you want to convert
|
|
1218
1237
|
* @param asset: Asset - the asset you want the fees converted to
|
|
1219
1238
|
* @returns TotalFees in asset
|
|
1220
1239
|
*/
|
|
1221
1240
|
getFeesIn(fees, asset) {
|
|
1222
1241
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1242
|
+
// Return the fees converted to the specified asset
|
|
1223
1243
|
return {
|
|
1224
1244
|
asset: fees.asset,
|
|
1225
1245
|
// swapFee: await this.convert(fees.swapFee, asset),
|
|
@@ -1231,73 +1251,78 @@ class ThorchainQuery {
|
|
|
1231
1251
|
}
|
|
1232
1252
|
/**
|
|
1233
1253
|
* Returns the exchange of a CryptoAmount to a different Asset
|
|
1234
|
-
*
|
|
1235
1254
|
* Ex. convert(input:100 BUSD, outAsset: BTC) -> 0.0001234 BTC
|
|
1236
|
-
*
|
|
1237
1255
|
* @param input - amount/asset to convert to outAsset
|
|
1238
1256
|
* @param ouAsset - the Asset you want to convert to
|
|
1239
1257
|
* @returns CryptoAmount of input
|
|
1240
1258
|
*/
|
|
1241
1259
|
convert(input, outAsset) {
|
|
1242
1260
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1261
|
+
// Convert the input amount to the specified asset
|
|
1243
1262
|
return yield this.thorchainCache.convert(input, outAsset);
|
|
1244
1263
|
});
|
|
1245
1264
|
}
|
|
1246
1265
|
/**
|
|
1247
1266
|
* Finds the required confCount required for an inbound or outbound Tx to THORChain. Estimate based on Midgard data only.
|
|
1248
|
-
*
|
|
1249
1267
|
* Finds the gas asset of the given asset (e.g. BUSD is on BNB), finds the value of asset in Gas Asset then finds the required confirmation count.
|
|
1250
1268
|
* ConfCount is then times by 6 seconds.
|
|
1251
|
-
*
|
|
1252
1269
|
* @param inbound: CryptoAmount - amount/asset of the outbound amount.
|
|
1253
1270
|
* @returns time in seconds before a Tx is confirmed by THORChain
|
|
1254
1271
|
* @see https://docs.thorchain.org/chain-clients/overview
|
|
1255
1272
|
*/
|
|
1256
1273
|
confCounting(inbound) {
|
|
1257
1274
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1258
|
-
//
|
|
1275
|
+
// Check for instant finality assets or synths
|
|
1259
1276
|
if (isAssetRuneNative(inbound.asset) ||
|
|
1260
1277
|
inbound.asset.chain == BNBChain ||
|
|
1261
1278
|
inbound.asset.chain == GAIAChain ||
|
|
1262
1279
|
inbound.asset.synth) {
|
|
1280
|
+
// Return the average block time for THORChain
|
|
1263
1281
|
return this.chainAttributes[THORChain].avgBlockTimeInSecs;
|
|
1264
1282
|
}
|
|
1265
|
-
// Get the gas asset for the inbound
|
|
1283
|
+
// Get the gas asset for the inbound asset's chain
|
|
1266
1284
|
const chainGasAsset = getChainAsset(inbound.asset.chain);
|
|
1267
|
-
//
|
|
1285
|
+
// Convert the inbound amount to the gas asset
|
|
1268
1286
|
const amountInGasAsset = yield this.thorchainCache.convert(inbound, chainGasAsset);
|
|
1269
|
-
//
|
|
1287
|
+
// Get the number of confirmations required based on the asset's value in the gas asset
|
|
1270
1288
|
const amountInGasAssetInAsset = amountInGasAsset.assetAmount;
|
|
1271
1289
|
const confConfig = this.chainAttributes[inbound.asset.chain];
|
|
1272
|
-
// find the required confs
|
|
1273
1290
|
const requiredConfs = Math.ceil(amountInGasAssetInAsset.amount().div(confConfig.blockReward).toNumber());
|
|
1274
|
-
//
|
|
1291
|
+
// Convert the number of confirmations to seconds
|
|
1275
1292
|
return requiredConfs * confConfig.avgBlockTimeInSecs;
|
|
1276
1293
|
});
|
|
1277
1294
|
}
|
|
1278
1295
|
/**
|
|
1279
|
-
* Estimates a liquidity position for given crypto amount value, both asymmetrical and
|
|
1280
|
-
* @param params - parameters needed for
|
|
1281
|
-
* @returns - type
|
|
1296
|
+
* Estimates a liquidity position for given crypto amount value, both asymmetrical and symmetrical
|
|
1297
|
+
* @param params - parameters needed for an estimated liquidity position
|
|
1298
|
+
* @returns - object of type EstimateLP
|
|
1282
1299
|
*/
|
|
1283
1300
|
estimateAddLP(params) {
|
|
1284
1301
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1285
1302
|
const errors = [];
|
|
1303
|
+
// Check if either of the assets are synths or if the rune is not THOR.RUNE
|
|
1286
1304
|
if (params.asset.asset.synth || params.rune.asset.synth)
|
|
1287
1305
|
errors.push('you cannot add liquidity with a synth');
|
|
1288
1306
|
if (!isAssetRuneNative(params.rune.asset))
|
|
1289
1307
|
errors.push('params.rune must be THOR.RUNE');
|
|
1308
|
+
// Get the pool for the asset
|
|
1290
1309
|
const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset.asset);
|
|
1310
|
+
// Calculate liquidity units
|
|
1291
1311
|
const lpUnits = getLiquidityUnits({ asset: params.asset, rune: params.rune }, assetPool);
|
|
1312
|
+
// Get inbound details
|
|
1292
1313
|
const inboundDetails = yield this.thorchainCache.getInboundDetails();
|
|
1314
|
+
// Create unit data
|
|
1293
1315
|
const unitData = {
|
|
1294
1316
|
liquidityUnits: lpUnits,
|
|
1295
1317
|
totalUnits: new BigNumber(assetPool.thornodeDetails.LP_units),
|
|
1296
1318
|
};
|
|
1319
|
+
// Calculate pool share
|
|
1297
1320
|
const poolShare = getPoolShare(unitData, assetPool);
|
|
1321
|
+
// Calculate wait time
|
|
1298
1322
|
const assetWaitTimeSeconds = yield this.confCounting(params.asset);
|
|
1299
1323
|
const runeWaitTimeSeconds = yield this.confCounting(params.rune);
|
|
1300
1324
|
const waitTimeSeconds = assetWaitTimeSeconds > runeWaitTimeSeconds ? assetWaitTimeSeconds : runeWaitTimeSeconds;
|
|
1325
|
+
// Calculate inbound fees
|
|
1301
1326
|
let assetInboundFee = new CryptoAmount(baseAmount(0), params.asset.asset);
|
|
1302
1327
|
let runeInboundFee = new CryptoAmount(baseAmount(0), AssetRuneNative);
|
|
1303
1328
|
if (!params.asset.assetAmount.eq(0)) {
|
|
@@ -1310,8 +1335,11 @@ class ThorchainQuery {
|
|
|
1310
1335
|
if (runeInboundFee.assetAmount.amount().times(3).gt(params.rune.assetAmount.amount()))
|
|
1311
1336
|
errors.push(`Rune amount is less than fees`);
|
|
1312
1337
|
}
|
|
1338
|
+
// Calculate total fees
|
|
1313
1339
|
const totalFees = (yield this.convert(assetInboundFee, AssetRuneNative)).plus(runeInboundFee);
|
|
1340
|
+
// Calculate slip
|
|
1314
1341
|
const slip = getSlipOnLiquidity({ asset: params.asset, rune: params.rune }, assetPool);
|
|
1342
|
+
// Create estimate LP object
|
|
1315
1343
|
const estimateLP = {
|
|
1316
1344
|
assetPool: assetPool.thornodeDetails.asset,
|
|
1317
1345
|
slipPercent: slip.times(100),
|
|
@@ -1333,9 +1361,9 @@ class ThorchainQuery {
|
|
|
1333
1361
|
});
|
|
1334
1362
|
}
|
|
1335
1363
|
/**
|
|
1336
|
-
* @param - Asset for
|
|
1337
|
-
* @param address - address used for
|
|
1338
|
-
* @returns -
|
|
1364
|
+
* @param - Asset for LP
|
|
1365
|
+
* @param address - address used for LP
|
|
1366
|
+
* @returns - Object of type LiquidityPosition
|
|
1339
1367
|
*/
|
|
1340
1368
|
checkLiquidityPosition(asset, assetOrRuneAddress) {
|
|
1341
1369
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1344,6 +1372,7 @@ class ThorchainQuery {
|
|
|
1344
1372
|
throw Error(`Could not find pool for ${asset}`);
|
|
1345
1373
|
if (!assetOrRuneAddress)
|
|
1346
1374
|
throw Error(`No address provided ${assetOrRuneAddress}`);
|
|
1375
|
+
// Get the current block number for that chain
|
|
1347
1376
|
const liquidityProvider = yield this.thorchainCache.thornode.getLiquidityProvider(poolAsset.assetString, assetOrRuneAddress);
|
|
1348
1377
|
if (!liquidityProvider)
|
|
1349
1378
|
throw Error(`Could not find LP for ${assetOrRuneAddress}`);
|
|
@@ -1357,28 +1386,35 @@ class ThorchainQuery {
|
|
|
1357
1386
|
liquidityUnits: new BigNumber(liquidityProvider.units),
|
|
1358
1387
|
};
|
|
1359
1388
|
const networkValues = yield this.thorchainCache.thornode.getNetworkValues();
|
|
1389
|
+
// Create block object
|
|
1360
1390
|
const block = {
|
|
1361
1391
|
current: blockData.thorchain,
|
|
1362
1392
|
lastAdded: liquidityProvider.last_add_height,
|
|
1363
1393
|
fullProtection: networkValues['FULLIMPLOSSPROTECTIONBLOCKS'],
|
|
1364
1394
|
};
|
|
1365
1395
|
const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset);
|
|
1396
|
+
// Get the current LP
|
|
1366
1397
|
const currentLP = {
|
|
1367
1398
|
asset: baseAmount(liquidityProvider.asset_deposit_value, assetDecimals),
|
|
1368
1399
|
rune: baseAmount(liquidityProvider.rune_deposit_value),
|
|
1369
1400
|
};
|
|
1401
|
+
// Calculate pool share
|
|
1370
1402
|
const poolShare = getPoolShare(unitData, poolAsset);
|
|
1371
1403
|
// Liquidity Unit Value Index = sprt(assetdepth * runeDepth) / Poolunits
|
|
1372
1404
|
// Using this formula we can work out an individual position to find LUVI and then the growth rate
|
|
1405
|
+
// Calculate deposit and redeem Liquidity Unit Value Index (LUVI)
|
|
1373
1406
|
const depositLuvi = Math.sqrt(currentLP.asset.times(currentLP.rune).div(unitData.liquidityUnits).amount().toNumber());
|
|
1374
1407
|
const redeemLuvi = Math.sqrt(poolShare.assetShare.baseAmount
|
|
1375
1408
|
.times(poolShare.runeShare.baseAmount)
|
|
1376
1409
|
.div(unitData.liquidityUnits)
|
|
1377
1410
|
.amount()
|
|
1378
1411
|
.toNumber());
|
|
1412
|
+
// Calculate LP growth
|
|
1379
1413
|
const lpGrowth = redeemLuvi - depositLuvi;
|
|
1380
1414
|
const currentLpGrowth = lpGrowth > 0 ? lpGrowth / depositLuvi : 0;
|
|
1415
|
+
// Get impermanent loss protection data
|
|
1381
1416
|
const impermanentLossProtection = getLiquidityProtectionData(currentLP, poolShare, block);
|
|
1417
|
+
// Create Liquidity Position object
|
|
1382
1418
|
const lpPosition = {
|
|
1383
1419
|
poolShare,
|
|
1384
1420
|
lpGrowth: `${(currentLpGrowth * 100).toFixed(2)} %`,
|
|
@@ -1395,7 +1431,9 @@ class ThorchainQuery {
|
|
|
1395
1431
|
*/
|
|
1396
1432
|
getPoolRatios(asset) {
|
|
1397
1433
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1434
|
+
// Get pool data for the asset
|
|
1398
1435
|
const assetPool = yield this.thorchainCache.getPoolForAsset(asset);
|
|
1436
|
+
// Create pool ratios object
|
|
1399
1437
|
const poolRatio = {
|
|
1400
1438
|
assetToRune: assetPool.assetToRuneRatio,
|
|
1401
1439
|
runeToAsset: assetPool.runeToAssetRatio,
|
|
@@ -1404,27 +1442,31 @@ class ThorchainQuery {
|
|
|
1404
1442
|
});
|
|
1405
1443
|
}
|
|
1406
1444
|
/**
|
|
1407
|
-
*
|
|
1408
|
-
* @param params
|
|
1445
|
+
* Estimates the result of withdrawing liquidity from a pool
|
|
1446
|
+
* @param params - parameters needed for estimating withdrawal of liquidity
|
|
1447
|
+
* @returns - object of type EstimateWithdrawLP
|
|
1409
1448
|
*/
|
|
1410
1449
|
estimateWithdrawLP(params) {
|
|
1411
1450
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1412
1451
|
// Caution Dust Limits: BTC,BCH,LTC chains 10k sats; DOGE 1m Sats; ETH 0 wei; THOR 0 RUNE.
|
|
1413
1452
|
const assetOrRuneAddress = params.assetAddress ? params.assetAddress : params.runeAddress;
|
|
1453
|
+
// Check liquidity position for the provided asset
|
|
1414
1454
|
const memberDetail = yield this.checkLiquidityPosition(params.asset, assetOrRuneAddress);
|
|
1455
|
+
// Get dust values
|
|
1415
1456
|
const dustValues = yield this.getDustValues(params.asset); // returns asset and rune dust values
|
|
1457
|
+
// Get asset pool
|
|
1416
1458
|
const assetPool = yield this.thorchainCache.getPoolForAsset(params.asset);
|
|
1417
|
-
//
|
|
1459
|
+
// Calculate pool share
|
|
1418
1460
|
const poolShare = getPoolShare({
|
|
1419
1461
|
liquidityUnits: new BigNumber(memberDetail.position.units),
|
|
1420
1462
|
totalUnits: new BigNumber(assetPool.thornodeDetails.LP_units),
|
|
1421
1463
|
}, assetPool);
|
|
1422
|
-
//
|
|
1464
|
+
// Calculate slip on liquidity removal
|
|
1423
1465
|
const slip = getSlipOnLiquidity({
|
|
1424
1466
|
asset: poolShare.assetShare,
|
|
1425
1467
|
rune: poolShare.runeShare,
|
|
1426
1468
|
}, assetPool);
|
|
1427
|
-
//
|
|
1469
|
+
// Calculate wait time
|
|
1428
1470
|
const waitTimeSecondsForAsset = yield this.confCounting(poolShare.assetShare.div(params.percentage / 100));
|
|
1429
1471
|
const waitTimeSecondsForRune = yield this.confCounting(poolShare.runeShare.div(params.percentage / 100));
|
|
1430
1472
|
let waitTimeSeconds = 0;
|
|
@@ -1438,51 +1480,59 @@ class ThorchainQuery {
|
|
|
1438
1480
|
else {
|
|
1439
1481
|
waitTimeSeconds = waitTimeSecondsForRune;
|
|
1440
1482
|
}
|
|
1483
|
+
// Get inbound and outbound fees
|
|
1441
1484
|
const allInboundDetails = yield this.thorchainCache.getInboundDetails();
|
|
1442
1485
|
const inboundDetails = allInboundDetails[params.asset.chain];
|
|
1443
1486
|
const runeInbound = calcNetworkFee(AssetRuneNative, inboundDetails);
|
|
1444
1487
|
const assetInbound = calcNetworkFee(params.asset, inboundDetails);
|
|
1445
1488
|
const runeOutbound = calcOutboundFee(AssetRuneNative, inboundDetails);
|
|
1446
1489
|
const assetOutbound = calcOutboundFee(params.asset, inboundDetails);
|
|
1490
|
+
// Create an EstimateWithdrawLP object
|
|
1447
1491
|
const estimateLP = {
|
|
1448
1492
|
assetAddress: memberDetail.position.asset_address,
|
|
1449
1493
|
runeAddress: memberDetail.position.rune_address,
|
|
1450
1494
|
slipPercent: slip.times(100),
|
|
1451
1495
|
inbound: {
|
|
1452
1496
|
minToSend: {
|
|
1497
|
+
// Minimum amount to send
|
|
1453
1498
|
rune: dustValues.rune,
|
|
1454
1499
|
asset: dustValues.asset,
|
|
1455
|
-
total: (yield this.convert(dustValues.asset, AssetRuneNative)).plus(dustValues.rune),
|
|
1500
|
+
total: (yield this.convert(dustValues.asset, AssetRuneNative)).plus(dustValues.rune), // Total amount
|
|
1456
1501
|
},
|
|
1457
1502
|
fees: {
|
|
1503
|
+
// Inbound fees
|
|
1458
1504
|
rune: runeInbound,
|
|
1459
1505
|
asset: assetInbound,
|
|
1460
|
-
total: (yield this.convert(assetInbound, AssetRuneNative)).plus(runeInbound),
|
|
1506
|
+
total: (yield this.convert(assetInbound, AssetRuneNative)).plus(runeInbound), // Total fees
|
|
1461
1507
|
},
|
|
1462
1508
|
},
|
|
1463
1509
|
outboundFee: {
|
|
1510
|
+
// Outbound fees
|
|
1464
1511
|
asset: assetOutbound,
|
|
1465
1512
|
rune: runeOutbound,
|
|
1466
|
-
total: (yield this.convert(assetOutbound, AssetRuneNative)).plus(runeOutbound),
|
|
1513
|
+
total: (yield this.convert(assetOutbound, AssetRuneNative)).plus(runeOutbound), // Total fees
|
|
1467
1514
|
},
|
|
1468
1515
|
assetAmount: poolShare.assetShare,
|
|
1469
1516
|
runeAmount: poolShare.runeShare,
|
|
1470
1517
|
lpGrowth: memberDetail.lpGrowth,
|
|
1471
1518
|
estimatedWaitSeconds: waitTimeSeconds,
|
|
1472
1519
|
impermanentLossProtection: memberDetail.impermanentLossProtection,
|
|
1473
|
-
assetPool: assetPool.thornodeDetails.asset,
|
|
1520
|
+
assetPool: assetPool.thornodeDetails.asset, // Asset pool
|
|
1474
1521
|
};
|
|
1475
|
-
return estimateLP;
|
|
1522
|
+
return estimateLP; // Return the EstimateWithdrawLP object
|
|
1476
1523
|
});
|
|
1477
1524
|
}
|
|
1478
1525
|
/**
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
* @
|
|
1526
|
+
* Can this become a queried constant? added to inbound_addresses or something
|
|
1527
|
+
* Retrieves dust values for the given asset
|
|
1528
|
+
* @param asset - The asset for which to retrieve dust values
|
|
1529
|
+
* @returns - Object containing dust values
|
|
1482
1530
|
*/
|
|
1483
1531
|
getDustValues(asset) {
|
|
1484
1532
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1533
|
+
// Get the number of decimals for the asset
|
|
1485
1534
|
const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset);
|
|
1535
|
+
// Determine the dust values based on the asset's chain
|
|
1486
1536
|
switch (asset.chain) {
|
|
1487
1537
|
case 'BNB':
|
|
1488
1538
|
return {
|
|
@@ -1492,80 +1542,88 @@ class ThorchainQuery {
|
|
|
1492
1542
|
case 'BTC':
|
|
1493
1543
|
case `BCH`:
|
|
1494
1544
|
case `LTC`:
|
|
1495
|
-
// 10k sats
|
|
1545
|
+
// Dust value: 10k sats
|
|
1496
1546
|
return {
|
|
1497
1547
|
asset: new CryptoAmount(assetToBase(assetAmount(0.0001, assetDecimals)), asset),
|
|
1498
1548
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1499
1549
|
};
|
|
1500
1550
|
case 'ETH':
|
|
1501
|
-
// 0 wei
|
|
1551
|
+
// Dust value: 0 wei
|
|
1502
1552
|
return {
|
|
1503
1553
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1504
1554
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1505
1555
|
};
|
|
1506
1556
|
case 'THOR':
|
|
1507
|
-
// 0 Rune
|
|
1557
|
+
// Dust value: 0 Rune
|
|
1508
1558
|
return {
|
|
1509
1559
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1510
1560
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1511
1561
|
};
|
|
1512
1562
|
case 'GAIA':
|
|
1513
|
-
// 0 GAIA
|
|
1563
|
+
// Dust value: 0 GAIA
|
|
1514
1564
|
return {
|
|
1515
1565
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1516
1566
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1517
1567
|
};
|
|
1518
1568
|
case 'DOGE':
|
|
1519
|
-
// 1 million sats
|
|
1569
|
+
// Dust value: 1 million sats
|
|
1520
1570
|
return {
|
|
1521
1571
|
asset: new CryptoAmount(assetToBase(assetAmount(0.01, assetDecimals)), asset),
|
|
1522
1572
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1523
1573
|
};
|
|
1524
1574
|
case 'AVAX':
|
|
1525
|
-
// 0 AVAX
|
|
1575
|
+
// Dust value: 0 AVAX
|
|
1526
1576
|
return {
|
|
1527
1577
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1528
1578
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1529
1579
|
};
|
|
1530
1580
|
case 'BSC':
|
|
1531
|
-
// 0 BSC
|
|
1581
|
+
// Dust value: 0 BSC
|
|
1532
1582
|
return {
|
|
1533
1583
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1534
1584
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1535
1585
|
};
|
|
1536
1586
|
case 'MAYA':
|
|
1537
|
-
// 0 MAYA
|
|
1587
|
+
// Dust value: 0 MAYA
|
|
1538
1588
|
return {
|
|
1539
1589
|
asset: new CryptoAmount(assetToBase(assetAmount(0, assetDecimals)), asset),
|
|
1540
1590
|
rune: new CryptoAmount(assetToBase(assetAmount(0)), AssetRuneNative),
|
|
1541
1591
|
};
|
|
1542
1592
|
default:
|
|
1543
|
-
throw Error('Unknown chain');
|
|
1593
|
+
throw Error('Unknown chain'); // Throw error for unknown chain
|
|
1544
1594
|
}
|
|
1545
1595
|
});
|
|
1546
1596
|
}
|
|
1547
1597
|
// Savers Queries
|
|
1548
1598
|
// Derrived from https://dev.thorchain.org/thorchain-dev/connection-guide/savers-guide
|
|
1599
|
+
/**
|
|
1600
|
+
* Estimates the result of adding to a saver
|
|
1601
|
+
* @param addAmount - The amount to be added to the saver
|
|
1602
|
+
* @returns - Object of type EstimateAddSaver
|
|
1603
|
+
*/
|
|
1549
1604
|
estimateAddSaver(addAmount) {
|
|
1550
1605
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1551
|
-
let errors = [];
|
|
1552
|
-
//
|
|
1606
|
+
let errors = []; // Initialize errors array
|
|
1607
|
+
// Check for errors before sending quote
|
|
1553
1608
|
errors = yield this.getAddSaversEstimateErrors(addAmount);
|
|
1554
|
-
//
|
|
1609
|
+
// Request parameter amount should always be in 1e8
|
|
1610
|
+
// Adjust decimals if chain decimals != 8
|
|
1555
1611
|
const newAddAmount = addAmount.baseAmount.decimal != 8 ? getBaseAmountWithDiffDecimals(addAmount, 8) : addAmount.baseAmount.amount();
|
|
1556
1612
|
// Fetch quote
|
|
1557
|
-
const depositQuote = yield this.thorchainCache.thornode.getSaversDepositQuote(assetToString(addAmount.asset),
|
|
1558
|
-
|
|
1613
|
+
const depositQuote = yield this.thorchainCache.thornode.getSaversDepositQuote(assetToString(addAmount.asset), // Convert asset to string
|
|
1614
|
+
newAddAmount.toNumber());
|
|
1615
|
+
// Error handling
|
|
1559
1616
|
const response = JSON.parse(JSON.stringify(depositQuote));
|
|
1560
1617
|
if (response.error)
|
|
1561
|
-
errors.push(`Thornode request quote failed: ${response.error}`);
|
|
1562
|
-
//The recommended minimum inbound amount for this transaction type & inbound asset.
|
|
1618
|
+
errors.push(`Thornode request quote failed: ${response.error}`); // Push error to array if exists
|
|
1619
|
+
// The recommended minimum inbound amount for this transaction type & inbound asset.
|
|
1563
1620
|
// Sending less than this amount could result in failed refunds
|
|
1564
1621
|
if (depositQuote.recommended_min_amount_in &&
|
|
1565
1622
|
addAmount.baseAmount.amount().toNumber() < Number(depositQuote.recommended_min_amount_in))
|
|
1566
|
-
errors.push(`Error amount in: ${addAmount.baseAmount.amount().toNumber()} is less than
|
|
1623
|
+
errors.push(`Error amount in: ${addAmount.baseAmount.amount().toNumber()} is less than recommended Min Amount: ${depositQuote.recommended_min_amount_in}`);
|
|
1567
1624
|
// Return errors if there is any
|
|
1568
1625
|
if (errors.length > 0) {
|
|
1626
|
+
// Return an object with default values and errors
|
|
1569
1627
|
return {
|
|
1570
1628
|
assetAmount: addAmount,
|
|
1571
1629
|
estimatedDepositValue: new CryptoAmount(baseAmount(0), addAmount.asset),
|
|
@@ -1584,26 +1642,44 @@ class ThorchainQuery {
|
|
|
1584
1642
|
slipBasisPoints: -1,
|
|
1585
1643
|
recommendedMinAmountIn: depositQuote.recommended_min_amount_in,
|
|
1586
1644
|
canAddSaver: false,
|
|
1587
|
-
errors,
|
|
1645
|
+
errors, // Errors
|
|
1588
1646
|
};
|
|
1589
1647
|
}
|
|
1648
|
+
// Get pool details
|
|
1590
1649
|
const pool = (yield this.thorchainCache.getPoolForAsset(addAmount.asset)).thornodeDetails;
|
|
1650
|
+
// Get asset decimals
|
|
1591
1651
|
const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(addAmount.asset);
|
|
1652
|
+
// Get fee asset decimals
|
|
1592
1653
|
const feeAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(addAmount.asset);
|
|
1593
|
-
//
|
|
1654
|
+
// Organize fees
|
|
1594
1655
|
const saverFees = {
|
|
1595
|
-
affiliate: getCryptoAmountWithNotation(
|
|
1656
|
+
affiliate: getCryptoAmountWithNotation(
|
|
1657
|
+
// Affiliate fee
|
|
1658
|
+
new CryptoAmount(baseAmount(depositQuote.fees.affiliate), addAmount.asset), // Convert to base amount
|
|
1659
|
+
assetDecimals),
|
|
1596
1660
|
asset: assetFromStringEx(depositQuote.fees.asset),
|
|
1597
|
-
outbound: getCryptoAmountWithNotation(
|
|
1598
|
-
|
|
1599
|
-
|
|
1661
|
+
outbound: getCryptoAmountWithNotation(
|
|
1662
|
+
// Outbound fee
|
|
1663
|
+
new CryptoAmount(baseAmount(depositQuote.fees.outbound), assetFromStringEx(depositQuote.fees.asset)), // Convert to base amount
|
|
1664
|
+
feeAssetDecimals),
|
|
1665
|
+
liquidity: getCryptoAmountWithNotation(
|
|
1666
|
+
// Liquidity fee
|
|
1667
|
+
new CryptoAmount(baseAmount(depositQuote.fees.liquidity), assetFromStringEx(depositQuote.fees.asset)), // Convert to base amount
|
|
1668
|
+
feeAssetDecimals),
|
|
1669
|
+
totalBps: depositQuote.fees.total_bps || 0, // Total basis points
|
|
1600
1670
|
};
|
|
1601
|
-
//
|
|
1671
|
+
// Define saver filled capacity
|
|
1602
1672
|
const saverCapFilledPercent = (Number(pool.synth_supply) / Number(pool.balance_asset)) * 100;
|
|
1603
|
-
//
|
|
1673
|
+
// Return object
|
|
1604
1674
|
const estimateAddSaver = {
|
|
1605
|
-
assetAmount: getCryptoAmountWithNotation(
|
|
1606
|
-
|
|
1675
|
+
assetAmount: getCryptoAmountWithNotation(
|
|
1676
|
+
// Asset amount
|
|
1677
|
+
new CryptoAmount(baseAmount(depositQuote.expected_amount_out), addAmount.asset), // Convert to base amount
|
|
1678
|
+
assetDecimals),
|
|
1679
|
+
estimatedDepositValue: getCryptoAmountWithNotation(
|
|
1680
|
+
// Estimated deposit value
|
|
1681
|
+
new CryptoAmount(baseAmount(depositQuote.expected_amount_deposit), addAmount.asset), // Convert to base amount
|
|
1682
|
+
assetDecimals),
|
|
1607
1683
|
fee: saverFees,
|
|
1608
1684
|
expiry: new Date(depositQuote.expiry),
|
|
1609
1685
|
toAddress: depositQuote.inbound_address,
|
|
@@ -1613,25 +1689,27 @@ class ThorchainQuery {
|
|
|
1613
1689
|
slipBasisPoints: depositQuote.slippage_bps,
|
|
1614
1690
|
saverCapFilledPercent,
|
|
1615
1691
|
recommendedMinAmountIn: depositQuote.recommended_min_amount_in,
|
|
1616
|
-
errors,
|
|
1692
|
+
errors, // Errors
|
|
1617
1693
|
};
|
|
1618
|
-
return estimateAddSaver;
|
|
1694
|
+
return estimateAddSaver; // Return the EstimateAddSaver object
|
|
1619
1695
|
});
|
|
1620
1696
|
}
|
|
1621
1697
|
/**
|
|
1622
|
-
*
|
|
1623
|
-
* @param withdrawParams - height
|
|
1624
|
-
* @returns -
|
|
1698
|
+
* Estimates the result of withdrawing from a saver
|
|
1699
|
+
* @param withdrawParams - Withdrawal parameters including height, asset, address, and withdrawal basis points
|
|
1700
|
+
* @returns - Object of type EstimateWithdrawSaver
|
|
1625
1701
|
*/
|
|
1626
1702
|
estimateWithdrawSaver(withdrawParams) {
|
|
1627
1703
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1628
|
-
const errors = [];
|
|
1629
|
-
//
|
|
1704
|
+
const errors = []; // Initialize errors array
|
|
1705
|
+
// Return error if asset in is incorrect
|
|
1630
1706
|
if (isAssetRuneNative(withdrawParams.asset) || withdrawParams.asset.synth)
|
|
1631
1707
|
errors.push(`Native Rune and synth assets are not supported only L1's`);
|
|
1708
|
+
// Get inbound details
|
|
1632
1709
|
const inboundDetails = yield this.thorchainCache.getInboundDetails();
|
|
1633
|
-
// Check
|
|
1710
|
+
// Check if there is a position before calling withdraw quote
|
|
1634
1711
|
const checkPositon = yield this.getSaverPosition(withdrawParams);
|
|
1712
|
+
// If there are errors in the position, return those errors
|
|
1635
1713
|
if (checkPositon.errors.length > 0) {
|
|
1636
1714
|
for (let i = 0; i < checkPositon.errors.length; i++) {
|
|
1637
1715
|
errors.push(checkPositon.errors[i]);
|
|
@@ -1639,13 +1717,16 @@ class ThorchainQuery {
|
|
|
1639
1717
|
return {
|
|
1640
1718
|
dustAmount: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
|
|
1641
1719
|
dustThreshold: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
|
|
1642
|
-
expectedAssetAmount: new CryptoAmount(
|
|
1720
|
+
expectedAssetAmount: new CryptoAmount(// Expected asset amount
|
|
1721
|
+
assetToBase(assetAmount(checkPositon.redeemableValue.assetAmount.amount())), // Convert to base amount
|
|
1722
|
+
withdrawParams.asset),
|
|
1643
1723
|
fee: {
|
|
1644
1724
|
affiliate: new CryptoAmount(assetToBase(assetAmount(0)), withdrawParams.asset),
|
|
1645
1725
|
asset: withdrawParams.asset,
|
|
1646
1726
|
liquidity: new CryptoAmount(baseAmount(0), withdrawParams.asset),
|
|
1647
|
-
outbound: new CryptoAmount(
|
|
1648
|
-
|
|
1727
|
+
outbound: new CryptoAmount(// Outbound fee
|
|
1728
|
+
assetToBase(assetAmount(calcOutboundFee(withdrawParams.asset, inboundDetails[withdrawParams.asset.chain]).assetAmount.amount())), withdrawParams.asset),
|
|
1729
|
+
totalBps: 0, // Total basis points
|
|
1649
1730
|
},
|
|
1650
1731
|
expiry: new Date(0),
|
|
1651
1732
|
toAddress: '',
|
|
@@ -1655,7 +1736,7 @@ class ThorchainQuery {
|
|
|
1655
1736
|
outBoundDelayBlocks: 0,
|
|
1656
1737
|
outBoundDelaySeconds: 0,
|
|
1657
1738
|
slipBasisPoints: -1,
|
|
1658
|
-
errors,
|
|
1739
|
+
errors, // Errors array
|
|
1659
1740
|
};
|
|
1660
1741
|
}
|
|
1661
1742
|
// Request withdraw quote
|
|
@@ -1665,6 +1746,7 @@ class ThorchainQuery {
|
|
|
1665
1746
|
if (response.error)
|
|
1666
1747
|
errors.push(`Thornode request quote failed: ${response.error}`);
|
|
1667
1748
|
if (errors.length > 0) {
|
|
1749
|
+
// Return default values and errors if there are any errors
|
|
1668
1750
|
return {
|
|
1669
1751
|
dustAmount: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
|
|
1670
1752
|
dustThreshold: new CryptoAmount(baseAmount(0), getChainAsset(withdrawParams.asset.chain)),
|
|
@@ -1687,14 +1769,21 @@ class ThorchainQuery {
|
|
|
1687
1769
|
errors,
|
|
1688
1770
|
};
|
|
1689
1771
|
}
|
|
1772
|
+
// Extract the withdraw asset and chain asset from the withdraw quote
|
|
1690
1773
|
const withdrawAsset = assetFromStringEx(withdrawQuote.fees.asset);
|
|
1691
1774
|
const chainAsset = getChainAsset(withdrawParams.asset.chain);
|
|
1775
|
+
// Get the decimals for the withdraw asset and chain asset
|
|
1692
1776
|
const withdrawAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(withdrawAsset);
|
|
1693
1777
|
const chainAssetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(chainAsset);
|
|
1778
|
+
// Create an EstimateWithdrawSaver object with the necessary data
|
|
1694
1779
|
const estimateWithdrawSaver = {
|
|
1780
|
+
// Format the dust amount with appropriate notation and decimals
|
|
1695
1781
|
dustAmount: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.dust_amount), chainAsset), chainAssetDecimals),
|
|
1782
|
+
// Format the dust threshold with appropriate notation and decimals
|
|
1696
1783
|
dustThreshold: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.dust_threshold), chainAsset), chainAssetDecimals),
|
|
1784
|
+
// Format the expected asset amount with appropriate notation and decimals
|
|
1697
1785
|
expectedAssetAmount: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.expected_amount_out), withdrawParams.asset), withdrawAssetDecimals),
|
|
1786
|
+
// Format the withdrawal fees with appropriate notation and decimals
|
|
1698
1787
|
fee: {
|
|
1699
1788
|
affiliate: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.fees.affiliate), withdrawAsset), withdrawAssetDecimals),
|
|
1700
1789
|
asset: withdrawAsset,
|
|
@@ -1702,53 +1791,77 @@ class ThorchainQuery {
|
|
|
1702
1791
|
outbound: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(withdrawQuote.fees.outbound), withdrawAsset), withdrawAssetDecimals),
|
|
1703
1792
|
totalBps: withdrawQuote.fees.total_bps || 0,
|
|
1704
1793
|
},
|
|
1794
|
+
// Set the expiry date
|
|
1705
1795
|
expiry: new Date(withdrawQuote.expiry),
|
|
1796
|
+
// Set the recipient address
|
|
1706
1797
|
toAddress: withdrawQuote.inbound_address,
|
|
1798
|
+
// Set the memo
|
|
1707
1799
|
memo: withdrawQuote.memo,
|
|
1800
|
+
// Set the inbound delay blocks
|
|
1708
1801
|
inboundDelayBlocks: withdrawQuote.inbound_confirmation_blocks || 0,
|
|
1802
|
+
// Set the inbound delay seconds
|
|
1709
1803
|
inboundDelaySeconds: withdrawQuote.inbound_confirmation_seconds || 0,
|
|
1804
|
+
// Set the outbound delay blocks
|
|
1710
1805
|
outBoundDelayBlocks: withdrawQuote.outbound_delay_blocks || 0,
|
|
1806
|
+
// Set the outbound delay seconds
|
|
1711
1807
|
outBoundDelaySeconds: withdrawQuote.outbound_delay_seconds || 0,
|
|
1808
|
+
// Set the slip basis points
|
|
1712
1809
|
slipBasisPoints: withdrawQuote.slippage_bps,
|
|
1810
|
+
// Set the errors
|
|
1713
1811
|
errors,
|
|
1714
1812
|
};
|
|
1813
|
+
// Return the withdrawal estimation object
|
|
1715
1814
|
return estimateWithdrawSaver;
|
|
1716
1815
|
});
|
|
1717
1816
|
}
|
|
1718
1817
|
/**
|
|
1719
|
-
*
|
|
1720
|
-
* @param params -
|
|
1721
|
-
* @returns -
|
|
1818
|
+
* Retrieve the position of a saver given the asset, address, and height.
|
|
1819
|
+
* @param params - Object containing the asset, address, and height.
|
|
1820
|
+
* @returns - Object representing the saver's position.
|
|
1722
1821
|
*/
|
|
1723
1822
|
getSaverPosition(params) {
|
|
1724
1823
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1824
|
+
// Initialize errors array
|
|
1725
1825
|
const errors = [];
|
|
1826
|
+
// Retrieve inbound details
|
|
1726
1827
|
const inboundDetails = yield this.thorchainCache.getInboundDetails();
|
|
1828
|
+
// Get the decimals for the asset
|
|
1727
1829
|
const assetDecimals = yield this.thorchainCache.midgardQuery.getDecimalForAsset(params.asset);
|
|
1830
|
+
// Retrieve block data for the specified asset chain
|
|
1728
1831
|
const blockData = (yield this.thorchainCache.thornode.getLastBlock()).find((item) => item.chain === params.asset.chain);
|
|
1729
|
-
//
|
|
1832
|
+
// Retrieve the saver from the Thorchain node API
|
|
1730
1833
|
const savers = (yield this.thorchainCache.thornode.getSavers(`${params.asset.chain}.${params.asset.symbol}`)).find((item) => item.asset_address.toLowerCase() === params.address.toLowerCase());
|
|
1834
|
+
// Retrieve pool details for the specified asset
|
|
1731
1835
|
const pool = (yield this.thorchainCache.getPoolForAsset(params.asset)).thornodeDetails;
|
|
1836
|
+
// Push errors if necessary data is not found
|
|
1732
1837
|
if (!savers)
|
|
1733
1838
|
errors.push(`Could not find position for ${params.address}`);
|
|
1734
1839
|
if (!(savers === null || savers === void 0 ? void 0 : savers.last_add_height))
|
|
1735
1840
|
errors.push(`Could not find position for ${params.address}`);
|
|
1736
1841
|
if (!(blockData === null || blockData === void 0 ? void 0 : blockData.thorchain))
|
|
1737
1842
|
errors.push(`Could not get thorchain block height`);
|
|
1843
|
+
// Calculate the outbound fee
|
|
1738
1844
|
const outboundFee = calcOutboundFee(params.asset, inboundDetails[params.asset.chain]);
|
|
1739
1845
|
const convertToBaseEight = getBaseAmountWithDiffDecimals(outboundFee, 8);
|
|
1740
|
-
//
|
|
1846
|
+
// Push an error if the redeemable value is less than the outbound fee
|
|
1741
1847
|
if (Number(savers === null || savers === void 0 ? void 0 : savers.asset_redeem_value) < convertToBaseEight.toNumber())
|
|
1742
1848
|
errors.push(`Unlikely to withdraw balance as outbound fee is greater than redeemable amount`);
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
const
|
|
1746
|
-
const
|
|
1849
|
+
// Calculate the redeemable value
|
|
1850
|
+
// Extract necessary data for calculation
|
|
1851
|
+
const ownerUnits = Number(savers === null || savers === void 0 ? void 0 : savers.units); // Number of units owned by the saver
|
|
1852
|
+
const lastAdded = Number(savers === null || savers === void 0 ? void 0 : savers.last_add_height); // Height at which the last addition was made to the pool
|
|
1853
|
+
const saverUnits = Number(pool.savers_units); // Total units in the pool
|
|
1854
|
+
const assetDepth = Number(pool.savers_depth); // Total asset depth in the pool
|
|
1855
|
+
// Calculate the redeemable value of the saver's position based on their ownership in the pool
|
|
1747
1856
|
const redeemableValue = (ownerUnits / saverUnits) * assetDepth;
|
|
1857
|
+
// Format the deposit amount and redeemable asset amount with appropriate notation and decimals
|
|
1748
1858
|
const depositAmount = getCryptoAmountWithNotation(new CryptoAmount(baseAmount(savers === null || savers === void 0 ? void 0 : savers.asset_deposit_value), params.asset), assetDecimals);
|
|
1749
1859
|
const redeemableAssetAmount = getCryptoAmountWithNotation(new CryptoAmount(baseAmount(redeemableValue), params.asset), assetDecimals);
|
|
1860
|
+
// Calculate the age of the saver's position in years and days
|
|
1750
1861
|
const saversAge = (Number(blockData === null || blockData === void 0 ? void 0 : blockData.thorchain) - lastAdded) / ((365 * 86400) / 6);
|
|
1862
|
+
// Calculate the growth percentage of the saver's position
|
|
1751
1863
|
const saverGrowth = redeemableAssetAmount.minus(depositAmount).div(depositAmount).times(100);
|
|
1864
|
+
// Create and populate a SaversPosition object with the calculated values
|
|
1752
1865
|
const saversPos = {
|
|
1753
1866
|
depositValue: depositAmount,
|
|
1754
1867
|
redeemableValue: redeemableAssetAmount,
|
|
@@ -1757,29 +1870,47 @@ class ThorchainQuery {
|
|
|
1757
1870
|
ageInYears: saversAge,
|
|
1758
1871
|
ageInDays: saversAge * 365,
|
|
1759
1872
|
asset: params.asset,
|
|
1760
|
-
errors,
|
|
1873
|
+
errors, // Array of any errors encountered during the calculation
|
|
1761
1874
|
};
|
|
1875
|
+
// Return the SaversPosition object representing the saver's position
|
|
1762
1876
|
return saversPos;
|
|
1763
1877
|
});
|
|
1764
1878
|
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Get errors related to estimating the addition of funds to a saver's pool.
|
|
1881
|
+
* @param addAmount - Amount of funds to be added to the saver's pool.
|
|
1882
|
+
* @returns An array of strings representing any errors encountered during the estimation process.
|
|
1883
|
+
*/
|
|
1765
1884
|
getAddSaversEstimateErrors(addAmount) {
|
|
1766
1885
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1767
1886
|
const errors = [];
|
|
1887
|
+
// Retrieve all pools
|
|
1768
1888
|
const pools = yield this.thorchainCache.getPools();
|
|
1889
|
+
// Filter out saver's pools with non-zero depth
|
|
1769
1890
|
const saversPools = Object.values(pools).filter((i) => i.thornodeDetails.savers_depth !== '0');
|
|
1891
|
+
// Retrieve inbound details
|
|
1770
1892
|
const inboundDetails = yield this.thorchainCache.getInboundDetails();
|
|
1893
|
+
// Find the saver's pool corresponding to the provided asset
|
|
1771
1894
|
const saverPool = saversPools.find((i) => assetToString(i.asset) === assetToString(addAmount.asset));
|
|
1895
|
+
// Check if a saver's pool exists for the provided asset
|
|
1772
1896
|
if (!saverPool)
|
|
1773
1897
|
errors.push(` ${assetToString(addAmount.asset)} does not have a saver's pool`);
|
|
1898
|
+
// Check if the chain for the provided asset is halted
|
|
1774
1899
|
if (inboundDetails[addAmount.asset.chain].haltedChain)
|
|
1775
1900
|
errors.push(`${addAmount.asset.chain} is halted, cannot add`);
|
|
1901
|
+
// Get details of the pool for the provided asset
|
|
1776
1902
|
const pool = (yield this.thorchainCache.getPoolForAsset(addAmount.asset)).thornodeDetails;
|
|
1903
|
+
// Check if the pool for the provided asset is available
|
|
1777
1904
|
if (pool.status.toLowerCase() !== 'available')
|
|
1778
1905
|
errors.push(`Pool is not available for this asset ${assetToString(addAmount.asset)}`);
|
|
1779
|
-
|
|
1780
|
-
const
|
|
1906
|
+
// Calculate inbound fee for the provided asset
|
|
1907
|
+
const inboundFee = new CryptoAmount(baseAmount(inboundDetails[addAmount.asset.chain].gasRate), addAmount.asset);
|
|
1908
|
+
// Convert inbound fee to the same asset as the addAmount to ensure consistency in calculations
|
|
1909
|
+
const inboundFeeInAddAmountAsset = yield this.convert(inboundFee, addAmount.asset);
|
|
1910
|
+
// Check if the addAmount covers the inbound fees
|
|
1781
1911
|
if (addAmount.lte(inboundFeeInAddAmountAsset))
|
|
1782
1912
|
errors.push(`Add amount does not cover fees`);
|
|
1913
|
+
// Return array of errors encountered during estimation
|
|
1783
1914
|
return errors;
|
|
1784
1915
|
});
|
|
1785
1916
|
}
|
|
@@ -1856,17 +1987,21 @@ class ThorchainQuery {
|
|
|
1856
1987
|
});
|
|
1857
1988
|
}
|
|
1858
1989
|
/**
|
|
1859
|
-
*
|
|
1860
|
-
* @param loanOpenParams -
|
|
1861
|
-
* @returns
|
|
1990
|
+
* Get a quote for opening a loan.
|
|
1991
|
+
* @param loanOpenParams - Parameters needed for the endpoint.
|
|
1992
|
+
* @returns A Promise resolving to a LoanOpenQuote.
|
|
1862
1993
|
*/
|
|
1863
1994
|
getLoanQuoteClose({ asset, amount, loanAsset, loanOwner, minOut, height, }) {
|
|
1864
1995
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1865
1996
|
const errors = [];
|
|
1997
|
+
// Retrieve loan open response from ThorNode API
|
|
1866
1998
|
const loanCloseResp = yield this.thorchainCache.thornode.getLoanQuoteClose(`${asset.chain}.${asset.symbol}`, amount.baseAmount.amount().toNumber(), `${loanAsset.chain}.${loanAsset.symbol}`, loanOwner, minOut, height);
|
|
1999
|
+
// Parse loan open response
|
|
1867
2000
|
const response = JSON.parse(JSON.stringify(loanCloseResp));
|
|
2001
|
+
// Check for errors in response
|
|
1868
2002
|
if (response.error)
|
|
1869
2003
|
errors.push(`Thornode request quote failed: ${response.error}`);
|
|
2004
|
+
// If errors exist, return an object with error details
|
|
1870
2005
|
if (errors.length > 0) {
|
|
1871
2006
|
return {
|
|
1872
2007
|
inboundAddress: '',
|
|
@@ -1894,6 +2029,7 @@ class ThorchainQuery {
|
|
|
1894
2029
|
errors: errors,
|
|
1895
2030
|
};
|
|
1896
2031
|
}
|
|
2032
|
+
// Construct loan open quote object
|
|
1897
2033
|
const loanCloseQuote = {
|
|
1898
2034
|
inboundAddress: loanCloseResp.inbound_address,
|
|
1899
2035
|
expectedWaitTime: {
|
|
@@ -1923,19 +2059,23 @@ class ThorchainQuery {
|
|
|
1923
2059
|
});
|
|
1924
2060
|
}
|
|
1925
2061
|
/**
|
|
1926
|
-
*
|
|
1927
|
-
* @param thorname -
|
|
1928
|
-
* @
|
|
2062
|
+
* Retrieve details for a THORName.
|
|
2063
|
+
* @param thorname - The THORName to get details for.
|
|
2064
|
+
* @param height - Optional parameter specifying the block height.
|
|
2065
|
+
* @returns A Promise resolving to ThornameDetails.
|
|
1929
2066
|
*/
|
|
1930
2067
|
getThornameDetails(thorname, height) {
|
|
1931
2068
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1932
2069
|
const errors = [];
|
|
1933
2070
|
try {
|
|
2071
|
+
// Retrieve THORName details from ThorNode API
|
|
1934
2072
|
const thornameResp = yield this.thorchainCache.thornode.getThornameDetails(thorname, height);
|
|
1935
2073
|
const response = JSON.parse(JSON.stringify(thornameResp));
|
|
2074
|
+
// Check for errors in response
|
|
1936
2075
|
if (response.error)
|
|
1937
2076
|
errors.push(`Thornode request quote failed: ${response.error}`);
|
|
1938
2077
|
if (errors.length > 0) {
|
|
2078
|
+
// If errors exist, return an object with error details
|
|
1939
2079
|
const errorResp = {
|
|
1940
2080
|
name: '',
|
|
1941
2081
|
expireBlockHeight: 0,
|
|
@@ -1947,10 +2087,12 @@ class ThorchainQuery {
|
|
|
1947
2087
|
};
|
|
1948
2088
|
return errorResp;
|
|
1949
2089
|
}
|
|
2090
|
+
// Map aliases to ThornameAlias objects
|
|
1950
2091
|
const thornameAliases = thornameResp.aliases.map((alias) => ({
|
|
1951
2092
|
chain: alias.chain,
|
|
1952
2093
|
address: alias.address,
|
|
1953
2094
|
}));
|
|
2095
|
+
// Construct ThornameDetails object
|
|
1954
2096
|
const thornameDetails = {
|
|
1955
2097
|
name: thornameResp.name || '',
|
|
1956
2098
|
expireBlockHeight: thornameResp.expire_block_height || 0,
|
|
@@ -1962,6 +2104,7 @@ class ThorchainQuery {
|
|
|
1962
2104
|
return thornameDetails;
|
|
1963
2105
|
}
|
|
1964
2106
|
catch (e) {
|
|
2107
|
+
// If an error occurs during the process, return an object with error details
|
|
1965
2108
|
const errorResp = {
|
|
1966
2109
|
name: '',
|
|
1967
2110
|
expireBlockHeight: 0,
|
|
@@ -1976,31 +2119,32 @@ class ThorchainQuery {
|
|
|
1976
2119
|
});
|
|
1977
2120
|
}
|
|
1978
2121
|
/**
|
|
1979
|
-
* Generate the memo and estimate the cost of
|
|
1980
|
-
* @param thorname -
|
|
1981
|
-
* @param chain -
|
|
1982
|
-
* @param chainAddress -
|
|
1983
|
-
* @param owner -
|
|
1984
|
-
* @param preferredAsset -
|
|
1985
|
-
* @param expirity -
|
|
1986
|
-
* @param isUpdate -
|
|
1987
|
-
* @returns
|
|
2122
|
+
* Generate the memo and estimate the cost of registering or updating a THORName.
|
|
2123
|
+
* @param thorname - The name to register or update.
|
|
2124
|
+
* @param chain - The chain to update/register.
|
|
2125
|
+
* @param chainAddress - The address to add to chain alias.
|
|
2126
|
+
* @param owner - The owner address (rune address).
|
|
2127
|
+
* @param preferredAsset - The preferred asset.
|
|
2128
|
+
* @param expirity - The expiry of the domain in MILLISECONDS.
|
|
2129
|
+
* @param isUpdate - True only if the domain is already registered and you want to update its data.
|
|
2130
|
+
* @returns Memo and value of deposit.
|
|
1988
2131
|
*/
|
|
1989
2132
|
estimateThorname(params) {
|
|
1990
2133
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1991
|
-
//
|
|
2134
|
+
// Check if THORName already exists
|
|
1992
2135
|
const thornameDetails = yield this.getThornameDetails(params.thorname);
|
|
1993
2136
|
if (thornameDetails.owner !== '' && !params.isUpdate) {
|
|
1994
2137
|
throw Error('Thorname already registered');
|
|
1995
2138
|
}
|
|
2139
|
+
// Retrieve block data
|
|
1996
2140
|
const blockData = yield this.thorchainCache.thornode.getLastBlock();
|
|
1997
2141
|
const currentThorchainHeight = blockData[0].thorchain;
|
|
1998
2142
|
const currentHeightForExpirity = params.isUpdate
|
|
1999
2143
|
? thornameDetails === null || thornameDetails === void 0 ? void 0 : thornameDetails.expireBlockHeight
|
|
2000
2144
|
: currentThorchainHeight;
|
|
2001
|
-
//
|
|
2145
|
+
// Default expiry
|
|
2002
2146
|
let numberOfBlocksToAddToExpirity = params.isUpdate ? 0 : 5259600; // One year by default
|
|
2003
|
-
//
|
|
2147
|
+
// Compute expiry height
|
|
2004
2148
|
if (params.expirity) {
|
|
2005
2149
|
const currentTimestamp = Math.floor(Date.now() / 1000);
|
|
2006
2150
|
const expirityTimestamp = Math.floor(params.expirity.getTime() / 1000);
|
|
@@ -2011,7 +2155,7 @@ class ThorchainQuery {
|
|
|
2011
2155
|
? newHeightExpirity - (thornameDetails === null || thornameDetails === void 0 ? void 0 : thornameDetails.expireBlockHeight)
|
|
2012
2156
|
: numberOfBlocks;
|
|
2013
2157
|
}
|
|
2014
|
-
//
|
|
2158
|
+
// Compute value
|
|
2015
2159
|
const constantsDetails = yield this.thorchainCache.thornode.getTcConstants();
|
|
2016
2160
|
const oneTimeFee = params.isUpdate ? baseAmount(0) : baseAmount(constantsDetails['TNSRegisterFee']);
|
|
2017
2161
|
const totalFeePerBlock = baseAmount(constantsDetails['TNSFeePerBlock']).times(numberOfBlocksToAddToExpirity > 0 ? numberOfBlocksToAddToExpirity : 0);
|
|
@@ -2023,8 +2167,32 @@ class ThorchainQuery {
|
|
|
2023
2167
|
};
|
|
2024
2168
|
});
|
|
2025
2169
|
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Get inbound addresses details
|
|
2172
|
+
* @returns Inbound details
|
|
2173
|
+
*/
|
|
2174
|
+
getInboundDetails() {
|
|
2175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2176
|
+
return this.thorchainCache.getInboundDetails();
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
/**
|
|
2180
|
+
* Get chain inbound address details
|
|
2181
|
+
* @returns Inbound details
|
|
2182
|
+
*/
|
|
2183
|
+
getChainInboundDetails(chain) {
|
|
2184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2185
|
+
const inboundDetails = yield this.getInboundDetails();
|
|
2186
|
+
if (!inboundDetails[chain])
|
|
2187
|
+
throw Error(`No inbound details known for ${chain} chain`);
|
|
2188
|
+
return inboundDetails[chain];
|
|
2189
|
+
});
|
|
2190
|
+
}
|
|
2026
2191
|
}
|
|
2027
2192
|
|
|
2193
|
+
/**
|
|
2194
|
+
* Enum representing different types of transactions.
|
|
2195
|
+
*/
|
|
2028
2196
|
var TxType;
|
|
2029
2197
|
(function (TxType) {
|
|
2030
2198
|
TxType["Swap"] = "Swap";
|
|
@@ -2036,12 +2204,18 @@ var TxType;
|
|
|
2036
2204
|
TxType["Other"] = "Other";
|
|
2037
2205
|
TxType["Unknown"] = "Unknown";
|
|
2038
2206
|
})(TxType || (TxType = {}));
|
|
2207
|
+
/**
|
|
2208
|
+
* Enum representing inbound transaction status.
|
|
2209
|
+
*/
|
|
2039
2210
|
var InboundStatus;
|
|
2040
2211
|
(function (InboundStatus) {
|
|
2041
2212
|
InboundStatus["Observed_Consensus"] = "Observed_Consensus";
|
|
2042
2213
|
InboundStatus["Observed_Incomplete"] = "Observed_Incomplete";
|
|
2043
2214
|
InboundStatus["Unknown"] = "Unknown";
|
|
2044
2215
|
})(InboundStatus || (InboundStatus = {}));
|
|
2216
|
+
/**
|
|
2217
|
+
* Enum representing swap transaction status.
|
|
2218
|
+
*/
|
|
2045
2219
|
var SwapStatus;
|
|
2046
2220
|
(function (SwapStatus) {
|
|
2047
2221
|
SwapStatus["Complete"] = "Complete";
|
|
@@ -2049,6 +2223,9 @@ var SwapStatus;
|
|
|
2049
2223
|
SwapStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
|
|
2050
2224
|
SwapStatus["Incomplete"] = "Incomplete";
|
|
2051
2225
|
})(SwapStatus || (SwapStatus = {}));
|
|
2226
|
+
/**
|
|
2227
|
+
* Enum representing add liquidity pool transaction status.
|
|
2228
|
+
*/
|
|
2052
2229
|
var AddLpStatus;
|
|
2053
2230
|
(function (AddLpStatus) {
|
|
2054
2231
|
AddLpStatus["Complete"] = "Complete";
|
|
@@ -2056,18 +2233,27 @@ var AddLpStatus;
|
|
|
2056
2233
|
AddLpStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
|
|
2057
2234
|
AddLpStatus["Incomplete"] = "Incomplete";
|
|
2058
2235
|
})(AddLpStatus || (AddLpStatus = {}));
|
|
2236
|
+
/**
|
|
2237
|
+
* Enum representing withdraw transaction status.
|
|
2238
|
+
*/
|
|
2059
2239
|
var WithdrawStatus;
|
|
2060
2240
|
(function (WithdrawStatus) {
|
|
2061
2241
|
WithdrawStatus["Complete"] = "Complete";
|
|
2062
2242
|
WithdrawStatus["Incomplete"] = "Incomplete";
|
|
2063
2243
|
WithdrawStatus["Complete_Refunded"] = "Complete_Refunded";
|
|
2064
2244
|
})(WithdrawStatus || (WithdrawStatus = {}));
|
|
2245
|
+
/**
|
|
2246
|
+
* Enum representing refund transaction status.
|
|
2247
|
+
*/
|
|
2065
2248
|
var RefundStatus;
|
|
2066
2249
|
(function (RefundStatus) {
|
|
2067
2250
|
RefundStatus["Complete"] = "Complete";
|
|
2068
2251
|
RefundStatus["Incomplete"] = "Incomplete";
|
|
2069
2252
|
RefundStatus["Complete_Refunded"] = "Complete_Refunded";
|
|
2070
2253
|
})(RefundStatus || (RefundStatus = {}));
|
|
2254
|
+
/**
|
|
2255
|
+
* Enum representing add saver transaction status.
|
|
2256
|
+
*/
|
|
2071
2257
|
var AddSaverStatus;
|
|
2072
2258
|
(function (AddSaverStatus) {
|
|
2073
2259
|
AddSaverStatus["Complete"] = "Complete";
|
|
@@ -2075,11 +2261,24 @@ var AddSaverStatus;
|
|
|
2075
2261
|
AddSaverStatus["Complete_Below_Dust"] = "Complete_Below_Dust";
|
|
2076
2262
|
AddSaverStatus["Incomplete"] = "Incomplete";
|
|
2077
2263
|
})(AddSaverStatus || (AddSaverStatus = {}));
|
|
2264
|
+
/**
|
|
2265
|
+
* Class for managing transaction stages.
|
|
2266
|
+
*/
|
|
2078
2267
|
class TransactionStage {
|
|
2268
|
+
/**
|
|
2269
|
+
* Constructor to create a TransactionStage instance.
|
|
2270
|
+
* @param thorchainCache - ThorchainCache instance.
|
|
2271
|
+
* @param chainAttributes - ChainAttributes object representing default chain attributes.
|
|
2272
|
+
*/
|
|
2079
2273
|
constructor(thorchainCache, chainAttributes = DefaultChainAttributes) {
|
|
2080
2274
|
this.thorchainCache = thorchainCache;
|
|
2081
2275
|
this.chainAttributes = chainAttributes;
|
|
2082
2276
|
}
|
|
2277
|
+
/**
|
|
2278
|
+
* Checks transaction progress.
|
|
2279
|
+
* @param inboundTxHash - Inbound transaction hash.
|
|
2280
|
+
* @returns Promise<TXProgress> - Transaction progress object.
|
|
2281
|
+
*/
|
|
2083
2282
|
checkTxProgress(inboundTxHash) {
|
|
2084
2283
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2085
2284
|
let txData;
|
|
@@ -2121,29 +2320,37 @@ class TransactionStage {
|
|
|
2121
2320
|
return progress;
|
|
2122
2321
|
});
|
|
2123
2322
|
}
|
|
2323
|
+
/**
|
|
2324
|
+
* Checks the progress of a swap transaction.
|
|
2325
|
+
* @param txData - Transaction details response.
|
|
2326
|
+
* @param progress - Transaction progress object.
|
|
2327
|
+
*/
|
|
2124
2328
|
checkSwapProgress(txData, progress) {
|
|
2125
2329
|
var _a, _b, _c, _d;
|
|
2126
2330
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2127
2331
|
if (progress.inboundObserved) {
|
|
2332
|
+
// Extract memo fields
|
|
2128
2333
|
const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
|
|
2129
2334
|
const memoFields = this.parseSwapMemo(memo);
|
|
2130
2335
|
const assetOut = assetFromStringEx(memoFields.asset.toUpperCase());
|
|
2131
|
-
//
|
|
2336
|
+
// Determine swap status
|
|
2132
2337
|
const swapStatus = ((_b = txData.out_txs[0].memo) === null || _b === void 0 ? void 0 : _b.match('OUT')) ? SwapStatus.Complete : SwapStatus.Complete_Refunded;
|
|
2133
|
-
// current height
|
|
2338
|
+
// Get current chain height for confirmations
|
|
2134
2339
|
const chainHeight = yield this.blockHeight(AssetRuneNative);
|
|
2135
|
-
//
|
|
2340
|
+
// Expected outbound height and date
|
|
2136
2341
|
const outboundHeight = Number((_c = txData.outbound_height) !== null && _c !== void 0 ? _c : txData.finalised_height);
|
|
2137
2342
|
const expectedOutBlock = Number((_d = txData.outbound_height) !== null && _d !== void 0 ? _d : txData.finalised_height);
|
|
2138
2343
|
const expectedOutDate = yield this.blockToDate(THORChain, txData, outboundHeight); // height held in the scheduled queue
|
|
2344
|
+
// Calculate confirmations
|
|
2139
2345
|
const confirmations = chainHeight > outboundHeight ? chainHeight - outboundHeight : 0;
|
|
2346
|
+
// Calculate minimum amount out and affiliate fee
|
|
2140
2347
|
const minimumAmountOut = memoFields.limit
|
|
2141
2348
|
? yield this.getCryptoAmount(memoFields.limit, assetOut)
|
|
2142
2349
|
: yield this.getCryptoAmount('0', assetOut);
|
|
2143
2350
|
const affliateFee = memoFields.affiliateFee
|
|
2144
2351
|
? yield this.getCryptoAmount(memoFields.affiliateFee, assetOut)
|
|
2145
2352
|
: yield this.getCryptoAmount('0', assetOut);
|
|
2146
|
-
//
|
|
2353
|
+
// Construct swap info object
|
|
2147
2354
|
const swapInfo = {
|
|
2148
2355
|
status: swapStatus,
|
|
2149
2356
|
expectedOutBlock,
|
|
@@ -2154,10 +2361,16 @@ class TransactionStage {
|
|
|
2154
2361
|
affliateFee,
|
|
2155
2362
|
toAddress: memoFields.destAddress,
|
|
2156
2363
|
};
|
|
2364
|
+
// Assign swap info to progress object
|
|
2157
2365
|
progress.swapInfo = swapInfo;
|
|
2158
2366
|
}
|
|
2159
2367
|
});
|
|
2160
2368
|
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Parses swap memo to extract relevant fields.
|
|
2371
|
+
* @param memo - Transaction memo.
|
|
2372
|
+
* @returns Parsed swap memo fields.
|
|
2373
|
+
*/
|
|
2161
2374
|
parseSwapMemo(memo) {
|
|
2162
2375
|
//SWAP:ASSET:DESTADDR:LIM:AFFILIATE:FEE
|
|
2163
2376
|
const parts = memo.split(`:`);
|
|
@@ -2169,12 +2382,23 @@ class TransactionStage {
|
|
|
2169
2382
|
const affiliateFee = parts.length > 5 && parts[5].length > 0 ? parts[5] : undefined;
|
|
2170
2383
|
return { action, asset, destAddress, limit, affiliateAddress, affiliateFee };
|
|
2171
2384
|
}
|
|
2385
|
+
/**
|
|
2386
|
+
* Retrieves a CryptoAmount object.
|
|
2387
|
+
* @param baseAmt - Base amount.
|
|
2388
|
+
* @param asset - Asset object.
|
|
2389
|
+
* @returns Promise<CryptoAmount> - CryptoAmount object.
|
|
2390
|
+
*/
|
|
2172
2391
|
getCryptoAmount(baseAmt, asset) {
|
|
2173
2392
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2174
2393
|
const decimals = THORChain === asset.chain ? 8 : Number(yield this.thorchainCache.midgardQuery.getDecimalForAsset(asset));
|
|
2175
2394
|
return new CryptoAmount(baseAmount(baseAmt, decimals), asset);
|
|
2176
2395
|
});
|
|
2177
2396
|
}
|
|
2397
|
+
/**
|
|
2398
|
+
* Determines the observed status of a transaction.
|
|
2399
|
+
* @param txData - Transaction signers response.
|
|
2400
|
+
* @returns Promise<TXProgress> - Transaction progress object.
|
|
2401
|
+
*/
|
|
2178
2402
|
determineObserved(txData) {
|
|
2179
2403
|
var _a, _b, _c, _d;
|
|
2180
2404
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -2225,14 +2449,21 @@ class TransactionStage {
|
|
|
2225
2449
|
return progress;
|
|
2226
2450
|
});
|
|
2227
2451
|
}
|
|
2452
|
+
/**
|
|
2453
|
+
* Checks the progress of an add liquidity pool transaction.
|
|
2454
|
+
* @param txData - Transaction details response.
|
|
2455
|
+
* @param progress - Transaction progress object.
|
|
2456
|
+
*/
|
|
2228
2457
|
checkAddLpProgress(txData, progress) {
|
|
2229
2458
|
var _a;
|
|
2230
2459
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2231
2460
|
if (progress.inboundObserved) {
|
|
2461
|
+
// Extract memo fields
|
|
2232
2462
|
const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
|
|
2233
2463
|
const memoFields = this.parseAddLpMemo(memo);
|
|
2234
2464
|
const asset = assetFromStringEx(memoFields.asset);
|
|
2235
2465
|
const isSymmetric = memoFields.pairedAddress ? true : false;
|
|
2466
|
+
// Determine if assetTx or runeTx
|
|
2236
2467
|
const assetTx = !isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
|
|
2237
2468
|
const runeTx = isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
|
|
2238
2469
|
const pairedAssetExpectedConfirmationDate = assetTx ? yield this.blockToDate(asset.chain, txData) : undefined;
|
|
@@ -2250,27 +2481,38 @@ class TransactionStage {
|
|
|
2250
2481
|
}
|
|
2251
2482
|
});
|
|
2252
2483
|
}
|
|
2484
|
+
/**
|
|
2485
|
+
* Checks the progress of a withdraw liquidity pool transaction.
|
|
2486
|
+
* @param txData - Transaction details response.
|
|
2487
|
+
* @param progress - Transaction progress object.
|
|
2488
|
+
*/
|
|
2253
2489
|
checkWithdrawLpProgress(txData, progress) {
|
|
2254
2490
|
var _a, _b;
|
|
2255
2491
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2256
2492
|
if (progress.inboundObserved) {
|
|
2493
|
+
// Extract memo fields
|
|
2257
2494
|
const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
|
|
2258
2495
|
const memoFields = this.parseWithdrawLpMemo(memo);
|
|
2259
2496
|
const asset = assetFromStringEx(memoFields.asset);
|
|
2497
|
+
// Get the last block object
|
|
2260
2498
|
const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
|
|
2261
2499
|
const currentHeight = lastBlockObj.find((obj) => obj);
|
|
2262
|
-
//
|
|
2500
|
+
// Calculate expected confirmation date
|
|
2263
2501
|
const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
|
|
2264
2502
|
const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
|
|
2265
|
-
//
|
|
2503
|
+
// Determine transaction status
|
|
2266
2504
|
const status = txData.tx.status === 'done' ? WithdrawStatus.Complete : WithdrawStatus.Incomplete;
|
|
2505
|
+
// Extract output amount
|
|
2267
2506
|
const outAmount = status === WithdrawStatus.Complete ? JSON.stringify(txData.out_txs).split(`"amount":"`)[1].split(`"`) : '';
|
|
2507
|
+
// Extract relevant block heights and calculate estimated wait time
|
|
2268
2508
|
const outboundBlock = Number((_b = txData.outbound_height) !== null && _b !== void 0 ? _b : txData.finalised_height);
|
|
2269
2509
|
const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
|
|
2270
2510
|
const estimatedWaitTime = outboundBlock > currentTCHeight
|
|
2271
2511
|
? (outboundBlock - currentTCHeight) * this.chainAttributes[THORChain].avgBlockTimeInSecs
|
|
2272
2512
|
: 0;
|
|
2513
|
+
// Get withdrawal amount
|
|
2273
2514
|
const withdrawalAmount = yield this.getCryptoAmount(outAmount[0], asset);
|
|
2515
|
+
// Construct withdraw liquidity pool info object
|
|
2274
2516
|
const withdrawLpInfo = {
|
|
2275
2517
|
status,
|
|
2276
2518
|
withdrawalAmount,
|
|
@@ -2279,38 +2521,58 @@ class TransactionStage {
|
|
|
2279
2521
|
outboundHeight: outboundBlock,
|
|
2280
2522
|
estimatedWaitTime,
|
|
2281
2523
|
};
|
|
2524
|
+
// Assign withdraw liquidity pool info to progress object
|
|
2282
2525
|
progress.withdrawLpInfo = withdrawLpInfo;
|
|
2283
2526
|
}
|
|
2284
2527
|
});
|
|
2285
2528
|
}
|
|
2529
|
+
/**
|
|
2530
|
+
* Checks the progress of an add saver transaction.
|
|
2531
|
+
* @param txData - Transaction details response.
|
|
2532
|
+
* @param progress - Transaction progress object.
|
|
2533
|
+
*/
|
|
2286
2534
|
checkAddSaverProgress(txData, progress) {
|
|
2287
2535
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2288
2536
|
if (progress.inboundObserved) {
|
|
2537
|
+
// Determine if it's an asset transaction
|
|
2289
2538
|
const assetTx = !isAssetRuneNative(progress.inboundObserved.amount.asset) ? progress.inboundObserved : undefined;
|
|
2539
|
+
// Check saver vaults
|
|
2290
2540
|
const checkSaverVaults = yield this.thorchainCache.thornode.getSaver(txData.tx.tx.coins[0].asset, `${assetTx === null || assetTx === void 0 ? void 0 : assetTx.fromAddress}`);
|
|
2541
|
+
// Determine transaction status
|
|
2291
2542
|
const status = checkSaverVaults ? AddSaverStatus.Complete : AddSaverStatus.Incomplete;
|
|
2543
|
+
// Construct add saver info object
|
|
2292
2544
|
const addSaverInfo = {
|
|
2293
2545
|
status: status,
|
|
2294
2546
|
assetTx,
|
|
2295
2547
|
saverPos: checkSaverVaults,
|
|
2296
2548
|
};
|
|
2549
|
+
// Assign add saver info to progress object
|
|
2297
2550
|
progress.addSaverInfo = addSaverInfo;
|
|
2298
2551
|
}
|
|
2299
2552
|
});
|
|
2300
2553
|
}
|
|
2554
|
+
/**
|
|
2555
|
+
* Checks the progress of a withdraw saver transaction.
|
|
2556
|
+
* @param txData - Transaction details response.
|
|
2557
|
+
* @param progress - Transaction progress object.
|
|
2558
|
+
*/
|
|
2301
2559
|
checkWithdrawSaverProgress(txData, progress) {
|
|
2302
2560
|
var _a;
|
|
2303
2561
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2304
2562
|
if (progress.inboundObserved) {
|
|
2563
|
+
// Extract memo fields
|
|
2305
2564
|
const memo = (_a = txData.tx.tx.memo) !== null && _a !== void 0 ? _a : '';
|
|
2306
2565
|
const memoFields = this.parseWithdrawLpMemo(memo);
|
|
2307
2566
|
const asset = assetFromStringEx(memoFields.asset);
|
|
2567
|
+
// Get the last block object
|
|
2308
2568
|
const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
|
|
2309
2569
|
const currentHeight = lastBlockObj.find((obj) => obj);
|
|
2310
|
-
//
|
|
2570
|
+
// Calculate expected confirmation date
|
|
2311
2571
|
const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
|
|
2312
2572
|
const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
|
|
2573
|
+
// Extract output amount
|
|
2313
2574
|
const outAmount = txData.out_txs ? JSON.stringify(txData.out_txs).split(`"amount":"`)[1].split(`"`) : '';
|
|
2575
|
+
// Extract relevant block heights and calculate estimated wait time
|
|
2314
2576
|
const outboundBlock = Number(txData.outbound_height);
|
|
2315
2577
|
const finalisedHeight = Number(txData.finalised_height);
|
|
2316
2578
|
const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
|
|
@@ -2318,9 +2580,11 @@ class TransactionStage {
|
|
|
2318
2580
|
? (outboundBlock - currentTCHeight) * this.chainAttributes[THORChain].avgBlockTimeInSecs +
|
|
2319
2581
|
this.chainAttributes[asset.chain].avgBlockTimeInSecs
|
|
2320
2582
|
: 0;
|
|
2321
|
-
//
|
|
2583
|
+
// Determine transaction status
|
|
2322
2584
|
const status = txData.out_txs ? WithdrawStatus.Complete : WithdrawStatus.Incomplete;
|
|
2585
|
+
// Get withdrawal amount
|
|
2323
2586
|
const withdrawalAmount = yield this.getCryptoAmount(outAmount[0], asset);
|
|
2587
|
+
// Construct withdraw saver info object
|
|
2324
2588
|
const withdrawSaverInfo = {
|
|
2325
2589
|
status,
|
|
2326
2590
|
withdrawalAmount,
|
|
@@ -2330,22 +2594,31 @@ class TransactionStage {
|
|
|
2330
2594
|
outboundBlock,
|
|
2331
2595
|
estimatedWaitTime,
|
|
2332
2596
|
};
|
|
2597
|
+
// Assign withdraw saver info to progress object
|
|
2333
2598
|
progress.withdrawSaverInfo = withdrawSaverInfo;
|
|
2334
2599
|
}
|
|
2335
2600
|
});
|
|
2336
2601
|
}
|
|
2602
|
+
/**
|
|
2603
|
+
* Checks the progress of a refund transaction.
|
|
2604
|
+
* @param txData - Transaction details response.
|
|
2605
|
+
* @param progress - Transaction progress object.
|
|
2606
|
+
*/
|
|
2337
2607
|
checkRefund(txData, progress) {
|
|
2338
2608
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2339
2609
|
if (progress.inboundObserved) {
|
|
2610
|
+
// Get the last block object
|
|
2340
2611
|
const lastBlockObj = yield this.thorchainCache.thornode.getLastBlock();
|
|
2341
|
-
//
|
|
2612
|
+
// Calculate expected confirmation date
|
|
2342
2613
|
const outboundHeight = txData.tx.status === 'done' ? txData.finalised_height : Number(`${txData.outbound_height}`);
|
|
2343
2614
|
const expectedConfirmationDate = yield this.blockToDate(THORChain, txData, outboundHeight); // always pass in thorchain
|
|
2615
|
+
// Extract amount and asset
|
|
2344
2616
|
const amount = txData.tx.tx.coins[0].amount;
|
|
2345
2617
|
const asset = assetFromStringEx(txData.tx.tx.coins[0].asset);
|
|
2346
2618
|
const toAddress = `${txData.tx.tx.to_address}`;
|
|
2347
2619
|
const currentHeight = lastBlockObj.find((obj) => obj.chain === asset.chain);
|
|
2348
2620
|
console.log(currentHeight);
|
|
2621
|
+
// Extract relevant block heights and calculate estimated wait time
|
|
2349
2622
|
const outboundBlock = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.last_observed_in}`);
|
|
2350
2623
|
const finalisedHeight = Number(txData.finalised_height);
|
|
2351
2624
|
const currentTCHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`);
|
|
@@ -2370,33 +2643,43 @@ class TransactionStage {
|
|
|
2370
2643
|
}
|
|
2371
2644
|
});
|
|
2372
2645
|
}
|
|
2646
|
+
/**
|
|
2647
|
+
* Parses the memo of an add liquidity pool transaction.
|
|
2648
|
+
* @param memo - Memo string of the transaction.
|
|
2649
|
+
* @returns Parsed memo fields.
|
|
2650
|
+
*/
|
|
2373
2651
|
parseAddLpMemo(memo) {
|
|
2374
|
-
//ADD:POOL:PAIREDADDR:AFFILIATE:FEE
|
|
2652
|
+
// Memo format: ADD:POOL:PAIREDADDR:AFFILIATE:FEE
|
|
2375
2653
|
const parts = memo.split(`:`);
|
|
2376
2654
|
const action = parts[0];
|
|
2377
2655
|
const asset = parts[1];
|
|
2378
|
-
//
|
|
2656
|
+
// Optional fields
|
|
2379
2657
|
const pairedAddress = parts.length > 2 && parts[2].length > 0 ? parts[2] : undefined;
|
|
2380
2658
|
const affiliateAddress = parts.length > 3 && parts[3].length > 0 ? parts[3] : undefined;
|
|
2381
2659
|
const affiliateFee = parts.length > 4 && parts[4].length > 0 ? parts[4] : undefined;
|
|
2382
2660
|
return { action, asset, pairedAddress, affiliateAddress, affiliateFee };
|
|
2383
2661
|
}
|
|
2662
|
+
/**
|
|
2663
|
+
* Parses the memo of a withdraw liquidity pool transaction.
|
|
2664
|
+
* @param memo - Memo string of the transaction.
|
|
2665
|
+
* @returns Parsed memo fields.
|
|
2666
|
+
*/
|
|
2384
2667
|
parseWithdrawLpMemo(memo) {
|
|
2385
|
-
//ADD:POOL:PAIREDADDR:AFFILIATE:FEE
|
|
2668
|
+
// Memo format: ADD:POOL:PAIREDADDR:AFFILIATE:FEE
|
|
2386
2669
|
const parts = memo.split(`:`);
|
|
2387
2670
|
const action = parts[0];
|
|
2388
2671
|
const asset = parts[1];
|
|
2389
|
-
//
|
|
2672
|
+
// Optional fields
|
|
2390
2673
|
const pairedAddress = parts.length > 2 && parts[2].length > 0 ? parts[2] : undefined;
|
|
2391
2674
|
const affiliateAddress = parts.length > 3 && parts[3].length > 0 ? parts[3] : undefined;
|
|
2392
2675
|
const affiliateFee = parts.length > 4 && parts[4].length > 0 ? parts[4] : undefined;
|
|
2393
2676
|
return { action, asset, pairedAddress, affiliateAddress, affiliateFee };
|
|
2394
2677
|
}
|
|
2395
2678
|
/**
|
|
2396
|
-
*
|
|
2397
|
-
* @param chain -
|
|
2398
|
-
* @param txData -
|
|
2399
|
-
* @returns
|
|
2679
|
+
* Converts block height to date.
|
|
2680
|
+
* @param chain - Input chain.
|
|
2681
|
+
* @param txData - Transaction response data.
|
|
2682
|
+
* @returns Date object.
|
|
2400
2683
|
*/
|
|
2401
2684
|
blockToDate(chain, txData, outboundBlock) {
|
|
2402
2685
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -2421,7 +2704,7 @@ class TransactionStage {
|
|
|
2421
2704
|
return time;
|
|
2422
2705
|
}
|
|
2423
2706
|
}
|
|
2424
|
-
//
|
|
2707
|
+
// Find out how long ago it was processed for all chains
|
|
2425
2708
|
if (chain == THORChain) {
|
|
2426
2709
|
const currentHeight = lastBlockObj.find((obj) => obj);
|
|
2427
2710
|
const thorchainHeight = Number(`${currentHeight === null || currentHeight === void 0 ? void 0 : currentHeight.thorchain}`); // current height of the TC
|
|
@@ -2438,9 +2721,9 @@ class TransactionStage {
|
|
|
2438
2721
|
});
|
|
2439
2722
|
}
|
|
2440
2723
|
/**
|
|
2441
|
-
* Returns current block height of an asset's native chain
|
|
2442
|
-
* @param
|
|
2443
|
-
* @returns
|
|
2724
|
+
* Returns the current block height of an asset's native chain.
|
|
2725
|
+
* @param asset - Asset for which block height is needed.
|
|
2726
|
+
* @returns Block height.
|
|
2444
2727
|
*/
|
|
2445
2728
|
blockHeight(asset) {
|
|
2446
2729
|
return __awaiter(this, void 0, void 0, function* () {
|