@orca-so/whirlpools-sdk
Advanced tools
Comparing version 0.9.0-alpha.6 to 0.9.0-alpha.7
@@ -8,3 +8,2 @@ "use strict"; | ||
const common_sdk_1 = require("@orca-so/common-sdk"); | ||
const anchor_1 = require("@project-serum/anchor"); | ||
const decimal_js_1 = __importDefault(require("decimal.js")); | ||
@@ -14,3 +13,2 @@ const _1 = require("."); | ||
const public_1 = require("../utils/public"); | ||
const pda_utils_1 = require("../utils/public/pda-utils"); | ||
function checkLiquidity(pool, tickArrays, aToB, thresholdConfig, decimalsMap) { | ||
@@ -54,21 +52,23 @@ const { amountOut, priceImpactThreshold } = thresholdConfig; | ||
} | ||
function getMostLiquidPool(mintA, mintB, poolMap, config = _1.defaultGetPricesConfig) { | ||
const { tickSpacings, programId, whirlpoolsConfig } = config; | ||
const pools = tickSpacings | ||
.map((tickSpacing) => { | ||
const pda = pda_utils_1.PDAUtil.getWhirlpool(programId, whirlpoolsConfig, common_sdk_1.AddressUtil.toPubKey(mintA), common_sdk_1.AddressUtil.toPubKey(mintB), tickSpacing); | ||
return { address: pda.publicKey, pool: poolMap[pda.publicKey.toBase58()] }; | ||
}) | ||
.filter(({ pool }) => pool != null); | ||
if (pools.length === 0) { | ||
return null; | ||
} | ||
return pools.slice(1).reduce((acc, { address, pool }) => { | ||
if (pool.liquidity.lt(acc.pool.liquidity)) { | ||
return acc; | ||
function getMostLiquidPools(quoteTokenMint, poolMap) { | ||
const mostLiquidPools = new Map(); | ||
Object.entries(poolMap).forEach(([address, pool]) => { | ||
const mintA = pool.tokenMintA.toBase58(); | ||
const mintB = pool.tokenMintB.toBase58(); | ||
if (pool.liquidity.isZero()) { | ||
return; | ||
} | ||
return { pool, address }; | ||
}, pools[0]); | ||
if (!pool.tokenMintA.equals(quoteTokenMint) && !pool.tokenMintB.equals(quoteTokenMint)) { | ||
return; | ||
} | ||
const baseTokenMint = pool.tokenMintA.equals(quoteTokenMint) ? mintB : mintA; | ||
const existingPool = mostLiquidPools.get(baseTokenMint); | ||
if (!existingPool || pool.liquidity.gt(existingPool.pool.liquidity)) { | ||
mostLiquidPools.set(baseTokenMint, { address: common_sdk_1.AddressUtil.toPubKey(address), pool }); | ||
} | ||
}); | ||
return Object.fromEntries(mostLiquidPools); | ||
} | ||
function calculatePricesForQuoteToken(mints, quoteTokenMint, poolMap, tickArrayMap, decimalsMap, config, thresholdConfig) { | ||
const mostLiquidPools = getMostLiquidPools(quoteTokenMint, poolMap); | ||
return Object.fromEntries(mints.map((mintAddr) => { | ||
@@ -82,5 +82,6 @@ const mint = common_sdk_1.AddressUtil.toPubKey(mintAddr); | ||
// Therefore, if the quote token is mintB, then we are swapping from mintA to mintB. | ||
const aToB = (0, anchor_1.translateAddress)(mintB).equals(quoteTokenMint); | ||
const poolCandidate = getMostLiquidPool(mintA, mintB, poolMap, config); | ||
if (poolCandidate == null) { | ||
const aToB = common_sdk_1.AddressUtil.toPubKey(mintB).equals(quoteTokenMint); | ||
const baseTokenMint = aToB ? mintA : mintB; | ||
const poolCandidate = mostLiquidPools[common_sdk_1.AddressUtil.toString(baseTokenMint)]; | ||
if (poolCandidate === undefined) { | ||
return [mint.toBase58(), null]; | ||
@@ -87,0 +88,0 @@ } |
@@ -197,16 +197,22 @@ "use strict"; | ||
const { programId } = config; | ||
const tickArrayAddresses = Object.entries(pools) | ||
.map(([poolAddress, pool]) => { | ||
const aToBTickArrayPublicKeys = public_1.SwapUtils.getTickArrayPublicKeys(pool.tickCurrentIndex, pool.tickSpacing, true, programId, new web3_js_1.PublicKey(poolAddress)); | ||
const bToATickArrayPublicKeys = public_1.SwapUtils.getTickArrayPublicKeys(pool.tickCurrentIndex, pool.tickSpacing, false, programId, new web3_js_1.PublicKey(poolAddress)); | ||
// Fetch tick arrays in both directions | ||
if (aToBTickArrayPublicKeys[0].equals(bToATickArrayPublicKeys[0])) { | ||
return aToBTickArrayPublicKeys.concat(bToATickArrayPublicKeys.slice(1)); | ||
const getQuoteTokenOrder = (mint) => { | ||
const index = config.quoteTokens.findIndex((quoteToken) => quoteToken.equals(mint)); | ||
return index === -1 ? config.quoteTokens.length : index; | ||
}; | ||
// select tick arrays based on the direction of swapQuote | ||
// TickArray is a large account, which affects decoding time. | ||
// Fetching can be performed in parallel, but it is preferable to fetch the minimum number of accounts necessary. | ||
const tickArrayAddressSet = new Set(); | ||
Object.entries(pools).forEach(([address, pool]) => { | ||
const orderA = getQuoteTokenOrder(pool.tokenMintA); | ||
const orderB = getQuoteTokenOrder(pool.tokenMintB); | ||
if (orderA === orderB) { | ||
// neither tokenMintA nor tokenMintB is a quote token | ||
return; | ||
} | ||
else { | ||
return aToBTickArrayPublicKeys.concat(bToATickArrayPublicKeys); | ||
} | ||
}) | ||
.flat() | ||
.map((tickArray) => tickArray.toBase58()); | ||
const aToB = orderA > orderB; | ||
const tickArrayPubkeys = public_1.SwapUtils.getTickArrayPublicKeys(pool.tickCurrentIndex, pool.tickSpacing, aToB, programId, new web3_js_1.PublicKey(address)); | ||
tickArrayPubkeys.forEach((p) => tickArrayAddressSet.add(p.toBase58())); | ||
}); | ||
const tickArrayAddresses = Array.from(tickArrayAddressSet); | ||
const tickArrays = yield ctx.fetcher.listTickArrays(tickArrayAddresses, refresh); | ||
@@ -213,0 +219,0 @@ const [filteredTickArrays, filteredTickArrayAddresses] = (0, txn_utils_1.filterNullObjects)(tickArrays, tickArrayAddresses); |
@@ -61,3 +61,3 @@ "use strict"; | ||
} | ||
const [cleanedQuoteMap, failures] = categorizeQuotes(tradeAmount, amountSpecifiedIsInput, quoteMap); | ||
const [cleanedQuoteMap, failures] = categorizeQuotes(quoteMap); | ||
const prunedQuoteMap = pruneQuoteMap(cleanedQuoteMap, numTopPartialQuotes, amountSpecifiedIsInput); | ||
@@ -243,3 +243,3 @@ const bestRoutes = [ | ||
*/ | ||
function categorizeQuotes(tradeAmount, amountSpecifiedIsInput, quoteMap) { | ||
function categorizeQuotes(quoteMap) { | ||
const percents = Object.keys(quoteMap).map((percent) => Number(percent)); | ||
@@ -256,10 +256,8 @@ const cleanedQuoteMap = {}; | ||
if (filteredCalculatedHops.length === route.length) { | ||
const otherAmount = amountSpecifiedIsInput | ||
? filteredCalculatedHops[filteredCalculatedHops.length - 1].amountOut | ||
: filteredCalculatedHops[0].amountIn; | ||
const [input, output] = [filteredCalculatedHops[0].amountIn, filteredCalculatedHops[filteredCalculatedHops.length - 1].amountOut]; | ||
cleanedQuoteMap[percent].push({ | ||
percent, | ||
route, | ||
amountIn: amountSpecifiedIsInput ? tradeAmount : otherAmount, | ||
amountOut: amountSpecifiedIsInput ? otherAmount : tradeAmount, | ||
amountIn: input, | ||
amountOut: output, | ||
calculatedHops: filteredCalculatedHops, | ||
@@ -266,0 +264,0 @@ }); |
@@ -52,2 +52,6 @@ /// <reference types="bn.js" /> | ||
}; | ||
/** | ||
* A collection of estimated values from quoting a swap. Object can be directly used in a swap transaction. | ||
* @category Quotes | ||
*/ | ||
export type NormalSwapQuote = SwapInput & SwapEstimates; | ||
@@ -54,0 +58,0 @@ /** |
@@ -19,6 +19,8 @@ "use strict"; | ||
// Run quick select algorithm to partition the topN results, mutating inplace | ||
const partitionSize = Math.min(topN, routes.length - 1); | ||
const routeCompare = getRouteCompareFn(amountSpecifiedIsInput); | ||
(0, k_smallest_partition_1.kSmallestPartition)(routes, partitionSize, 0, routes.length - 1, routeCompare); | ||
return routes.slice(0, partitionSize).sort(routeCompare); | ||
if (routes.length <= topN) { | ||
return routes.sort(routeCompare); | ||
} | ||
(0, k_smallest_partition_1.kSmallestPartition)(routes, topN, 0, routes.length - 1, routeCompare); | ||
return routes.slice(0, topN).sort(routeCompare); | ||
} | ||
@@ -25,0 +27,0 @@ exports.getRankedRoutes = getRankedRoutes; |
@@ -17,2 +17,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// TODO: Temp do not export new PoolGraph to avoid duplicate export. | ||
// export * from "../graphs/public"; | ||
__exportStar(require("./ix-utils"), exports); | ||
@@ -19,0 +21,0 @@ __exportStar(require("./pda-utils"), exports); |
{ | ||
"name": "@orca-so/whirlpools-sdk", | ||
"version": "0.9.0-alpha.6", | ||
"version": "0.9.0-alpha.7", | ||
"description": "Typescript SDK to interact with Orca's Whirlpool program.", | ||
@@ -19,3 +19,2 @@ "license": "Apache-2.0", | ||
"@types/bn.js": "~5.1.0", | ||
"@types/jest": "^26.0.24", | ||
"@types/mocha": "^9.0.0", | ||
@@ -26,9 +25,9 @@ "@typescript-eslint/eslint-plugin": "^4.26.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"jest": "^27.0.6", | ||
"mocha": "^9.0.3", | ||
"prettier": "^2.3.2", | ||
"process": "^0.11.10", | ||
"ts-jest": "^27.0.3", | ||
"typedoc": "~0.22.18", | ||
"typescript": "^4.5.5" | ||
"typescript": "^4.5.5", | ||
"ts-mocha": "^9.0.0", | ||
"ts-node": "^10.9.1" | ||
}, | ||
@@ -35,0 +34,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
824430
13
200
17770