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