UNPKG

ndtr-dexter

Version:

Customizable Typescript SDK for interacting with Cardano DEXs

155 lines (154 loc) 6.36 kB
import { BaseApi } from './base-api'; import { Asset } from '../models/asset'; import { LiquidityPool } from '../models/liquidity-pool'; import axios from 'axios'; import AES from 'crypto-js/aes'; import Utf8 from 'crypto-js/enc-utf8'; const AES_KEY = '22eaca439bfd89cf125827a7a33fe3970d735dbfd5d84f19dd95820781fc47be'; export class MinswapApi extends BaseApi { constructor(dex, requestConfig) { super(); this.dex = dex; this.api = axios.create({ timeout: requestConfig.timeout, baseURL: `${requestConfig.proxyUrl}https://monorepo-mainnet-prod.minswap.org/graphql` }); } liquidityPools(assetA, assetB) { // Small optimization for providing both tokens if (assetA && assetB) { return this.poolsByPair(assetA, assetB) .then((pool) => [pool]); } const maxPerPage = 20; const getPaginatedResponse = (page) => { return this.api.post('', { operationName: 'PoolsByAsset', query: ` query PoolsByAsset($asset: InputAsset!, $limit: Int, $offset: Int) { poolsByAsset( asset: $asset limit: $limit offset: $offset ) { assetA { currencySymbol tokenName ...allMetadata } assetB { currencySymbol tokenName ...allMetadata } reserveA reserveB lpAsset { currencySymbol tokenName } totalLiquidity } } fragment allMetadata on Asset { metadata { name decimals } } `, variables: { asset: { currencySymbol: assetA === 'lovelace' ? '' : assetA.policyId, tokenName: assetA === 'lovelace' ? '' : assetA.nameHex, }, limit: maxPerPage, offset: page * maxPerPage, }, }).then((response) => { response = JSON.parse(this.decryptResponse(response.data.data.encryptedData)); const pools = response.poolsByAsset; const liquidityPools = pools.map((pool) => this.liquidityPoolFromResponse(pool)); if (pools.length < maxPerPage) { return liquidityPools; } return getPaginatedResponse(page + 1).then((nextPagePools) => { return liquidityPools.concat(nextPagePools); }); }); }; return getPaginatedResponse(0); } poolsByPair(assetA, assetB) { return this.api.post('', { operationName: 'PoolByPair', query: ` query PoolByPair($pair: InputPoolByPair!) { poolByPair(pair: $pair) { assetA { currencySymbol tokenName isVerified ...allMetadata } assetB { currencySymbol tokenName isVerified ...allMetadata } reserveA reserveB lpAsset { currencySymbol tokenName } totalLiquidity profitSharing { feeTo } } } fragment allMetadata on Asset { metadata { name ticker url decimals description } } `, variables: { pair: { assetA: { currencySymbol: assetA === 'lovelace' ? '' : assetA.policyId, tokenName: assetA === 'lovelace' ? '' : assetA.nameHex, }, assetB: { currencySymbol: assetB === 'lovelace' ? '' : assetB.policyId, tokenName: assetB === 'lovelace' ? '' : assetB.nameHex, }, }, }, }).then((response) => { response = JSON.parse(this.decryptResponse(response.data.data.encryptedData)); return this.liquidityPoolFromResponse(response.poolByPair); }); } liquidityPoolFromResponse(poolData) { const liquidityPool = new LiquidityPool(this.dex.name, poolData.assetA.currencySymbol !== '' ? new Asset(poolData.assetA.currencySymbol, poolData.assetA.tokenName, poolData.assetA.metadata?.decimals ?? 0) : 'lovelace', poolData.assetB.currencySymbol !== '' ? new Asset(poolData.assetB.currencySymbol, poolData.assetB.tokenName, poolData.assetB.metadata?.decimals ?? 0) : 'lovelace', BigInt(poolData.reserveA), BigInt(poolData.reserveB), '', // Not provided this.dex.marketOrderAddress, this.dex.limitOrderAddress); liquidityPool.lpToken = new Asset(poolData.lpAsset.currencySymbol, poolData.lpAsset.tokenName); liquidityPool.totalLpTokens = BigInt(poolData.totalLiquidity); liquidityPool.poolFeePercent = 0.3; return liquidityPool; } decryptResponse(encryptedResponse) { return AES.decrypt(encryptedResponse, AES_KEY).toString(Utf8); } }