@guru-fund/sdk 0.2.8 → 0.2.10
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/dist/router/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import getUniswapV4Route, { connectV4Quoter, toAdapterPathKeys, } from './getUni
|
|
|
7
7
|
import getVeloraRoute from './getVeloraRoute.js';
|
|
8
8
|
import { stablecoinAddresses } from './helpers.js';
|
|
9
9
|
import PoolHelper from './poolHelper.js';
|
|
10
|
+
import { V4_ZERO_ADDRESS } from './constants.js';
|
|
10
11
|
import { discoverV4Paths } from './v4PoolDiscovery.js';
|
|
11
12
|
const AERO_V3_FACTORY_ABI = [
|
|
12
13
|
'function getPool(address tokenA, address tokenB, int24 tickSpacing) view returns (address pool)',
|
|
@@ -342,6 +343,11 @@ async function _priceViaV4Pools(token, oneToken, getWethUsd, ctx) {
|
|
|
342
343
|
}
|
|
343
344
|
return best > 0n ? best : null;
|
|
344
345
|
};
|
|
346
|
+
const inNative = await quoteVia(V4_ZERO_ADDRESS);
|
|
347
|
+
if (inNative !== null) {
|
|
348
|
+
const wethUsd = await getWethUsd();
|
|
349
|
+
return (inNative * wethUsd) / WETH_UNIT;
|
|
350
|
+
}
|
|
345
351
|
const inUsdc = await quoteVia(addresses.tokens.USDG ?? addresses.tokens.USDC);
|
|
346
352
|
if (inUsdc !== null) {
|
|
347
353
|
return inUsdc * 10n ** 12n;
|
|
@@ -24,7 +24,10 @@ const V3_FACTORY_ABI = [
|
|
|
24
24
|
const AERO_V3_FACTORY_ABI = [
|
|
25
25
|
'function getPool(address tokenA, address tokenB, int24 tickSpacing) view returns (address pool)',
|
|
26
26
|
];
|
|
27
|
-
const V3_POOL_ABI = [
|
|
27
|
+
const V3_POOL_ABI = [
|
|
28
|
+
'function fee() view returns (uint24)',
|
|
29
|
+
'function liquidity() view returns (uint128)',
|
|
30
|
+
];
|
|
28
31
|
const AERO_FACTORY_ABI = [
|
|
29
32
|
'function getPool(address tokenA, address tokenB, bool stable) view returns (address)',
|
|
30
33
|
];
|
|
@@ -114,6 +117,17 @@ function buildDexTable(addresses) {
|
|
|
114
117
|
}
|
|
115
118
|
return table;
|
|
116
119
|
}
|
|
120
|
+
export function rankUsablePools(pools) {
|
|
121
|
+
return pools
|
|
122
|
+
.filter((pool) => pool.feeTier === 0 || (pool.activeLiquidity ?? 0n) > 0n)
|
|
123
|
+
.sort((a, b) => {
|
|
124
|
+
if (a.wethBalance > b.wethBalance)
|
|
125
|
+
return -1;
|
|
126
|
+
if (a.wethBalance < b.wethBalance)
|
|
127
|
+
return 1;
|
|
128
|
+
return 0;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
117
131
|
const PERCENT_DENOMINATOR = 100000n;
|
|
118
132
|
const CACHE_DURATION = 60 * 60 * 1000;
|
|
119
133
|
function withSlippageTolerance(amount, slippage) {
|
|
@@ -274,11 +288,14 @@ export default class PoolHelper {
|
|
|
274
288
|
const wethBalance = await wethToken.balanceOf(poolAddress);
|
|
275
289
|
if (wethBalance === 0n)
|
|
276
290
|
return;
|
|
291
|
+
const pool = connect(poolAddress, V3_POOL_ABI, this.provider);
|
|
292
|
+
const activeLiquidity = await pool.liquidity();
|
|
277
293
|
pools.push({
|
|
278
294
|
address: poolAddress,
|
|
279
295
|
feeTier: feeTier,
|
|
280
296
|
exchangeFactory: factoryAddress,
|
|
281
297
|
wethBalance,
|
|
298
|
+
activeLiquidity,
|
|
282
299
|
});
|
|
283
300
|
}
|
|
284
301
|
catch {
|
|
@@ -286,14 +303,7 @@ export default class PoolHelper {
|
|
|
286
303
|
}));
|
|
287
304
|
}
|
|
288
305
|
}));
|
|
289
|
-
pools
|
|
290
|
-
if (a.wethBalance > b.wethBalance)
|
|
291
|
-
return -1;
|
|
292
|
-
if (a.wethBalance < b.wethBalance)
|
|
293
|
-
return 1;
|
|
294
|
-
return 0;
|
|
295
|
-
});
|
|
296
|
-
return pools;
|
|
306
|
+
return rankUsablePools(pools);
|
|
297
307
|
}
|
|
298
308
|
async getUniswapCompatibleTokenPools(token, options) {
|
|
299
309
|
const swappableOnly = options?.swappableOnly ?? true;
|
|
@@ -23,6 +23,7 @@ interface DexscreenerPair {
|
|
|
23
23
|
liquidity?: {
|
|
24
24
|
usd?: number;
|
|
25
25
|
};
|
|
26
|
+
pairCreatedAt?: number;
|
|
26
27
|
}
|
|
27
28
|
export declare function selectV4PairPoolIds(pairs: DexscreenerPair[], tokenIn: string, tokenOut: string): string[];
|
|
28
29
|
export declare function stitchNativeBridgeV4Paths(firstLegs: V4Path[], secondLegs: V4Path[]): V4Path[];
|
|
@@ -66,18 +66,63 @@ export function stitchNativeBridgeV4Paths(firstLegs, secondLegs) {
|
|
|
66
66
|
return paths;
|
|
67
67
|
}
|
|
68
68
|
const poolKeyCache = new Map();
|
|
69
|
-
async function resolvePoolKey(chainId, poolId, provider) {
|
|
69
|
+
async function resolvePoolKey(chainId, poolId, provider, pairCreatedAt) {
|
|
70
70
|
const cacheKey = `${chainId}:${poolId}`;
|
|
71
71
|
const cached = poolKeyCache.get(cacheKey);
|
|
72
72
|
if (cached)
|
|
73
73
|
return cached;
|
|
74
74
|
const config = V4_CHAIN_CONFIG[chainId];
|
|
75
|
-
const
|
|
75
|
+
const filter = {
|
|
76
76
|
address: config.poolManager,
|
|
77
77
|
topics: [POOL_INITIALIZE_TOPIC, poolId],
|
|
78
78
|
fromBlock: config.deployBlock,
|
|
79
79
|
toBlock: 'latest',
|
|
80
|
-
}
|
|
80
|
+
};
|
|
81
|
+
let logs;
|
|
82
|
+
try {
|
|
83
|
+
logs = await provider.getLogs(filter);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
logs = [];
|
|
87
|
+
const latestBlock = await provider.getBlockNumber();
|
|
88
|
+
const chunkSize = 9_999;
|
|
89
|
+
if (pairCreatedAt) {
|
|
90
|
+
let low = config.deployBlock;
|
|
91
|
+
let high = latestBlock;
|
|
92
|
+
const targetTimestamp = Math.floor(pairCreatedAt / 1_000);
|
|
93
|
+
while (low < high) {
|
|
94
|
+
const middle = Math.floor((low + high) / 2);
|
|
95
|
+
const block = await provider.getBlock(middle);
|
|
96
|
+
if (!block)
|
|
97
|
+
break;
|
|
98
|
+
if (block.timestamp < targetTimestamp)
|
|
99
|
+
low = middle + 1;
|
|
100
|
+
else
|
|
101
|
+
high = middle;
|
|
102
|
+
}
|
|
103
|
+
const fromBlock = Math.max(config.deployBlock, low - 5_000);
|
|
104
|
+
const toBlock = Math.min(latestBlock, fromBlock + chunkSize);
|
|
105
|
+
logs = await provider.getLogs({
|
|
106
|
+
...filter,
|
|
107
|
+
fromBlock,
|
|
108
|
+
toBlock,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (logs.length === 0) {
|
|
112
|
+
for (let toBlock = latestBlock; toBlock >= config.deployBlock; toBlock -= chunkSize + 1) {
|
|
113
|
+
const fromBlock = Math.max(config.deployBlock, toBlock - chunkSize);
|
|
114
|
+
const chunk = await provider.getLogs({
|
|
115
|
+
...filter,
|
|
116
|
+
fromBlock,
|
|
117
|
+
toBlock,
|
|
118
|
+
});
|
|
119
|
+
if (chunk.length > 0) {
|
|
120
|
+
logs = chunk;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
81
126
|
const log = logs[0];
|
|
82
127
|
if (!log)
|
|
83
128
|
return null;
|
|
@@ -142,6 +187,7 @@ async function discoverDirectV4Paths(chainId, tokenIn, tokenOut, provider, endpo
|
|
|
142
187
|
const isMajor = (token) => majors.some((major) => compareAddresses(major, token));
|
|
143
188
|
const queryOrder = isMajor(tokenIn) ? [tokenOut, tokenIn] : [tokenIn, tokenOut];
|
|
144
189
|
let poolIds = [];
|
|
190
|
+
const pairCreatedAtByPoolId = new Map();
|
|
145
191
|
for (const queryToken of queryOrder) {
|
|
146
192
|
const response = await fetch(`${endpoint}/${config.dexscreenerSlug}/${queryToken}`);
|
|
147
193
|
if (!response.ok) {
|
|
@@ -149,10 +195,16 @@ async function discoverDirectV4Paths(chainId, tokenIn, tokenOut, provider, endpo
|
|
|
149
195
|
}
|
|
150
196
|
const pairs = (await response.json());
|
|
151
197
|
poolIds = selectV4PairPoolIds(pairs, tokenIn, tokenOut);
|
|
152
|
-
if (poolIds.length > 0)
|
|
198
|
+
if (poolIds.length > 0) {
|
|
199
|
+
for (const pair of pairs) {
|
|
200
|
+
if (!pair.pairAddress || !pair.pairCreatedAt)
|
|
201
|
+
continue;
|
|
202
|
+
pairCreatedAtByPoolId.set(pair.pairAddress.toLowerCase(), pair.pairCreatedAt);
|
|
203
|
+
}
|
|
153
204
|
break;
|
|
205
|
+
}
|
|
154
206
|
}
|
|
155
|
-
const keys = await Promise.all(poolIds.map((poolId) => resolvePoolKey(chainId, poolId, provider)));
|
|
207
|
+
const keys = await Promise.all(poolIds.map((poolId) => resolvePoolKey(chainId, poolId, provider, pairCreatedAtByPoolId.get(poolId))));
|
|
156
208
|
const resolvedKeys = keys.filter((key) => key !== null && isSafeDiscoveredV4PoolKey(key));
|
|
157
209
|
const onchainKeys = resolvedKeys.length > 0
|
|
158
210
|
? []
|