@net-protocol/score 0.1.6 → 0.1.8

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/react.mjs CHANGED
@@ -1,8 +1,10 @@
1
- import { useReadContract, useWriteContract } from 'wagmi';
1
+ import { useReadContract, useWriteContract, usePublicClient } from 'wagmi';
2
2
  import { useMemo } from 'react';
3
3
  import { keccak256, encodePacked, formatEther } from 'viem';
4
4
  import { getStorageKeyBytes } from '@net-protocol/storage';
5
5
  import { getBaseDataSuffix } from '@net-protocol/core';
6
+ import { useQuery, skipToken } from '@tanstack/react-query';
7
+ import { readContract } from 'viem/actions';
6
8
 
7
9
  // src/hooks/useUpvotes.ts
8
10
 
@@ -160,6 +162,372 @@ var upvote_app_default = [
160
162
  { type: "error", name: "WithdrawFailed", inputs: [] }
161
163
  ];
162
164
 
165
+ // src/abis/multi-version-uniswap-bulk-pool-finder.json
166
+ var multi_version_uniswap_bulk_pool_finder_default = [
167
+ {
168
+ type: "function",
169
+ name: "V2_FACTORY",
170
+ inputs: [],
171
+ outputs: [{ name: "", type: "address", internalType: "address" }],
172
+ stateMutability: "view"
173
+ },
174
+ {
175
+ type: "function",
176
+ name: "V3_FACTORY",
177
+ inputs: [],
178
+ outputs: [{ name: "", type: "address", internalType: "address" }],
179
+ stateMutability: "view"
180
+ },
181
+ {
182
+ type: "function",
183
+ name: "V4_POOL_MANAGER",
184
+ inputs: [],
185
+ outputs: [{ name: "", type: "address", internalType: "address" }],
186
+ stateMutability: "view"
187
+ },
188
+ {
189
+ type: "function",
190
+ name: "_checkV4PoolExternal",
191
+ inputs: [
192
+ {
193
+ name: "poolKey",
194
+ type: "tuple",
195
+ internalType: "struct PoolKey",
196
+ components: [
197
+ {
198
+ name: "currency0",
199
+ type: "address",
200
+ internalType: "Currency"
201
+ },
202
+ {
203
+ name: "currency1",
204
+ type: "address",
205
+ internalType: "Currency"
206
+ },
207
+ { name: "fee", type: "uint24", internalType: "uint24" },
208
+ { name: "tickSpacing", type: "int24", internalType: "int24" },
209
+ {
210
+ name: "hooks",
211
+ type: "address",
212
+ internalType: "contract IHooks"
213
+ }
214
+ ]
215
+ }
216
+ ],
217
+ outputs: [{ name: "exists", type: "bool", internalType: "bool" }],
218
+ stateMutability: "view"
219
+ },
220
+ {
221
+ type: "function",
222
+ name: "getPoolsMultiVersion",
223
+ inputs: [
224
+ {
225
+ name: "params",
226
+ type: "tuple",
227
+ internalType: "struct MultiVersionUniswapBulkPoolFinder.PoolFinderParams",
228
+ components: [
229
+ {
230
+ name: "tokenAs",
231
+ type: "address[]",
232
+ internalType: "address[]"
233
+ },
234
+ {
235
+ name: "tokenBs",
236
+ type: "address[]",
237
+ internalType: "address[]"
238
+ },
239
+ { name: "fees", type: "uint24[]", internalType: "uint24[]" },
240
+ {
241
+ name: "v4TickSpacings",
242
+ type: "int24[]",
243
+ internalType: "int24[]"
244
+ },
245
+ {
246
+ name: "v4Hooks",
247
+ type: "address[]",
248
+ internalType: "address[]"
249
+ }
250
+ ]
251
+ }
252
+ ],
253
+ outputs: [
254
+ {
255
+ name: "pools",
256
+ type: "tuple[]",
257
+ internalType: "struct MultiVersionUniswapBulkPoolFinder.PoolDiscovery[]",
258
+ components: [
259
+ {
260
+ name: "pairIndex",
261
+ type: "uint256",
262
+ internalType: "uint256"
263
+ },
264
+ { name: "version", type: "uint8", internalType: "uint8" },
265
+ {
266
+ name: "poolAddress",
267
+ type: "address",
268
+ internalType: "address"
269
+ },
270
+ {
271
+ name: "poolKey",
272
+ type: "tuple",
273
+ internalType: "struct PoolKey",
274
+ components: [
275
+ {
276
+ name: "currency0",
277
+ type: "address",
278
+ internalType: "Currency"
279
+ },
280
+ {
281
+ name: "currency1",
282
+ type: "address",
283
+ internalType: "Currency"
284
+ },
285
+ { name: "fee", type: "uint24", internalType: "uint24" },
286
+ {
287
+ name: "tickSpacing",
288
+ type: "int24",
289
+ internalType: "int24"
290
+ },
291
+ {
292
+ name: "hooks",
293
+ type: "address",
294
+ internalType: "contract IHooks"
295
+ }
296
+ ]
297
+ },
298
+ { name: "fee", type: "uint24", internalType: "uint24" },
299
+ { name: "tickSpacing", type: "int24", internalType: "int24" },
300
+ { name: "hooks", type: "address", internalType: "address" }
301
+ ]
302
+ },
303
+ { name: "count", type: "uint256", internalType: "uint256" }
304
+ ],
305
+ stateMutability: "view"
306
+ }
307
+ ];
308
+
309
+ // src/abis/multi-version-uniswap-pool-info-retriever.json
310
+ var multi_version_uniswap_pool_info_retriever_default = [
311
+ {
312
+ type: "function",
313
+ name: "V4_POOL_MANAGER",
314
+ inputs: [],
315
+ outputs: [
316
+ {
317
+ name: "",
318
+ type: "address",
319
+ internalType: "address"
320
+ }
321
+ ],
322
+ stateMutability: "view"
323
+ },
324
+ {
325
+ type: "function",
326
+ name: "_getV4Liquidity",
327
+ inputs: [
328
+ {
329
+ name: "poolKey",
330
+ type: "tuple",
331
+ internalType: "struct PoolKey",
332
+ components: [
333
+ {
334
+ name: "currency0",
335
+ type: "address",
336
+ internalType: "Currency"
337
+ },
338
+ {
339
+ name: "currency1",
340
+ type: "address",
341
+ internalType: "Currency"
342
+ },
343
+ {
344
+ name: "fee",
345
+ type: "uint24",
346
+ internalType: "uint24"
347
+ },
348
+ {
349
+ name: "tickSpacing",
350
+ type: "int24",
351
+ internalType: "int24"
352
+ },
353
+ {
354
+ name: "hooks",
355
+ type: "address",
356
+ internalType: "contract IHooks"
357
+ }
358
+ ]
359
+ }
360
+ ],
361
+ outputs: [
362
+ {
363
+ name: "liquidity",
364
+ type: "uint128",
365
+ internalType: "uint128"
366
+ }
367
+ ],
368
+ stateMutability: "view"
369
+ },
370
+ {
371
+ type: "function",
372
+ name: "_getV4Slot0",
373
+ inputs: [
374
+ {
375
+ name: "poolKey",
376
+ type: "tuple",
377
+ internalType: "struct PoolKey",
378
+ components: [
379
+ {
380
+ name: "currency0",
381
+ type: "address",
382
+ internalType: "Currency"
383
+ },
384
+ {
385
+ name: "currency1",
386
+ type: "address",
387
+ internalType: "Currency"
388
+ },
389
+ {
390
+ name: "fee",
391
+ type: "uint24",
392
+ internalType: "uint24"
393
+ },
394
+ {
395
+ name: "tickSpacing",
396
+ type: "int24",
397
+ internalType: "int24"
398
+ },
399
+ {
400
+ name: "hooks",
401
+ type: "address",
402
+ internalType: "contract IHooks"
403
+ }
404
+ ]
405
+ }
406
+ ],
407
+ outputs: [
408
+ {
409
+ name: "sqrtPriceX96",
410
+ type: "uint160",
411
+ internalType: "uint160"
412
+ }
413
+ ],
414
+ stateMutability: "view"
415
+ },
416
+ {
417
+ type: "function",
418
+ name: "getPoolsFullInfoMultiVersion",
419
+ inputs: [
420
+ {
421
+ name: "v2PoolAddresses",
422
+ type: "address[]",
423
+ internalType: "address[]"
424
+ },
425
+ {
426
+ name: "v3PoolAddresses",
427
+ type: "address[]",
428
+ internalType: "address[]"
429
+ },
430
+ {
431
+ name: "v4PoolKeys",
432
+ type: "tuple[]",
433
+ internalType: "struct PoolKey[]",
434
+ components: [
435
+ {
436
+ name: "currency0",
437
+ type: "address",
438
+ internalType: "Currency"
439
+ },
440
+ {
441
+ name: "currency1",
442
+ type: "address",
443
+ internalType: "Currency"
444
+ },
445
+ {
446
+ name: "fee",
447
+ type: "uint24",
448
+ internalType: "uint24"
449
+ },
450
+ {
451
+ name: "tickSpacing",
452
+ type: "int24",
453
+ internalType: "int24"
454
+ },
455
+ {
456
+ name: "hooks",
457
+ type: "address",
458
+ internalType: "contract IHooks"
459
+ }
460
+ ]
461
+ },
462
+ {
463
+ name: "baseToken",
464
+ type: "address",
465
+ internalType: "address"
466
+ }
467
+ ],
468
+ outputs: [
469
+ {
470
+ name: "",
471
+ type: "tuple[]",
472
+ internalType: "struct MultiVersionPoolInfoRetriever.PoolFullInfo[]",
473
+ components: [
474
+ {
475
+ name: "poolAddress",
476
+ type: "address",
477
+ internalType: "address"
478
+ },
479
+ {
480
+ name: "token0",
481
+ type: "address",
482
+ internalType: "address"
483
+ },
484
+ {
485
+ name: "token1",
486
+ type: "address",
487
+ internalType: "address"
488
+ },
489
+ {
490
+ name: "token0Decimals",
491
+ type: "uint8",
492
+ internalType: "uint8"
493
+ },
494
+ {
495
+ name: "token1Decimals",
496
+ type: "uint8",
497
+ internalType: "uint8"
498
+ },
499
+ {
500
+ name: "sqrtPriceX96",
501
+ type: "uint256",
502
+ internalType: "uint256"
503
+ },
504
+ {
505
+ name: "baseTokenBalance",
506
+ type: "uint256",
507
+ internalType: "uint256"
508
+ },
509
+ {
510
+ name: "token0Balance",
511
+ type: "uint256",
512
+ internalType: "uint256"
513
+ },
514
+ {
515
+ name: "token1Balance",
516
+ type: "uint256",
517
+ internalType: "uint256"
518
+ },
519
+ {
520
+ name: "liquidity",
521
+ type: "uint128",
522
+ internalType: "uint128"
523
+ }
524
+ ]
525
+ }
526
+ ],
527
+ stateMutability: "view"
528
+ }
529
+ ];
530
+
163
531
  // src/abis/user-upvote.json
164
532
  var user_upvote_default = [
165
533
  {
@@ -637,6 +1005,27 @@ var ALL_STRATEGY_ADDRESSES = [
637
1005
  PURE_ALPHA_STRATEGY.address,
638
1006
  DYNAMIC_SPLIT_STRATEGY.address
639
1007
  ];
1008
+ var MULTI_VERSION_UNISWAP_BULK_POOL_FINDER = {
1009
+ address: "0xbc237dac4c74c170780fc12f353a258bdd31a8cf",
1010
+ abi: multi_version_uniswap_bulk_pool_finder_default
1011
+ };
1012
+ var MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER = {
1013
+ address: "0x00000002986Ca76897216a8A3A7Db10FcB0d29Cf",
1014
+ abi: multi_version_uniswap_pool_info_retriever_default
1015
+ };
1016
+ var WETH_BY_CHAIN = {
1017
+ 8453: "0x4200000000000000000000000000000000000006",
1018
+ // Base (L2 predeploy)
1019
+ 1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
1020
+ // Ethereum mainnet
1021
+ };
1022
+ function getWethAddress(chainId) {
1023
+ const addr = WETH_BY_CHAIN[chainId];
1024
+ if (!addr) {
1025
+ throw new Error(`Score: No WETH address for chain ${chainId}`);
1026
+ }
1027
+ return addr;
1028
+ }
640
1029
  var NULL_ADDRESS = "0x0000000000000000000000000000000000000000";
641
1030
  var USER_UPVOTE_CONTRACT = {
642
1031
  address: "0xa4bc2c63dd0157692fd5f409389e5032e37d8895",
@@ -873,7 +1262,361 @@ function useUpvotePrice({
873
1262
  refetch
874
1263
  };
875
1264
  }
1265
+ var V3_V4_FEE_TIERS = [500, 3e3, 1e4, 12e3, 8388608];
1266
+ var V4_TICK_SPACINGS = [200];
1267
+ var V4_HOOKS = [
1268
+ NULL_ADDRESS,
1269
+ "0xDd5EeaFf7BD481AD55Db083062b13a3cdf0A68CC",
1270
+ "0x34a45c6B61876d739400Bd71228CbcbD4F53E8cC",
1271
+ "0xb429d62f8f3bFFb98CdB9569533eA23bF0Ba28CC",
1272
+ "0xd60D6B218116cFd801E28F78d011a203D2b068Cc",
1273
+ "0x3e342a06f9592459D75721d6956B570F02eF2Dc0",
1274
+ "0xbB7784A4d481184283Ed89619A3e3ed143e1Adc0",
1275
+ "0xBDF938149ac6a781F94FAa0ed45E6A0e984c6544"
1276
+ ];
1277
+ var Q96 = BigInt(2) ** BigInt(96);
1278
+ var ZERO_BI = BigInt(0);
1279
+ function deriveV4WethDepthWei(liquidity, sqrtPriceX96, wethIsCurrency1) {
1280
+ if (sqrtPriceX96 === ZERO_BI || liquidity === ZERO_BI) return ZERO_BI;
1281
+ if (wethIsCurrency1) {
1282
+ return liquidity * sqrtPriceX96 / Q96;
1283
+ }
1284
+ return liquidity * Q96 / sqrtPriceX96;
1285
+ }
1286
+ function deriveV2V3WethDepthWei(info, wethLower) {
1287
+ if ((info.token0 ?? "").toLowerCase() === wethLower) {
1288
+ return BigInt(info.token0Balance ?? 0);
1289
+ }
1290
+ if ((info.token1 ?? "").toLowerCase() === wethLower) {
1291
+ return BigInt(info.token1Balance ?? 0);
1292
+ }
1293
+ return BigInt(info.baseTokenBalance ?? 0);
1294
+ }
1295
+ function normalizeTokenPairs(pairs, wethAddress) {
1296
+ return pairs.map((pair) => {
1297
+ const tokenA = pair.tokenAddress;
1298
+ const tokenB = pair.baseTokenAddress || wethAddress;
1299
+ return {
1300
+ originalPair: pair,
1301
+ tokenA: tokenA.toLowerCase() < tokenB.toLowerCase() ? tokenA : tokenB,
1302
+ tokenB: tokenA.toLowerCase() < tokenB.toLowerCase() ? tokenB : tokenA
1303
+ };
1304
+ });
1305
+ }
1306
+ function buildDiscoveryArgs(normalizedPairs) {
1307
+ return {
1308
+ tokenAs: normalizedPairs.map((p) => p.tokenA),
1309
+ tokenBs: normalizedPairs.map((p) => p.tokenB),
1310
+ fees: V3_V4_FEE_TIERS,
1311
+ v4TickSpacings: V4_TICK_SPACINGS,
1312
+ v4Hooks: V4_HOOKS
1313
+ };
1314
+ }
1315
+ function parsePoolDiscoveries(poolResults, pairs, wethAddress) {
1316
+ if (!poolResults) {
1317
+ return {
1318
+ v2PoolAddresses: [],
1319
+ v3PoolAddresses: [],
1320
+ v4PoolKeys: [],
1321
+ v2PoolAddressToPair: {},
1322
+ v3PoolAddressToPair: {},
1323
+ v4PoolKeyToPair: {}
1324
+ };
1325
+ }
1326
+ const [discoveries, countRaw] = poolResults;
1327
+ const countNum = typeof countRaw === "bigint" ? Number(countRaw) : Number(countRaw || 0);
1328
+ const v2PoolAddresses = [];
1329
+ const v3PoolAddresses = [];
1330
+ const v4PoolKeys = [];
1331
+ const seenV2V3Addresses = /* @__PURE__ */ new Set();
1332
+ const seenV4Keys = /* @__PURE__ */ new Set();
1333
+ const v2PoolAddressToPair = {};
1334
+ const v3PoolAddressToPair = {};
1335
+ const v4PoolKeyToPair = {};
1336
+ for (let i = 0; i < Math.min(countNum, discoveries.length); i++) {
1337
+ const discovery = discoveries[i];
1338
+ const version = Number(discovery?.version ?? 0);
1339
+ const poolAddressValue = discovery?.poolAddress;
1340
+ const pairIndex = Number(discovery?.pairIndex ?? 0);
1341
+ const feeNum = Number(discovery?.fee ?? 0);
1342
+ const poolKey = discovery?.poolKey;
1343
+ const pair = pairs[pairIndex];
1344
+ if (!pair) continue;
1345
+ if (version === 2 && poolAddressValue && poolAddressValue !== NULL_ADDRESS) {
1346
+ const poolAddress = poolAddressValue.toLowerCase();
1347
+ if (!seenV2V3Addresses.has(poolAddress)) {
1348
+ seenV2V3Addresses.add(poolAddress);
1349
+ v2PoolAddresses.push(poolAddressValue);
1350
+ v2PoolAddressToPair[poolAddress] = {
1351
+ tokenAddress: pair.tokenAddress,
1352
+ baseTokenAddress: pair.baseTokenAddress || wethAddress,
1353
+ fee: feeNum
1354
+ };
1355
+ }
1356
+ } else if (version === 3 && poolAddressValue && poolAddressValue !== NULL_ADDRESS) {
1357
+ const poolAddress = poolAddressValue.toLowerCase();
1358
+ if (!seenV2V3Addresses.has(poolAddress)) {
1359
+ seenV2V3Addresses.add(poolAddress);
1360
+ v3PoolAddresses.push(poolAddressValue);
1361
+ v3PoolAddressToPair[poolAddress] = {
1362
+ tokenAddress: pair.tokenAddress,
1363
+ baseTokenAddress: pair.baseTokenAddress || wethAddress,
1364
+ fee: feeNum
1365
+ };
1366
+ }
1367
+ } else if (version === 4 && poolKey) {
1368
+ const poolKeyString = JSON.stringify(poolKey);
1369
+ if (!seenV4Keys.has(poolKeyString)) {
1370
+ seenV4Keys.add(poolKeyString);
1371
+ v4PoolKeys.push(poolKey);
1372
+ v4PoolKeyToPair[poolKeyString] = {
1373
+ tokenAddress: pair.tokenAddress,
1374
+ baseTokenAddress: pair.baseTokenAddress || wethAddress,
1375
+ fee: feeNum
1376
+ };
1377
+ }
1378
+ }
1379
+ }
1380
+ return {
1381
+ v2PoolAddresses,
1382
+ v3PoolAddresses,
1383
+ v4PoolKeys,
1384
+ v2PoolAddressToPair,
1385
+ v3PoolAddressToPair,
1386
+ v4PoolKeyToPair
1387
+ };
1388
+ }
1389
+ function determinePoolVersion(discoveries, index) {
1390
+ const {
1391
+ v2PoolAddresses,
1392
+ v3PoolAddresses,
1393
+ v4PoolKeys,
1394
+ v2PoolAddressToPair,
1395
+ v3PoolAddressToPair,
1396
+ v4PoolKeyToPair
1397
+ } = discoveries;
1398
+ if (index < v2PoolAddresses.length) {
1399
+ const poolAddress = v2PoolAddresses[index].toLowerCase();
1400
+ return {
1401
+ version: 2,
1402
+ pair: v2PoolAddressToPair[poolAddress],
1403
+ fee: 0,
1404
+ v4PoolKey: void 0
1405
+ };
1406
+ } else if (index < v2PoolAddresses.length + v3PoolAddresses.length) {
1407
+ const v3Index = index - v2PoolAddresses.length;
1408
+ const poolAddress = v3PoolAddresses[v3Index].toLowerCase();
1409
+ return {
1410
+ version: 3,
1411
+ pair: v3PoolAddressToPair[poolAddress],
1412
+ fee: v3PoolAddressToPair[poolAddress]?.fee || 0,
1413
+ v4PoolKey: void 0
1414
+ };
1415
+ } else {
1416
+ const v4Index = index - v2PoolAddresses.length - v3PoolAddresses.length;
1417
+ const poolKey = v4PoolKeys[v4Index];
1418
+ const poolKeyString = JSON.stringify(poolKey);
1419
+ return {
1420
+ version: 4,
1421
+ pair: v4PoolKeyToPair[poolKeyString],
1422
+ fee: v4PoolKeyToPair[poolKeyString]?.fee || 0,
1423
+ v4PoolKey: poolKey
1424
+ };
1425
+ }
1426
+ }
1427
+ function calculatePoolPrice(info, pair, version) {
1428
+ try {
1429
+ const sqrtPriceX96 = Number(info.sqrtPriceX96);
1430
+ const token0Decimals = Number(info.token0Decimals);
1431
+ const token1Decimals = Number(info.token1Decimals);
1432
+ const isToken0 = info.token0.toLowerCase() === pair.tokenAddress.toLowerCase();
1433
+ if (version === 2) {
1434
+ const token0Balance = Number(info.token0Balance) / 10 ** token0Decimals;
1435
+ const token1Balance = Number(info.token1Balance) / 10 ** token1Decimals;
1436
+ if (token0Balance === 0 || token1Balance === 0) return null;
1437
+ if (isToken0) {
1438
+ return token1Balance / token0Balance;
1439
+ } else {
1440
+ return token0Balance / token1Balance;
1441
+ }
1442
+ } else {
1443
+ if (sqrtPriceX96 === 0) return null;
1444
+ if (isToken0) {
1445
+ return (sqrtPriceX96 / 2 ** 96) ** 2 * 10 ** (token0Decimals - token1Decimals);
1446
+ } else {
1447
+ const priceX96 = (sqrtPriceX96 / 2 ** 96) ** 2;
1448
+ return 1 / priceX96 * 10 ** (token1Decimals - token0Decimals);
1449
+ }
1450
+ }
1451
+ } catch {
1452
+ return null;
1453
+ }
1454
+ }
1455
+ function constructPoolKey(info, pair, version, v4PoolKey) {
1456
+ try {
1457
+ if (!info.token0 || !info.token1 || typeof pair.fee !== "number") {
1458
+ return void 0;
1459
+ }
1460
+ if (!info.token0.startsWith("0x") || !info.token1.startsWith("0x")) {
1461
+ return void 0;
1462
+ }
1463
+ const currency0 = info.token0.toLowerCase() < info.token1.toLowerCase() ? info.token0 : info.token1;
1464
+ const currency1 = info.token0.toLowerCase() < info.token1.toLowerCase() ? info.token1 : info.token0;
1465
+ if (version === 2) {
1466
+ return {
1467
+ currency0,
1468
+ currency1,
1469
+ fee: 0,
1470
+ tickSpacing: 0,
1471
+ hooks: NULL_ADDRESS
1472
+ };
1473
+ } else if (version === 3) {
1474
+ return {
1475
+ currency0,
1476
+ currency1,
1477
+ fee: pair.fee,
1478
+ tickSpacing: 0,
1479
+ hooks: NULL_ADDRESS
1480
+ };
1481
+ } else {
1482
+ if (!v4PoolKey || !v4PoolKey.currency0 || !v4PoolKey.currency1) {
1483
+ return void 0;
1484
+ }
1485
+ return v4PoolKey;
1486
+ }
1487
+ } catch {
1488
+ return void 0;
1489
+ }
1490
+ }
1491
+ function selectBestPoolPerPair(allPools) {
1492
+ const poolsByPair = {};
1493
+ for (const pool of allPools) {
1494
+ const key = pool.tokenAddress.toLowerCase() + "_" + pool.baseTokenAddress.toLowerCase();
1495
+ if (!poolsByPair[key]) poolsByPair[key] = [];
1496
+ poolsByPair[key].push(pool);
1497
+ }
1498
+ const bestPools = [];
1499
+ for (const group of Object.values(poolsByPair)) {
1500
+ const withDepth = group.filter((p) => p.wethDepthWei > ZERO_BI);
1501
+ if (withDepth.length === 0) continue;
1502
+ const best = withDepth.reduce(
1503
+ (a, b) => a.wethDepthWei > b.wethDepthWei ? a : b
1504
+ );
1505
+ bestPools.push(best);
1506
+ }
1507
+ return bestPools;
1508
+ }
1509
+ async function discoverPools({
1510
+ publicClient,
1511
+ pairs,
1512
+ chainId = 8453
1513
+ }) {
1514
+ if (pairs.length === 0) return [];
1515
+ const wethAddress = getWethAddress(chainId);
1516
+ const normalizedPairs = normalizeTokenPairs(pairs, wethAddress);
1517
+ const discoveryArgs = buildDiscoveryArgs(normalizedPairs);
1518
+ const poolResults = await readContract(publicClient, {
1519
+ address: MULTI_VERSION_UNISWAP_BULK_POOL_FINDER.address,
1520
+ abi: MULTI_VERSION_UNISWAP_BULK_POOL_FINDER.abi,
1521
+ functionName: "getPoolsMultiVersion",
1522
+ args: [discoveryArgs]
1523
+ });
1524
+ const discoveries = parsePoolDiscoveries(poolResults, pairs, wethAddress);
1525
+ const totalPools = discoveries.v2PoolAddresses.length + discoveries.v3PoolAddresses.length + discoveries.v4PoolKeys.length;
1526
+ if (totalPools === 0) return [];
1527
+ const poolInfos = await readContract(publicClient, {
1528
+ address: MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER.address,
1529
+ abi: MULTI_VERSION_UNISWAP_POOL_INFO_RETRIEVER.abi,
1530
+ functionName: "getPoolsFullInfoMultiVersion",
1531
+ args: [
1532
+ discoveries.v2PoolAddresses,
1533
+ discoveries.v3PoolAddresses,
1534
+ discoveries.v4PoolKeys,
1535
+ wethAddress
1536
+ ]
1537
+ });
1538
+ if (!Array.isArray(poolInfos) || poolInfos.length === 0) return [];
1539
+ const wethLower = wethAddress.toLowerCase();
1540
+ const allPools = poolInfos.map((info, index) => {
1541
+ const poolData = determinePoolVersion(discoveries, index);
1542
+ if (!poolData || !poolData.pair) return null;
1543
+ const isV4 = poolData.version === 4;
1544
+ const liquidity = BigInt(info.liquidity ?? 0);
1545
+ let wethDepthWei;
1546
+ if (isV4) {
1547
+ const wethIsCurrency1 = poolData.v4PoolKey.currency1.toLowerCase() === wethLower;
1548
+ wethDepthWei = deriveV4WethDepthWei(
1549
+ liquidity,
1550
+ BigInt(info.sqrtPriceX96 ?? 0),
1551
+ wethIsCurrency1
1552
+ );
1553
+ } else {
1554
+ wethDepthWei = deriveV2V3WethDepthWei(info, wethLower);
1555
+ }
1556
+ return {
1557
+ tokenAddress: poolData.pair.tokenAddress,
1558
+ baseTokenAddress: poolData.pair.baseTokenAddress || wethAddress,
1559
+ poolAddress: isV4 ? null : info.poolAddress,
1560
+ price: calculatePoolPrice(info, poolData.pair, poolData.version),
1561
+ baseTokenBalance: String(info.baseTokenBalance || 0),
1562
+ token0: info.token0,
1563
+ token1: info.token1,
1564
+ token0Balance: String(info.token0Balance || 0),
1565
+ token1Balance: String(info.token1Balance || 0),
1566
+ fee: poolData.fee,
1567
+ poolKey: constructPoolKey(
1568
+ info,
1569
+ poolData.pair,
1570
+ poolData.version,
1571
+ poolData.v4PoolKey
1572
+ ),
1573
+ liquidity: String(liquidity),
1574
+ wethDepthWei
1575
+ };
1576
+ }).filter((p) => p !== null);
1577
+ const bestPools = selectBestPoolPerPair(allPools);
1578
+ return bestPools.map(
1579
+ (pool) => ({
1580
+ tokenAddress: pool.tokenAddress,
1581
+ baseTokenAddress: pool.baseTokenAddress,
1582
+ poolAddress: pool.poolAddress,
1583
+ price: pool.price,
1584
+ fee: pool.fee,
1585
+ poolKey: pool.poolKey,
1586
+ liquidity: pool.liquidity,
1587
+ balances: {
1588
+ baseTokenBalance: pool.baseTokenBalance,
1589
+ token0Balance: pool.token0Balance,
1590
+ token1Balance: pool.token1Balance
1591
+ }
1592
+ })
1593
+ );
1594
+ }
1595
+
1596
+ // src/hooks/useDiscoverPools.ts
1597
+ function useDiscoverPools({
1598
+ chainId,
1599
+ pairs,
1600
+ enabled = true
1601
+ }) {
1602
+ const publicClient = usePublicClient({ chainId });
1603
+ const canRun = enabled && !!publicClient && pairs.length > 0;
1604
+ const keyPairs = pairs.map((p) => [
1605
+ p.tokenAddress.toLowerCase(),
1606
+ p.baseTokenAddress?.toLowerCase()
1607
+ ]);
1608
+ const { data, isLoading, error, refetch } = useQuery({
1609
+ queryKey: ["discoverPools", chainId, keyPairs],
1610
+ queryFn: canRun ? () => discoverPools({ publicClient, pairs, chainId }) : skipToken
1611
+ });
1612
+ return {
1613
+ pools: data ?? [],
1614
+ isLoading,
1615
+ error,
1616
+ refetch
1617
+ };
1618
+ }
876
1619
 
877
- export { getScoreKey, getStorageScoreKey, getTokenScoreKey, useTokenUpvotes, useUpvotePrice, useUpvoteUser, useUpvotes, useUpvotesBatch, useUserUpvotesGiven, useUserUpvotesGivenPerTokenBatch, useUserUpvotesReceived, useUserUpvotesReceivedPerTokenBatch };
1620
+ export { getScoreKey, getStorageScoreKey, getTokenScoreKey, useDiscoverPools, useTokenUpvotes, useUpvotePrice, useUpvoteUser, useUpvotes, useUpvotesBatch, useUserUpvotesGiven, useUserUpvotesGivenPerTokenBatch, useUserUpvotesReceived, useUserUpvotesReceivedPerTokenBatch };
878
1621
  //# sourceMappingURL=react.mjs.map
879
1622
  //# sourceMappingURL=react.mjs.map