@xchainjs/xchain-mayachain-query 2.1.1 → 2.1.3
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 +203 -41
- package/lib/index.js +202 -40
- package/lib/mayachain-cache.d.ts +12 -0
- package/lib/mayachain-query.d.ts +13 -1
- package/lib/types.d.ts +1 -0
- package/lib/utils/mayanode.d.ts +9 -2
- package/package.json +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { assetFromStringEx, assetToString, baseAmount, CryptoAmount, CachedValue
|
|
|
2
2
|
import { MidgardQuery } from '@xchainjs/xchain-mayamidgard-query';
|
|
3
3
|
import BigNumber from 'bignumber.js';
|
|
4
4
|
import { Network } from '@xchainjs/xchain-client';
|
|
5
|
-
import { QuoteApi, Configuration, MimirApi, NetworkApi, TradeUnitApi, TradeUnitsApi, TradeAccountApi, TradeAccountsApi } from '@xchainjs/xchain-mayanode';
|
|
5
|
+
import { QuoteApi, Configuration, MimirApi, NetworkApi, PoolsApi, TradeUnitApi, TradeUnitsApi, TradeAccountApi, TradeAccountsApi } from '@xchainjs/xchain-mayanode';
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
import axiosRetry from 'axios-retry';
|
|
8
8
|
|
|
@@ -60,6 +60,7 @@ class Mayanode {
|
|
|
60
60
|
this.quoteApis = this.config.mayanodeBaseUrls.map((url) => new QuoteApi(new Configuration({ basePath: url })));
|
|
61
61
|
this.mimirApis = this.config.mayanodeBaseUrls.map((url) => new MimirApi(new Configuration({ basePath: url })));
|
|
62
62
|
this.networkApis = this.config.mayanodeBaseUrls.map((url) => new NetworkApi(new Configuration({ basePath: url })));
|
|
63
|
+
this.poolsApis = this.config.mayanodeBaseUrls.map((url) => new PoolsApi(new Configuration({ basePath: url })));
|
|
63
64
|
this.tradeUnitApis = this.config.mayanodeBaseUrls.map((url) => new TradeUnitApi(new Configuration({ basePath: url })));
|
|
64
65
|
this.tradeUnitsApis = this.config.mayanodeBaseUrls.map((url) => new TradeUnitsApi(new Configuration({ basePath: url })));
|
|
65
66
|
this.tradeAccountApis = this.config.mayanodeBaseUrls.map((url) => new TradeAccountApi(new Configuration({ basePath: url })));
|
|
@@ -80,13 +81,12 @@ class Mayanode {
|
|
|
80
81
|
* @param height - block height
|
|
81
82
|
* @returns quotes swap object response
|
|
82
83
|
*/
|
|
83
|
-
getSwapQuote(fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliate, height) {
|
|
84
|
+
getSwapQuote(fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, liquidityToleranceBps, toleranceBps, affiliateBps, affiliate, height) {
|
|
84
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
85
86
|
for (const api of this.quoteApis) {
|
|
86
87
|
try {
|
|
87
|
-
return (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, undefined, //
|
|
88
|
-
streamingInterval, streamingQuantity, toleranceBps,
|
|
89
|
-
affiliateBps === null || affiliateBps === void 0 ? void 0 : affiliateBps.toString(), affiliate)).data;
|
|
88
|
+
return (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, undefined, //refund address
|
|
89
|
+
streamingInterval, streamingQuantity, toleranceBps, liquidityToleranceBps, affiliateBps === null || affiliateBps === void 0 ? void 0 : affiliateBps.toString(), affiliate)).data;
|
|
90
90
|
}
|
|
91
91
|
catch (_e) { }
|
|
92
92
|
}
|
|
@@ -211,6 +211,22 @@ class Mayanode {
|
|
|
211
211
|
throw new Error(`MAYANode not responding. Can not get trade asset accounts`);
|
|
212
212
|
});
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Get all available pools.
|
|
216
|
+
* @param height - optional MAYAChain height, default, latest block
|
|
217
|
+
* @returns pool data
|
|
218
|
+
*/
|
|
219
|
+
getPools(height) {
|
|
220
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
221
|
+
for (const api of this.poolsApis) {
|
|
222
|
+
try {
|
|
223
|
+
return (yield api.pools(height)).data;
|
|
224
|
+
}
|
|
225
|
+
catch (_e) { }
|
|
226
|
+
}
|
|
227
|
+
throw new Error(`MAYANode not responding`);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
214
230
|
}
|
|
215
231
|
|
|
216
232
|
const BtcAsset = assetFromStringEx('BTC.BTC');
|
|
@@ -245,6 +261,10 @@ const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
|
|
|
245
261
|
const getCryptoAmountWithNotation = (amount, notation) => {
|
|
246
262
|
const inputAmountBaseNotation = amount.baseAmount.amount();
|
|
247
263
|
const decimalsDiff = notation - amount.baseAmount.decimal;
|
|
264
|
+
// Ensure we don't create negative decimals
|
|
265
|
+
if (notation < 0) {
|
|
266
|
+
throw new Error(`Invalid notation: ${notation}. Decimals cannot be negative.`);
|
|
267
|
+
}
|
|
248
268
|
return new CryptoAmount(baseAmount(inputAmountBaseNotation.times(Math.pow(10, decimalsDiff)), notation), amount.asset);
|
|
249
269
|
};
|
|
250
270
|
|
|
@@ -291,14 +311,29 @@ class MayachainCache {
|
|
|
291
311
|
return __awaiter(this, void 0, void 0, function* () {
|
|
292
312
|
if (!this.assetDecimalsCache)
|
|
293
313
|
throw Error(`Could not refresh assets decimals`);
|
|
294
|
-
|
|
314
|
+
try {
|
|
315
|
+
return yield this.assetDecimalsCache.getValue();
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
// Fallback: if cache refresh fails (e.g., Mayamidgard is down), use static fallback
|
|
319
|
+
console.warn('Maya asset decimals cache refresh failed, using static fallback:', error);
|
|
320
|
+
return this.getFallbackAssetDecimals();
|
|
321
|
+
}
|
|
295
322
|
});
|
|
296
323
|
}
|
|
297
324
|
getPools() {
|
|
298
325
|
return __awaiter(this, void 0, void 0, function* () {
|
|
299
326
|
if (!this.poolsCache)
|
|
300
327
|
throw Error(`Could not refresh pools cache`);
|
|
301
|
-
|
|
328
|
+
try {
|
|
329
|
+
return yield this.poolsCache.getValue();
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
// If pools cache fails to refresh (e.g., Mayamidgard is down), throw the error
|
|
333
|
+
// The calling code should handle this gracefully with optimistic fallbacks
|
|
334
|
+
console.warn('Maya pools cache refresh failed:', error);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
302
337
|
});
|
|
303
338
|
}
|
|
304
339
|
/**
|
|
@@ -356,29 +391,117 @@ class MayachainCache {
|
|
|
356
391
|
*/
|
|
357
392
|
refreshAssetDecimalsCache() {
|
|
358
393
|
return __awaiter(this, void 0, void 0, function* () {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
394
|
+
try {
|
|
395
|
+
// Try to get pool data and extract decimals if available
|
|
396
|
+
const pools = yield this.midgardQuery.getPools();
|
|
397
|
+
const decimals = {};
|
|
398
|
+
for (const pool of pools) {
|
|
399
|
+
if (pool.nativeDecimal) {
|
|
400
|
+
const decimal = Number(pool.nativeDecimal);
|
|
401
|
+
// Only use the decimal value if it's a valid positive number
|
|
402
|
+
if (decimal >= 0) {
|
|
403
|
+
decimals[pool.asset] = decimal;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Merge with fallback data for assets that don't have native decimals specified
|
|
408
|
+
return Object.assign(Object.assign({}, this.getFallbackAssetDecimals()), decimals);
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
console.warn('Failed to refresh Maya asset decimals from pools, using fallback:', error);
|
|
412
|
+
return this.getFallbackAssetDecimals();
|
|
413
|
+
}
|
|
373
414
|
});
|
|
374
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Provides fallback decimal values for Maya assets when Mayamidgard is unavailable.
|
|
418
|
+
* Data sourced from https://mayanode.mayachain.info/mayachain/pools
|
|
419
|
+
* Updated with live pool data as of latest fetch
|
|
420
|
+
*/
|
|
421
|
+
getFallbackAssetDecimals() {
|
|
422
|
+
return {
|
|
423
|
+
// Current Maya pools with verified decimals from Mayanode
|
|
424
|
+
'BTC.BTC': 8,
|
|
425
|
+
'ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831': 6,
|
|
426
|
+
'ARB.USDT-0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9': 6,
|
|
427
|
+
'ARB.LEO-0x5985D2Dc68E67aeE82F4e30e8e74F1ea8e532a3c': 3,
|
|
428
|
+
'ARB.TGT-0X429FED88F10285E61B12BDF00848315FBDFCC341': 18,
|
|
429
|
+
'ARB.TGT-0x429FED88F10285E61B12BDF00848315FBDFCC341': 18,
|
|
430
|
+
'ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 6,
|
|
431
|
+
'ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7': 6,
|
|
432
|
+
'KUJI.KUJI': 6,
|
|
433
|
+
'KUJI.USK': 6,
|
|
434
|
+
'THOR.RUNE': 8,
|
|
435
|
+
// Chain defaults for native assets
|
|
436
|
+
'ETH.ETH': 18,
|
|
437
|
+
'ARB.ETH': 18,
|
|
438
|
+
'MAYA.CACAO': 10,
|
|
439
|
+
// Additional pool assets (using chain defaults where decimals not specified)
|
|
440
|
+
'DASH.DASH': 8,
|
|
441
|
+
'XDR.XDR': 18,
|
|
442
|
+
'ZEC.ZEC': 8,
|
|
443
|
+
// Legacy mappings for backward compatibility
|
|
444
|
+
'ETH.WSTETH-0X7F39C581F595B53C5CB19BD0B3F8DA6C935E2CA0': 18,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
375
447
|
/**
|
|
376
448
|
* Refreshes the Pools cache
|
|
377
449
|
* @returns {PoolDetail[]} the list of pools
|
|
378
450
|
*/
|
|
379
451
|
refreshPoolsCache() {
|
|
380
452
|
return __awaiter(this, void 0, void 0, function* () {
|
|
381
|
-
|
|
453
|
+
try {
|
|
454
|
+
// Try Mayanode first (like THORChain uses Thornode first)
|
|
455
|
+
const mayanodePools = yield this.mayanode.getPools();
|
|
456
|
+
return this.convertMayanodePoolsToMidgardFormat(mayanodePools);
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
console.warn('Mayanode pools unavailable, falling back to Mayamidgard:', error);
|
|
460
|
+
// Fallback to Midgard like before
|
|
461
|
+
return this.midgardQuery.getPools();
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Convert Mayanode pool format to Midgard PoolDetail format
|
|
467
|
+
* @param pools - Pools from Mayanode API
|
|
468
|
+
* @returns PoolDetail array compatible with Midgard format
|
|
469
|
+
*/
|
|
470
|
+
convertMayanodePoolsToMidgardFormat(pools) {
|
|
471
|
+
return pools.map((pool) => {
|
|
472
|
+
var _a;
|
|
473
|
+
// Get the fallback decimal for this asset if available
|
|
474
|
+
const fallbackDecimals = this.getFallbackAssetDecimals();
|
|
475
|
+
const nativeDecimal = ((_a = fallbackDecimals[pool.asset]) === null || _a === void 0 ? void 0 : _a.toString()) || '8';
|
|
476
|
+
// Calculate units from liquidityUnits and synthUnits
|
|
477
|
+
const liquidityUnits = pool.LP_units;
|
|
478
|
+
const synthUnits = '0';
|
|
479
|
+
return {
|
|
480
|
+
// Core pool data from Mayanode
|
|
481
|
+
asset: pool.asset,
|
|
482
|
+
assetDepth: pool.balance_asset,
|
|
483
|
+
runeDepth: pool.balance_cacao,
|
|
484
|
+
liquidityUnits,
|
|
485
|
+
status: 'available', // Assume available if returned by Mayanode
|
|
486
|
+
// Calculated fields
|
|
487
|
+
assetPrice: pool.balance_cacao && pool.balance_asset
|
|
488
|
+
? (parseFloat(pool.balance_cacao) / parseFloat(pool.balance_asset)).toString()
|
|
489
|
+
: '0',
|
|
490
|
+
// Required fields with appropriate defaults
|
|
491
|
+
annualPercentageRate: '0',
|
|
492
|
+
assetPriceUSD: '0',
|
|
493
|
+
nativeDecimal,
|
|
494
|
+
poolAPY: '0',
|
|
495
|
+
saversAPR: '0',
|
|
496
|
+
saversDepth: '0',
|
|
497
|
+
saversUnits: '0',
|
|
498
|
+
synthSupply: '0',
|
|
499
|
+
synthUnits,
|
|
500
|
+
totalCollateral: '0',
|
|
501
|
+
totalDebtTor: '0',
|
|
502
|
+
units: new BigNumber(liquidityUnits || '0').plus(new BigNumber(synthUnits)).toString(),
|
|
503
|
+
volume24h: '0',
|
|
504
|
+
};
|
|
382
505
|
});
|
|
383
506
|
}
|
|
384
507
|
}
|
|
@@ -419,14 +542,15 @@ class MayachainQuery {
|
|
|
419
542
|
* @returns {QuoteSwap} A quote for the swap operation.
|
|
420
543
|
*/
|
|
421
544
|
quoteSwap(_a) {
|
|
422
|
-
return __awaiter(this, arguments, void 0, function* ({ fromAsset, destinationAsset, amount, destinationAddress, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }) {
|
|
545
|
+
return __awaiter(this, arguments, void 0, function* ({ fromAsset, destinationAsset, amount, destinationAddress, liquidityToleranceBps, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }) {
|
|
423
546
|
const fromAssetString = assetToString(fromAsset);
|
|
424
547
|
const toAssetString = assetToString(destinationAsset);
|
|
425
548
|
// Endpoint allows 10 decimals for Cacao, 8 for the rest of assets
|
|
426
|
-
const inputAmount =
|
|
549
|
+
const inputAmount = eqAsset(fromAsset, CacaoAsset)
|
|
427
550
|
? amount.baseAmount.amount()
|
|
428
|
-
: getBaseAmountWithDiffDecimals(amount,
|
|
429
|
-
const swapQuote = yield this.mayachainCache.mayanode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height);
|
|
551
|
+
: getBaseAmountWithDiffDecimals(amount, this.getQuoteAssetDecimals(fromAsset));
|
|
552
|
+
const swapQuote = yield this.mayachainCache.mayanode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, liquidityToleranceBps, toleranceBps, affiliateBps, affiliateAddress, height);
|
|
553
|
+
// Check if the response indicates an error by examining memo and other required field
|
|
430
554
|
const response = JSON.parse(JSON.stringify(swapQuote));
|
|
431
555
|
if (response.error) {
|
|
432
556
|
return {
|
|
@@ -458,23 +582,22 @@ class MayachainQuery {
|
|
|
458
582
|
}
|
|
459
583
|
const feeAsset = assetFromStringEx(swapQuote.fees.asset);
|
|
460
584
|
const errors = [];
|
|
461
|
-
if (swapQuote.memo === undefined)
|
|
585
|
+
if (swapQuote.memo === undefined || swapQuote.memo === '')
|
|
462
586
|
errors.push(`Error parsing swap quote: Memo is ${swapQuote.memo}`);
|
|
463
|
-
const isFeeAssetCacao = swapQuote.fees.asset === assetToString(CacaoAsset);
|
|
464
587
|
return {
|
|
465
588
|
toAddress: swapQuote.inbound_address || '',
|
|
466
589
|
memo: swapQuote.memo || '',
|
|
467
|
-
expectedAmount: new CryptoAmount(baseAmount(swapQuote.expected_amount_out,
|
|
590
|
+
expectedAmount: new CryptoAmount(baseAmount(swapQuote.expected_amount_out, this.getQuoteAssetDecimals(destinationAsset)), destinationAsset),
|
|
468
591
|
dustThreshold: this.getChainDustValue(fromAsset.chain),
|
|
469
592
|
fees: {
|
|
470
593
|
asset: feeAsset,
|
|
471
|
-
affiliateFee: new CryptoAmount(baseAmount(swapQuote.fees.affiliate,
|
|
472
|
-
outboundFee: new CryptoAmount(baseAmount(swapQuote.fees.outbound,
|
|
473
|
-
liquidityFee: new CryptoAmount(baseAmount(swapQuote.fees.liquidity,
|
|
474
|
-
totalFee: new CryptoAmount(baseAmount(swapQuote.fees.total,
|
|
594
|
+
affiliateFee: new CryptoAmount(baseAmount(swapQuote.fees.affiliate, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
595
|
+
outboundFee: new CryptoAmount(baseAmount(swapQuote.fees.outbound, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
596
|
+
liquidityFee: new CryptoAmount(baseAmount(swapQuote.fees.liquidity, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
597
|
+
totalFee: new CryptoAmount(baseAmount(swapQuote.fees.total, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
475
598
|
},
|
|
476
599
|
expiry: swapQuote.expiry,
|
|
477
|
-
recommendedMinAmountIn: new CryptoAmount(baseAmount(swapQuote.recommended_min_amount_in || '0',
|
|
600
|
+
recommendedMinAmountIn: new CryptoAmount(baseAmount(swapQuote.recommended_min_amount_in || '0', this.getQuoteAssetDecimals(fromAsset)), fromAsset),
|
|
478
601
|
router: swapQuote.router,
|
|
479
602
|
recommendedGasRate: swapQuote.recommended_gas_rate,
|
|
480
603
|
gasRateUnits: swapQuote.gas_rate_units,
|
|
@@ -572,12 +695,41 @@ class MayachainQuery {
|
|
|
572
695
|
if (isSynthAsset(asset))
|
|
573
696
|
return DEFAULT_MAYACHAIN_DECIMALS;
|
|
574
697
|
const assetNotation = assetToString(asset);
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
698
|
+
try {
|
|
699
|
+
const assetsDecimals = yield this.mayachainCache.getAssetDecimals();
|
|
700
|
+
if (assetsDecimals[assetNotation]) {
|
|
701
|
+
return assetsDecimals[assetNotation];
|
|
702
|
+
}
|
|
703
|
+
// Fallback for unknown assets: use chain defaults
|
|
704
|
+
console.warn(`No decimal mapping found for ${assetNotation}, using chain default`);
|
|
705
|
+
return this.getChainDefaultDecimals(asset.chain);
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
// Fallback if asset decimals cache fails entirely
|
|
709
|
+
console.warn(`Failed to get asset decimals for ${assetNotation}, using chain default:`, error);
|
|
710
|
+
return this.getChainDefaultDecimals(asset.chain);
|
|
711
|
+
}
|
|
579
712
|
});
|
|
580
713
|
}
|
|
714
|
+
/**
|
|
715
|
+
* Get default decimal places for a chain when specific asset data is unavailable
|
|
716
|
+
* @param chain - The chain to get default decimals for
|
|
717
|
+
* @returns Default decimal places for the chain
|
|
718
|
+
*/
|
|
719
|
+
getChainDefaultDecimals(chain) {
|
|
720
|
+
const chainDefaults = {
|
|
721
|
+
BTC: 8,
|
|
722
|
+
ETH: 18,
|
|
723
|
+
ARB: 18,
|
|
724
|
+
KUJI: 6,
|
|
725
|
+
THOR: 8,
|
|
726
|
+
MAYA: 10,
|
|
727
|
+
DASH: 8,
|
|
728
|
+
XDR: 18,
|
|
729
|
+
ZEC: 8,
|
|
730
|
+
};
|
|
731
|
+
return chainDefaults[chain] || 8; // Ultimate fallback to 8 decimals
|
|
732
|
+
}
|
|
581
733
|
/**
|
|
582
734
|
* Get pools details
|
|
583
735
|
* @returns {PoolDetail[]} pools details
|
|
@@ -603,10 +755,12 @@ class MayachainQuery {
|
|
|
603
755
|
const poolDetails = yield this.mayachainCache.getPools();
|
|
604
756
|
const getCryptoAmount = (assetDecimals, asset, amount) => {
|
|
605
757
|
const decimals = asset in assetDecimals ? assetDecimals[asset] : DEFAULT_MAYACHAIN_DECIMALS;
|
|
758
|
+
// Ensure decimals is valid (not negative or undefined)
|
|
759
|
+
const validDecimals = typeof decimals === 'number' && decimals >= 0 ? decimals : DEFAULT_MAYACHAIN_DECIMALS;
|
|
606
760
|
const assetFormatted = assetFromStringEx(asset);
|
|
607
|
-
return
|
|
608
|
-
? new CryptoAmount(baseAmount(amount,
|
|
609
|
-
: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(amount), assetFormatted),
|
|
761
|
+
return validDecimals === DEFAULT_MAYACHAIN_DECIMALS || eqAsset(CacaoAsset, assetFormatted)
|
|
762
|
+
? new CryptoAmount(baseAmount(amount, validDecimals), assetFormatted)
|
|
763
|
+
: getCryptoAmountWithNotation(new CryptoAmount(baseAmount(amount), assetFormatted), validDecimals);
|
|
610
764
|
};
|
|
611
765
|
return {
|
|
612
766
|
count: actionsResume.count ? Number(actionsResume.count) : 0,
|
|
@@ -810,6 +964,14 @@ class MayachainQuery {
|
|
|
810
964
|
});
|
|
811
965
|
});
|
|
812
966
|
}
|
|
967
|
+
/**
|
|
968
|
+
* Get the hardcoded decimal precision for quote calculations
|
|
969
|
+
* @param asset The asset to get decimals for
|
|
970
|
+
* @returns 10 for Cacao, 8 for other assets (used in quote calculations)
|
|
971
|
+
*/
|
|
972
|
+
getQuoteAssetDecimals(asset) {
|
|
973
|
+
return eqAsset(asset, CacaoAsset) ? 10 : 8;
|
|
974
|
+
}
|
|
813
975
|
}
|
|
814
976
|
|
|
815
977
|
export { ArbAsset, ArbChain, BtcAsset, BtcChain, CacaoAsset, DEFAULT_MAYACHAIN_DECIMALS, DashAsset, DashChain, EthAsset, EthChain, KujiraAsset, KujiraChain, MayaChain, MayachainCache, MayachainQuery, Mayanode, RuneAsset, ThorChain, XdrAsset, XdrChain, ZecAsset, ZecChain, getBaseAmountWithDiffDecimals, getCryptoAmountWithNotation, isCacaoAsset };
|
package/lib/index.js
CHANGED
|
@@ -68,6 +68,7 @@ class Mayanode {
|
|
|
68
68
|
this.quoteApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.QuoteApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
69
69
|
this.mimirApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.MimirApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
70
70
|
this.networkApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.NetworkApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
71
|
+
this.poolsApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.PoolsApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
71
72
|
this.tradeUnitApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.TradeUnitApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
72
73
|
this.tradeUnitsApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.TradeUnitsApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
73
74
|
this.tradeAccountApis = this.config.mayanodeBaseUrls.map((url) => new xchainMayanode.TradeAccountApi(new xchainMayanode.Configuration({ basePath: url })));
|
|
@@ -88,13 +89,12 @@ class Mayanode {
|
|
|
88
89
|
* @param height - block height
|
|
89
90
|
* @returns quotes swap object response
|
|
90
91
|
*/
|
|
91
|
-
getSwapQuote(fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliate, height) {
|
|
92
|
+
getSwapQuote(fromAsset, toAsset, amount, destinationAddress, streamingInterval, streamingQuantity, liquidityToleranceBps, toleranceBps, affiliateBps, affiliate, height) {
|
|
92
93
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
94
|
for (const api of this.quoteApis) {
|
|
94
95
|
try {
|
|
95
|
-
return (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, undefined, //
|
|
96
|
-
streamingInterval, streamingQuantity, toleranceBps,
|
|
97
|
-
affiliateBps === null || affiliateBps === void 0 ? void 0 : affiliateBps.toString(), affiliate)).data;
|
|
96
|
+
return (yield api.quoteswap(height, fromAsset, toAsset, amount, destinationAddress, undefined, //refund address
|
|
97
|
+
streamingInterval, streamingQuantity, toleranceBps, liquidityToleranceBps, affiliateBps === null || affiliateBps === void 0 ? void 0 : affiliateBps.toString(), affiliate)).data;
|
|
98
98
|
}
|
|
99
99
|
catch (_e) { }
|
|
100
100
|
}
|
|
@@ -219,6 +219,22 @@ class Mayanode {
|
|
|
219
219
|
throw new Error(`MAYANode not responding. Can not get trade asset accounts`);
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Get all available pools.
|
|
224
|
+
* @param height - optional MAYAChain height, default, latest block
|
|
225
|
+
* @returns pool data
|
|
226
|
+
*/
|
|
227
|
+
getPools(height) {
|
|
228
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
229
|
+
for (const api of this.poolsApis) {
|
|
230
|
+
try {
|
|
231
|
+
return (yield api.pools(height)).data;
|
|
232
|
+
}
|
|
233
|
+
catch (_e) { }
|
|
234
|
+
}
|
|
235
|
+
throw new Error(`MAYANode not responding`);
|
|
236
|
+
});
|
|
237
|
+
}
|
|
222
238
|
}
|
|
223
239
|
|
|
224
240
|
const BtcAsset = xchainUtil.assetFromStringEx('BTC.BTC');
|
|
@@ -253,6 +269,10 @@ const getBaseAmountWithDiffDecimals = (inputAmount, outDecimals) => {
|
|
|
253
269
|
const getCryptoAmountWithNotation = (amount, notation) => {
|
|
254
270
|
const inputAmountBaseNotation = amount.baseAmount.amount();
|
|
255
271
|
const decimalsDiff = notation - amount.baseAmount.decimal;
|
|
272
|
+
// Ensure we don't create negative decimals
|
|
273
|
+
if (notation < 0) {
|
|
274
|
+
throw new Error(`Invalid notation: ${notation}. Decimals cannot be negative.`);
|
|
275
|
+
}
|
|
256
276
|
return new xchainUtil.CryptoAmount(xchainUtil.baseAmount(inputAmountBaseNotation.times(Math.pow(10, decimalsDiff)), notation), amount.asset);
|
|
257
277
|
};
|
|
258
278
|
|
|
@@ -299,14 +319,29 @@ class MayachainCache {
|
|
|
299
319
|
return __awaiter(this, void 0, void 0, function* () {
|
|
300
320
|
if (!this.assetDecimalsCache)
|
|
301
321
|
throw Error(`Could not refresh assets decimals`);
|
|
302
|
-
|
|
322
|
+
try {
|
|
323
|
+
return yield this.assetDecimalsCache.getValue();
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
// Fallback: if cache refresh fails (e.g., Mayamidgard is down), use static fallback
|
|
327
|
+
console.warn('Maya asset decimals cache refresh failed, using static fallback:', error);
|
|
328
|
+
return this.getFallbackAssetDecimals();
|
|
329
|
+
}
|
|
303
330
|
});
|
|
304
331
|
}
|
|
305
332
|
getPools() {
|
|
306
333
|
return __awaiter(this, void 0, void 0, function* () {
|
|
307
334
|
if (!this.poolsCache)
|
|
308
335
|
throw Error(`Could not refresh pools cache`);
|
|
309
|
-
|
|
336
|
+
try {
|
|
337
|
+
return yield this.poolsCache.getValue();
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
// If pools cache fails to refresh (e.g., Mayamidgard is down), throw the error
|
|
341
|
+
// The calling code should handle this gracefully with optimistic fallbacks
|
|
342
|
+
console.warn('Maya pools cache refresh failed:', error);
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
310
345
|
});
|
|
311
346
|
}
|
|
312
347
|
/**
|
|
@@ -364,29 +399,117 @@ class MayachainCache {
|
|
|
364
399
|
*/
|
|
365
400
|
refreshAssetDecimalsCache() {
|
|
366
401
|
return __awaiter(this, void 0, void 0, function* () {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
402
|
+
try {
|
|
403
|
+
// Try to get pool data and extract decimals if available
|
|
404
|
+
const pools = yield this.midgardQuery.getPools();
|
|
405
|
+
const decimals = {};
|
|
406
|
+
for (const pool of pools) {
|
|
407
|
+
if (pool.nativeDecimal) {
|
|
408
|
+
const decimal = Number(pool.nativeDecimal);
|
|
409
|
+
// Only use the decimal value if it's a valid positive number
|
|
410
|
+
if (decimal >= 0) {
|
|
411
|
+
decimals[pool.asset] = decimal;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Merge with fallback data for assets that don't have native decimals specified
|
|
416
|
+
return Object.assign(Object.assign({}, this.getFallbackAssetDecimals()), decimals);
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
console.warn('Failed to refresh Maya asset decimals from pools, using fallback:', error);
|
|
420
|
+
return this.getFallbackAssetDecimals();
|
|
421
|
+
}
|
|
381
422
|
});
|
|
382
423
|
}
|
|
424
|
+
/**
|
|
425
|
+
* Provides fallback decimal values for Maya assets when Mayamidgard is unavailable.
|
|
426
|
+
* Data sourced from https://mayanode.mayachain.info/mayachain/pools
|
|
427
|
+
* Updated with live pool data as of latest fetch
|
|
428
|
+
*/
|
|
429
|
+
getFallbackAssetDecimals() {
|
|
430
|
+
return {
|
|
431
|
+
// Current Maya pools with verified decimals from Mayanode
|
|
432
|
+
'BTC.BTC': 8,
|
|
433
|
+
'ARB.USDC-0xaf88d065e77c8cC2239327C5EDb3A432268e5831': 6,
|
|
434
|
+
'ARB.USDT-0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9': 6,
|
|
435
|
+
'ARB.LEO-0x5985D2Dc68E67aeE82F4e30e8e74F1ea8e532a3c': 3,
|
|
436
|
+
'ARB.TGT-0X429FED88F10285E61B12BDF00848315FBDFCC341': 18,
|
|
437
|
+
'ARB.TGT-0x429FED88F10285E61B12BDF00848315FBDFCC341': 18,
|
|
438
|
+
'ETH.USDC-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 6,
|
|
439
|
+
'ETH.USDT-0xdAC17F958D2ee523a2206206994597C13D831ec7': 6,
|
|
440
|
+
'KUJI.KUJI': 6,
|
|
441
|
+
'KUJI.USK': 6,
|
|
442
|
+
'THOR.RUNE': 8,
|
|
443
|
+
// Chain defaults for native assets
|
|
444
|
+
'ETH.ETH': 18,
|
|
445
|
+
'ARB.ETH': 18,
|
|
446
|
+
'MAYA.CACAO': 10,
|
|
447
|
+
// Additional pool assets (using chain defaults where decimals not specified)
|
|
448
|
+
'DASH.DASH': 8,
|
|
449
|
+
'XDR.XDR': 18,
|
|
450
|
+
'ZEC.ZEC': 8,
|
|
451
|
+
// Legacy mappings for backward compatibility
|
|
452
|
+
'ETH.WSTETH-0X7F39C581F595B53C5CB19BD0B3F8DA6C935E2CA0': 18,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
383
455
|
/**
|
|
384
456
|
* Refreshes the Pools cache
|
|
385
457
|
* @returns {PoolDetail[]} the list of pools
|
|
386
458
|
*/
|
|
387
459
|
refreshPoolsCache() {
|
|
388
460
|
return __awaiter(this, void 0, void 0, function* () {
|
|
389
|
-
|
|
461
|
+
try {
|
|
462
|
+
// Try Mayanode first (like THORChain uses Thornode first)
|
|
463
|
+
const mayanodePools = yield this.mayanode.getPools();
|
|
464
|
+
return this.convertMayanodePoolsToMidgardFormat(mayanodePools);
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
console.warn('Mayanode pools unavailable, falling back to Mayamidgard:', error);
|
|
468
|
+
// Fallback to Midgard like before
|
|
469
|
+
return this.midgardQuery.getPools();
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Convert Mayanode pool format to Midgard PoolDetail format
|
|
475
|
+
* @param pools - Pools from Mayanode API
|
|
476
|
+
* @returns PoolDetail array compatible with Midgard format
|
|
477
|
+
*/
|
|
478
|
+
convertMayanodePoolsToMidgardFormat(pools) {
|
|
479
|
+
return pools.map((pool) => {
|
|
480
|
+
var _a;
|
|
481
|
+
// Get the fallback decimal for this asset if available
|
|
482
|
+
const fallbackDecimals = this.getFallbackAssetDecimals();
|
|
483
|
+
const nativeDecimal = ((_a = fallbackDecimals[pool.asset]) === null || _a === void 0 ? void 0 : _a.toString()) || '8';
|
|
484
|
+
// Calculate units from liquidityUnits and synthUnits
|
|
485
|
+
const liquidityUnits = pool.LP_units;
|
|
486
|
+
const synthUnits = '0';
|
|
487
|
+
return {
|
|
488
|
+
// Core pool data from Mayanode
|
|
489
|
+
asset: pool.asset,
|
|
490
|
+
assetDepth: pool.balance_asset,
|
|
491
|
+
runeDepth: pool.balance_cacao,
|
|
492
|
+
liquidityUnits,
|
|
493
|
+
status: 'available', // Assume available if returned by Mayanode
|
|
494
|
+
// Calculated fields
|
|
495
|
+
assetPrice: pool.balance_cacao && pool.balance_asset
|
|
496
|
+
? (parseFloat(pool.balance_cacao) / parseFloat(pool.balance_asset)).toString()
|
|
497
|
+
: '0',
|
|
498
|
+
// Required fields with appropriate defaults
|
|
499
|
+
annualPercentageRate: '0',
|
|
500
|
+
assetPriceUSD: '0',
|
|
501
|
+
nativeDecimal,
|
|
502
|
+
poolAPY: '0',
|
|
503
|
+
saversAPR: '0',
|
|
504
|
+
saversDepth: '0',
|
|
505
|
+
saversUnits: '0',
|
|
506
|
+
synthSupply: '0',
|
|
507
|
+
synthUnits,
|
|
508
|
+
totalCollateral: '0',
|
|
509
|
+
totalDebtTor: '0',
|
|
510
|
+
units: new BigNumber__default.default(liquidityUnits || '0').plus(new BigNumber__default.default(synthUnits)).toString(),
|
|
511
|
+
volume24h: '0',
|
|
512
|
+
};
|
|
390
513
|
});
|
|
391
514
|
}
|
|
392
515
|
}
|
|
@@ -427,14 +550,15 @@ class MayachainQuery {
|
|
|
427
550
|
* @returns {QuoteSwap} A quote for the swap operation.
|
|
428
551
|
*/
|
|
429
552
|
quoteSwap(_a) {
|
|
430
|
-
return __awaiter(this, arguments, void 0, function* ({ fromAsset, destinationAsset, amount, destinationAddress, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }) {
|
|
553
|
+
return __awaiter(this, arguments, void 0, function* ({ fromAsset, destinationAsset, amount, destinationAddress, liquidityToleranceBps, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }) {
|
|
431
554
|
const fromAssetString = xchainUtil.assetToString(fromAsset);
|
|
432
555
|
const toAssetString = xchainUtil.assetToString(destinationAsset);
|
|
433
556
|
// Endpoint allows 10 decimals for Cacao, 8 for the rest of assets
|
|
434
|
-
const inputAmount =
|
|
557
|
+
const inputAmount = xchainUtil.eqAsset(fromAsset, CacaoAsset)
|
|
435
558
|
? amount.baseAmount.amount()
|
|
436
|
-
: getBaseAmountWithDiffDecimals(amount,
|
|
437
|
-
const swapQuote = yield this.mayachainCache.mayanode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, toleranceBps, affiliateBps, affiliateAddress, height);
|
|
559
|
+
: getBaseAmountWithDiffDecimals(amount, this.getQuoteAssetDecimals(fromAsset));
|
|
560
|
+
const swapQuote = yield this.mayachainCache.mayanode.getSwapQuote(fromAssetString, toAssetString, inputAmount.toNumber(), destinationAddress, streamingInterval, streamingQuantity, liquidityToleranceBps, toleranceBps, affiliateBps, affiliateAddress, height);
|
|
561
|
+
// Check if the response indicates an error by examining memo and other required field
|
|
438
562
|
const response = JSON.parse(JSON.stringify(swapQuote));
|
|
439
563
|
if (response.error) {
|
|
440
564
|
return {
|
|
@@ -466,23 +590,22 @@ class MayachainQuery {
|
|
|
466
590
|
}
|
|
467
591
|
const feeAsset = xchainUtil.assetFromStringEx(swapQuote.fees.asset);
|
|
468
592
|
const errors = [];
|
|
469
|
-
if (swapQuote.memo === undefined)
|
|
593
|
+
if (swapQuote.memo === undefined || swapQuote.memo === '')
|
|
470
594
|
errors.push(`Error parsing swap quote: Memo is ${swapQuote.memo}`);
|
|
471
|
-
const isFeeAssetCacao = swapQuote.fees.asset === xchainUtil.assetToString(CacaoAsset);
|
|
472
595
|
return {
|
|
473
596
|
toAddress: swapQuote.inbound_address || '',
|
|
474
597
|
memo: swapQuote.memo || '',
|
|
475
|
-
expectedAmount: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.expected_amount_out,
|
|
598
|
+
expectedAmount: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.expected_amount_out, this.getQuoteAssetDecimals(destinationAsset)), destinationAsset),
|
|
476
599
|
dustThreshold: this.getChainDustValue(fromAsset.chain),
|
|
477
600
|
fees: {
|
|
478
601
|
asset: feeAsset,
|
|
479
|
-
affiliateFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.affiliate,
|
|
480
|
-
outboundFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.outbound,
|
|
481
|
-
liquidityFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.liquidity,
|
|
482
|
-
totalFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.total,
|
|
602
|
+
affiliateFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.affiliate, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
603
|
+
outboundFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.outbound, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
604
|
+
liquidityFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.liquidity, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
605
|
+
totalFee: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.fees.total, this.getQuoteAssetDecimals(feeAsset)), feeAsset),
|
|
483
606
|
},
|
|
484
607
|
expiry: swapQuote.expiry,
|
|
485
|
-
recommendedMinAmountIn: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.recommended_min_amount_in || '0',
|
|
608
|
+
recommendedMinAmountIn: new xchainUtil.CryptoAmount(xchainUtil.baseAmount(swapQuote.recommended_min_amount_in || '0', this.getQuoteAssetDecimals(fromAsset)), fromAsset),
|
|
486
609
|
router: swapQuote.router,
|
|
487
610
|
recommendedGasRate: swapQuote.recommended_gas_rate,
|
|
488
611
|
gasRateUnits: swapQuote.gas_rate_units,
|
|
@@ -580,12 +703,41 @@ class MayachainQuery {
|
|
|
580
703
|
if (xchainUtil.isSynthAsset(asset))
|
|
581
704
|
return DEFAULT_MAYACHAIN_DECIMALS;
|
|
582
705
|
const assetNotation = xchainUtil.assetToString(asset);
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
706
|
+
try {
|
|
707
|
+
const assetsDecimals = yield this.mayachainCache.getAssetDecimals();
|
|
708
|
+
if (assetsDecimals[assetNotation]) {
|
|
709
|
+
return assetsDecimals[assetNotation];
|
|
710
|
+
}
|
|
711
|
+
// Fallback for unknown assets: use chain defaults
|
|
712
|
+
console.warn(`No decimal mapping found for ${assetNotation}, using chain default`);
|
|
713
|
+
return this.getChainDefaultDecimals(asset.chain);
|
|
714
|
+
}
|
|
715
|
+
catch (error) {
|
|
716
|
+
// Fallback if asset decimals cache fails entirely
|
|
717
|
+
console.warn(`Failed to get asset decimals for ${assetNotation}, using chain default:`, error);
|
|
718
|
+
return this.getChainDefaultDecimals(asset.chain);
|
|
719
|
+
}
|
|
587
720
|
});
|
|
588
721
|
}
|
|
722
|
+
/**
|
|
723
|
+
* Get default decimal places for a chain when specific asset data is unavailable
|
|
724
|
+
* @param chain - The chain to get default decimals for
|
|
725
|
+
* @returns Default decimal places for the chain
|
|
726
|
+
*/
|
|
727
|
+
getChainDefaultDecimals(chain) {
|
|
728
|
+
const chainDefaults = {
|
|
729
|
+
BTC: 8,
|
|
730
|
+
ETH: 18,
|
|
731
|
+
ARB: 18,
|
|
732
|
+
KUJI: 6,
|
|
733
|
+
THOR: 8,
|
|
734
|
+
MAYA: 10,
|
|
735
|
+
DASH: 8,
|
|
736
|
+
XDR: 18,
|
|
737
|
+
ZEC: 8,
|
|
738
|
+
};
|
|
739
|
+
return chainDefaults[chain] || 8; // Ultimate fallback to 8 decimals
|
|
740
|
+
}
|
|
589
741
|
/**
|
|
590
742
|
* Get pools details
|
|
591
743
|
* @returns {PoolDetail[]} pools details
|
|
@@ -611,10 +763,12 @@ class MayachainQuery {
|
|
|
611
763
|
const poolDetails = yield this.mayachainCache.getPools();
|
|
612
764
|
const getCryptoAmount = (assetDecimals, asset, amount) => {
|
|
613
765
|
const decimals = asset in assetDecimals ? assetDecimals[asset] : DEFAULT_MAYACHAIN_DECIMALS;
|
|
766
|
+
// Ensure decimals is valid (not negative or undefined)
|
|
767
|
+
const validDecimals = typeof decimals === 'number' && decimals >= 0 ? decimals : DEFAULT_MAYACHAIN_DECIMALS;
|
|
614
768
|
const assetFormatted = xchainUtil.assetFromStringEx(asset);
|
|
615
|
-
return
|
|
616
|
-
? new xchainUtil.CryptoAmount(xchainUtil.baseAmount(amount,
|
|
617
|
-
: getCryptoAmountWithNotation(new xchainUtil.CryptoAmount(xchainUtil.baseAmount(amount), assetFormatted),
|
|
769
|
+
return validDecimals === DEFAULT_MAYACHAIN_DECIMALS || xchainUtil.eqAsset(CacaoAsset, assetFormatted)
|
|
770
|
+
? new xchainUtil.CryptoAmount(xchainUtil.baseAmount(amount, validDecimals), assetFormatted)
|
|
771
|
+
: getCryptoAmountWithNotation(new xchainUtil.CryptoAmount(xchainUtil.baseAmount(amount), assetFormatted), validDecimals);
|
|
618
772
|
};
|
|
619
773
|
return {
|
|
620
774
|
count: actionsResume.count ? Number(actionsResume.count) : 0,
|
|
@@ -818,6 +972,14 @@ class MayachainQuery {
|
|
|
818
972
|
});
|
|
819
973
|
});
|
|
820
974
|
}
|
|
975
|
+
/**
|
|
976
|
+
* Get the hardcoded decimal precision for quote calculations
|
|
977
|
+
* @param asset The asset to get decimals for
|
|
978
|
+
* @returns 10 for Cacao, 8 for other assets (used in quote calculations)
|
|
979
|
+
*/
|
|
980
|
+
getQuoteAssetDecimals(asset) {
|
|
981
|
+
return xchainUtil.eqAsset(asset, CacaoAsset) ? 10 : 8;
|
|
982
|
+
}
|
|
821
983
|
}
|
|
822
984
|
|
|
823
985
|
exports.ArbAsset = ArbAsset;
|
package/lib/mayachain-cache.d.ts
CHANGED
|
@@ -46,9 +46,21 @@ export declare class MayachainCache {
|
|
|
46
46
|
* Refreshes the number of decimals of the supported Mayachain tokens.
|
|
47
47
|
*/
|
|
48
48
|
private refreshAssetDecimalsCache;
|
|
49
|
+
/**
|
|
50
|
+
* Provides fallback decimal values for Maya assets when Mayamidgard is unavailable.
|
|
51
|
+
* Data sourced from https://mayanode.mayachain.info/mayachain/pools
|
|
52
|
+
* Updated with live pool data as of latest fetch
|
|
53
|
+
*/
|
|
54
|
+
private getFallbackAssetDecimals;
|
|
49
55
|
/**
|
|
50
56
|
* Refreshes the Pools cache
|
|
51
57
|
* @returns {PoolDetail[]} the list of pools
|
|
52
58
|
*/
|
|
53
59
|
private refreshPoolsCache;
|
|
60
|
+
/**
|
|
61
|
+
* Convert Mayanode pool format to Midgard PoolDetail format
|
|
62
|
+
* @param pools - Pools from Mayanode API
|
|
63
|
+
* @returns PoolDetail array compatible with Midgard format
|
|
64
|
+
*/
|
|
65
|
+
private convertMayanodePoolsToMidgardFormat;
|
|
54
66
|
}
|
package/lib/mayachain-query.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare class MayachainQuery {
|
|
|
32
32
|
* @param {QuoteSwapParams} quoteSwapParams - Parameters for the quote swap operation.
|
|
33
33
|
* @returns {QuoteSwap} A quote for the swap operation.
|
|
34
34
|
*/
|
|
35
|
-
quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }: QuoteSwapParams): Promise<QuoteSwap>;
|
|
35
|
+
quoteSwap({ fromAsset, destinationAsset, amount, destinationAddress, liquidityToleranceBps, toleranceBps, affiliateBps, affiliateAddress, height, streamingInterval, streamingQuantity, }: QuoteSwapParams): Promise<QuoteSwap>;
|
|
36
36
|
/**
|
|
37
37
|
* Return mayachain supported chains dust amounts
|
|
38
38
|
* @returns a map where chain is the key and dust amount cryptoAmount as value
|
|
@@ -67,6 +67,12 @@ export declare class MayachainQuery {
|
|
|
67
67
|
* @throws {Error} if the asset is not supported in Mayachain
|
|
68
68
|
*/
|
|
69
69
|
getAssetDecimals(asset: CompatibleAsset): Promise<number>;
|
|
70
|
+
/**
|
|
71
|
+
* Get default decimal places for a chain when specific asset data is unavailable
|
|
72
|
+
* @param chain - The chain to get default decimals for
|
|
73
|
+
* @returns Default decimal places for the chain
|
|
74
|
+
*/
|
|
75
|
+
private getChainDefaultDecimals;
|
|
70
76
|
/**
|
|
71
77
|
* Get pools details
|
|
72
78
|
* @returns {PoolDetail[]} pools details
|
|
@@ -116,4 +122,10 @@ export declare class MayachainQuery {
|
|
|
116
122
|
* @returns {TradeAssetAccounts} All trade accounts for the asset
|
|
117
123
|
*/
|
|
118
124
|
getTradeAssetAccounts({ asset, height }: TradeAssetAccountsParams): Promise<TradeAssetAccounts>;
|
|
125
|
+
/**
|
|
126
|
+
* Get the hardcoded decimal precision for quote calculations
|
|
127
|
+
* @param asset The asset to get decimals for
|
|
128
|
+
* @returns 10 for Cacao, 8 for other assets (used in quote calculations)
|
|
129
|
+
*/
|
|
130
|
+
private getQuoteAssetDecimals;
|
|
119
131
|
}
|
package/lib/types.d.ts
CHANGED
package/lib/utils/mayanode.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Network } from '@xchainjs/xchain-client';
|
|
2
|
-
import { InboundAddress, LastBlock, MimirResponse, QuoteSwapResponse, TradeAccountsResponse, TradeUnitResponse, TradeUnitsResponse } from '@xchainjs/xchain-mayanode';
|
|
2
|
+
import { InboundAddress, LastBlock, MimirResponse, PoolsResponse, QuoteSwapResponse, TradeAccountsResponse, TradeUnitResponse, TradeUnitsResponse } from '@xchainjs/xchain-mayanode';
|
|
3
3
|
import { Address } from '@xchainjs/xchain-util';
|
|
4
4
|
export type MayanodeConfig = {
|
|
5
5
|
apiRetries: number;
|
|
@@ -11,6 +11,7 @@ export declare class Mayanode {
|
|
|
11
11
|
private quoteApis;
|
|
12
12
|
private mimirApis;
|
|
13
13
|
private networkApis;
|
|
14
|
+
private poolsApis;
|
|
14
15
|
private tradeUnitApis;
|
|
15
16
|
private tradeUnitsApis;
|
|
16
17
|
private tradeAccountApis;
|
|
@@ -30,7 +31,7 @@ export declare class Mayanode {
|
|
|
30
31
|
* @param height - block height
|
|
31
32
|
* @returns quotes swap object response
|
|
32
33
|
*/
|
|
33
|
-
getSwapQuote(fromAsset: string, toAsset: string, amount: number, destinationAddress?: string, streamingInterval?: number, streamingQuantity?: number, toleranceBps?: number, affiliateBps?: number, affiliate?: string, height?: number): Promise<QuoteSwapResponse>;
|
|
34
|
+
getSwapQuote(fromAsset: string, toAsset: string, amount: number, destinationAddress?: string, streamingInterval?: number, streamingQuantity?: number, liquidityToleranceBps?: number, toleranceBps?: number, affiliateBps?: number, affiliate?: string, height?: number): Promise<QuoteSwapResponse>;
|
|
34
35
|
/**
|
|
35
36
|
* Get current active mimir configuration.
|
|
36
37
|
* @returns mimir configuration
|
|
@@ -74,4 +75,10 @@ export declare class Mayanode {
|
|
|
74
75
|
* @returns Returns all trade accounts for an asset
|
|
75
76
|
*/
|
|
76
77
|
getTradeAssetAccounts(asset: string, height?: number): Promise<TradeAccountsResponse>;
|
|
78
|
+
/**
|
|
79
|
+
* Get all available pools.
|
|
80
|
+
* @param height - optional MAYAChain height, default, latest block
|
|
81
|
+
* @returns pool data
|
|
82
|
+
*/
|
|
83
|
+
getPools(height?: number): Promise<PoolsResponse>;
|
|
77
84
|
}
|
package/package.json
CHANGED