ndtr-dexter
Version:
Customizable Typescript SDK for interacting with Cardano DEXs
155 lines (154 loc) • 6.36 kB
JavaScript
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);
}
}