@andrewkimjoseph/celina-sdk 0.27.5 → 0.28.0

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.
Files changed (90) hide show
  1. package/README.md +2 -2
  2. package/build/a2a/skills.js +1 -1
  3. package/build/a2a/skills.js.map +1 -1
  4. package/build/abis/aave-data-provider.d.ts +17 -0
  5. package/build/abis/aave-data-provider.js +14 -0
  6. package/build/abis/aave-data-provider.js.map +1 -0
  7. package/build/abis/uniswap-v3.d.ts +171 -0
  8. package/build/abis/uniswap-v3.js +120 -0
  9. package/build/abis/uniswap-v3.js.map +1 -0
  10. package/build/config/aave.d.ts +2 -0
  11. package/build/config/aave.js +2 -0
  12. package/build/config/aave.js.map +1 -1
  13. package/build/config/uniswap.d.ts +15 -0
  14. package/build/config/uniswap.js +9 -1
  15. package/build/config/uniswap.js.map +1 -1
  16. package/build/index.d.ts +3 -3
  17. package/build/services/aave.service.d.ts +7 -0
  18. package/build/services/aave.service.js +31 -1
  19. package/build/services/aave.service.js.map +1 -1
  20. package/build/services/swap-pairs.d.ts +18 -4
  21. package/build/services/swap-pairs.js +35 -2
  22. package/build/services/swap-pairs.js.map +1 -1
  23. package/build/services/uniswap-path-router.d.ts +11 -1
  24. package/build/services/uniswap-path-router.js +36 -10
  25. package/build/services/uniswap-path-router.js.map +1 -1
  26. package/build/services/uniswap-v3-path-router.d.ts +40 -0
  27. package/build/services/uniswap-v3-path-router.js +183 -0
  28. package/build/services/uniswap-v3-path-router.js.map +1 -0
  29. package/build/services/uniswap-v3-pool-discovery.d.ts +33 -0
  30. package/build/services/uniswap-v3-pool-discovery.js +141 -0
  31. package/build/services/uniswap-v3-pool-discovery.js.map +1 -0
  32. package/build/services/uniswap-venue-quote.d.ts +28 -0
  33. package/build/services/uniswap-venue-quote.js +114 -0
  34. package/build/services/uniswap-venue-quote.js.map +1 -0
  35. package/build/services/uniswap.service.d.ts +24 -9
  36. package/build/services/uniswap.service.js +86 -37
  37. package/build/services/uniswap.service.js.map +1 -1
  38. package/build/src/a2a/skills.js +1 -1
  39. package/build/src/a2a/skills.js.map +1 -1
  40. package/build/src/abis/aave-data-provider.d.ts +17 -0
  41. package/build/src/abis/aave-data-provider.js +14 -0
  42. package/build/src/abis/aave-data-provider.js.map +1 -0
  43. package/build/src/abis/uniswap-v3.d.ts +171 -0
  44. package/build/src/abis/uniswap-v3.js +120 -0
  45. package/build/src/abis/uniswap-v3.js.map +1 -0
  46. package/build/src/config/aave.d.ts +2 -0
  47. package/build/src/config/aave.js +2 -0
  48. package/build/src/config/aave.js.map +1 -1
  49. package/build/src/config/uniswap.d.ts +15 -0
  50. package/build/src/config/uniswap.js +9 -1
  51. package/build/src/config/uniswap.js.map +1 -1
  52. package/build/src/index.d.ts +3 -3
  53. package/build/src/services/aave.service.d.ts +7 -0
  54. package/build/src/services/aave.service.js +31 -1
  55. package/build/src/services/aave.service.js.map +1 -1
  56. package/build/src/services/swap-pairs.d.ts +18 -4
  57. package/build/src/services/swap-pairs.js +35 -2
  58. package/build/src/services/swap-pairs.js.map +1 -1
  59. package/build/src/services/uniswap-path-router.d.ts +11 -1
  60. package/build/src/services/uniswap-path-router.js +36 -10
  61. package/build/src/services/uniswap-path-router.js.map +1 -1
  62. package/build/src/services/uniswap-v3-path-router.d.ts +40 -0
  63. package/build/src/services/uniswap-v3-path-router.js +183 -0
  64. package/build/src/services/uniswap-v3-path-router.js.map +1 -0
  65. package/build/src/services/uniswap-v3-pool-discovery.d.ts +33 -0
  66. package/build/src/services/uniswap-v3-pool-discovery.js +141 -0
  67. package/build/src/services/uniswap-v3-pool-discovery.js.map +1 -0
  68. package/build/src/services/uniswap-venue-quote.d.ts +28 -0
  69. package/build/src/services/uniswap-venue-quote.js +114 -0
  70. package/build/src/services/uniswap-venue-quote.js.map +1 -0
  71. package/build/src/services/uniswap.service.d.ts +24 -9
  72. package/build/src/services/uniswap.service.js +86 -37
  73. package/build/src/services/uniswap.service.js.map +1 -1
  74. package/build/src/tools/domains/browser.js +5 -3
  75. package/build/src/tools/domains/browser.js.map +1 -1
  76. package/build/src/tools/domains/uniswap.js +5 -5
  77. package/build/src/tools/domains/uniswap.js.map +1 -1
  78. package/build/src/tools/swap-routing.d.ts +2 -2
  79. package/build/src/tools/swap-routing.js +21 -6
  80. package/build/src/tools/swap-routing.js.map +1 -1
  81. package/build/tests/catalog/domains/defi.js +8 -1
  82. package/build/tests/catalog/domains/defi.js.map +1 -1
  83. package/build/tools/domains/browser.js +5 -3
  84. package/build/tools/domains/browser.js.map +1 -1
  85. package/build/tools/domains/uniswap.js +5 -5
  86. package/build/tools/domains/uniswap.js.map +1 -1
  87. package/build/tools/swap-routing.d.ts +2 -2
  88. package/build/tools/swap-routing.js +21 -6
  89. package/build/tools/swap-routing.js.map +1 -1
  90. package/package.json +1 -1
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import type { PublicClient } from "viem";
5
5
  import { type UniswapPoolKey } from "../config/uniswap.js";
6
+ import { type UniswapPoolIndex } from "./uniswap-pool-discovery.js";
6
7
  /** Single hop descriptor in a Uniswap v4 multi-hop path. */
7
8
  export type UniswapPathKey = {
8
9
  intermediateCurrency: `0x${string}`;
@@ -28,6 +29,15 @@ export type UniswapSwapRoute = {
28
29
  * prepare steps that follow it in the same chat turn.
29
30
  */
30
31
  export declare const MAX_QUOTE_PATHS = 16;
32
+ /**
33
+ * Split a shared simulateContract budget across two venues.
34
+ * Each venue gets up to half, then leftover calls go to the venue with more candidates.
35
+ */
36
+ export declare function splitQuoteBudget(firstCount: number, secondCount: number, total?: number): {
37
+ first: number;
38
+ second: number;
39
+ };
40
+ export declare function countV4CandidatePaths(index: UniswapPoolIndex, currencyIn: `0x${string}`, currencyOut: `0x${string}`): number;
31
41
  /**
32
42
  * Quote all candidate paths and return the highest-output Uniswap v4 route.
33
43
  * @param client - Celo public client for quoter simulation
@@ -36,7 +46,7 @@ export declare const MAX_QUOTE_PATHS = 16;
36
46
  * @param amountIn - Input amount in base units
37
47
  * @returns Best route and quoter output, or `null` when no path quotes successfully
38
48
  */
39
- export declare function findBestUniswapRoute(client: PublicClient, currencyIn: `0x${string}`, currencyOut: `0x${string}`, amountIn: bigint): Promise<{
49
+ export declare function findBestUniswapRoute(client: PublicClient, currencyIn: `0x${string}`, currencyOut: `0x${string}`, amountIn: bigint, maxPaths?: number, index?: UniswapPoolIndex): Promise<{
40
50
  route: UniswapSwapRoute;
41
51
  amountOut: bigint;
42
52
  indexSource: string;
@@ -39,6 +39,35 @@ function buildPathKeys(pools, currencyIn) {
39
39
  }
40
40
  return pathKeys;
41
41
  }
42
+ /**
43
+ * Split a shared simulateContract budget across two venues.
44
+ * Each venue gets up to half, then leftover calls go to the venue with more candidates.
45
+ */
46
+ export function splitQuoteBudget(firstCount, secondCount, total = MAX_QUOTE_PATHS) {
47
+ const budget = Math.max(0, total);
48
+ const firstNeeded = Math.max(0, firstCount);
49
+ const secondNeeded = Math.max(0, secondCount);
50
+ if (firstNeeded + secondNeeded <= budget) {
51
+ return { first: firstNeeded, second: secondNeeded };
52
+ }
53
+ const half = Math.floor(budget / 2);
54
+ let first = Math.min(firstNeeded, half);
55
+ let second = Math.min(secondNeeded, budget - first);
56
+ let leftover = budget - first - second;
57
+ if (firstNeeded > first && leftover > 0) {
58
+ const give = Math.min(leftover, firstNeeded - first);
59
+ first += give;
60
+ leftover -= give;
61
+ }
62
+ if (secondNeeded > second && leftover > 0) {
63
+ const give = Math.min(leftover, secondNeeded - second);
64
+ second += give;
65
+ }
66
+ return { first, second };
67
+ }
68
+ export function countV4CandidatePaths(index, currencyIn, currencyOut) {
69
+ return enumeratePaths(index, currencyIn, currencyOut).length;
70
+ }
42
71
  function enumeratePaths(index, currencyIn, currencyOut) {
43
72
  const start = currencyIn.toLowerCase();
44
73
  const goal = currencyOut.toLowerCase();
@@ -125,16 +154,13 @@ async function quotePath(client, currencyIn, pools, amountIn) {
125
154
  * @param amountIn - Input amount in base units
126
155
  * @returns Best route and quoter output, or `null` when no path quotes successfully
127
156
  */
128
- export async function findBestUniswapRoute(client, currencyIn, currencyOut, amountIn) {
129
- const index = await getUniswapPoolIndex(client);
130
- // Sort shortest-first so 1-hop direct pools are always preferred, then cap to
131
- // MAX_QUOTE_PATHS to keep the concurrent simulateContract fan-out bounded.
132
- // Each simulateContract call is one Cloudflare Workers subrequest; an
133
- // unbounded walk over a dense pool graph can exhaust the per-invocation
134
- // budget before the subsequent balance-check and prepare steps can run.
135
- const candidatePaths = enumeratePaths(index, currencyIn, currencyOut)
157
+ export async function findBestUniswapRoute(client, currencyIn, currencyOut, amountIn, maxPaths = MAX_QUOTE_PATHS, index) {
158
+ const poolIndex = index ?? (await getUniswapPoolIndex(client));
159
+ // Sort shortest-first so 1-hop direct pools are always preferred, then cap
160
+ // simulateContract calls. Each call is one Cloudflare Workers subrequest.
161
+ const candidatePaths = enumeratePaths(poolIndex, currencyIn, currencyOut)
136
162
  .sort((a, b) => a.length - b.length)
137
- .slice(0, MAX_QUOTE_PATHS);
163
+ .slice(0, Math.max(0, maxPaths));
138
164
  // Quote every candidate path concurrently; failed quotes (e.g. uninitialized
139
165
  // pools or insufficient liquidity) are dropped rather than aborting the rest.
140
166
  const quotes = await Promise.allSettled(candidatePaths.map(async (pools) => ({
@@ -169,7 +195,7 @@ export async function findBestUniswapRoute(client, currencyIn, currencyOut, amou
169
195
  return {
170
196
  route: best.route,
171
197
  amountOut: best.amountOut,
172
- indexSource: index.source,
198
+ indexSource: poolIndex.source,
173
199
  };
174
200
  }
175
201
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"uniswap-path-router.js","sourceRoot":"","sources":["../../../src/services/uniswap-path-router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uniswap-path-router.js","sourceRoot":"","sources":["../../../src/services/uniswap-path-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Uniswap v3 path routing: BFS over the hub-pool index and QuoterV2 selection.
3
+ */
4
+ import { type Hex, type PublicClient } from "viem";
5
+ import { type UniswapV3Pool } from "../config/uniswap.js";
6
+ import { type UniswapV3PoolIndex } from "./uniswap-v3-pool-discovery.js";
7
+ /** Best quoted v3 route between two tokens. Pools are in hop order. */
8
+ export type UniswapV3SwapRoute = {
9
+ tokenIn: `0x${string}`;
10
+ tokenOut: `0x${string}`;
11
+ pools: UniswapV3Pool[];
12
+ hops: number;
13
+ };
14
+ /** Token on the other side of a canonical v3 pool. */
15
+ export declare function otherV3Token(pool: UniswapV3Pool, token: `0x${string}`): `0x${string}`;
16
+ /** Packed v3 path: token, fee, token, fee, token. */
17
+ export declare function encodeV3Path(tokenIn: `0x${string}`, pools: UniswapV3Pool[]): Hex;
18
+ /**
19
+ * SwapRouter02 calldata. Single- and multi-hop swaps are wrapped in
20
+ * `multicall(deadline, bytes[])` because exactInput has no deadline field.
21
+ */
22
+ export declare function buildSwapRouter02Calldata(args: {
23
+ tokenIn: `0x${string}`;
24
+ recipient: `0x${string}`;
25
+ amountIn: bigint;
26
+ amountOutMin: bigint;
27
+ deadline: bigint;
28
+ pools: UniswapV3Pool[];
29
+ }): Hex;
30
+ export declare function enumerateV3Paths(index: UniswapV3PoolIndex, tokenIn: `0x${string}`, tokenOut: `0x${string}`): UniswapV3Pool[][];
31
+ export declare function countV3CandidatePaths(index: UniswapV3PoolIndex, tokenIn: `0x${string}`, tokenOut: `0x${string}`): number;
32
+ /**
33
+ * Quote candidate v3 paths and return the highest output.
34
+ * @param maxPaths - Cap on simulateContract calls for this venue
35
+ */
36
+ export declare function findBestV3Route(client: PublicClient, tokenIn: `0x${string}`, tokenOut: `0x${string}`, amountIn: bigint, maxPaths: number, index?: UniswapV3PoolIndex): Promise<{
37
+ route: UniswapV3SwapRoute;
38
+ amountOut: bigint;
39
+ indexSource: "onchain";
40
+ } | null>;
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Uniswap v3 path routing: BFS over the hub-pool index and QuoterV2 selection.
3
+ */
4
+ import { encodeFunctionData, encodePacked } from "viem";
5
+ import { swapRouter02Abi, v3QuoterAbi } from "../abis/uniswap-v3.js";
6
+ import { UNISWAP_V3 } from "../config/uniswap.js";
7
+ import { getUniswapV3PoolIndex, poolsBetweenV3, } from "./uniswap-v3-pool-discovery.js";
8
+ const MAX_POOLS = 3;
9
+ /** Token on the other side of a canonical v3 pool. */
10
+ export function otherV3Token(pool, token) {
11
+ const current = token.toLowerCase();
12
+ if (pool.token0.toLowerCase() === current)
13
+ return pool.token1;
14
+ if (pool.token1.toLowerCase() === current)
15
+ return pool.token0;
16
+ throw new Error("Token is not in the Uniswap v3 pool.");
17
+ }
18
+ /** Packed v3 path: token, fee, token, fee, token. */
19
+ export function encodeV3Path(tokenIn, pools) {
20
+ const types = ["address"];
21
+ const values = [tokenIn];
22
+ let current = tokenIn;
23
+ for (const pool of pools) {
24
+ const out = otherV3Token(pool, current);
25
+ types.push("uint24", "address");
26
+ values.push(pool.fee, out);
27
+ current = out;
28
+ }
29
+ return encodePacked(types, values);
30
+ }
31
+ /**
32
+ * SwapRouter02 calldata. Single- and multi-hop swaps are wrapped in
33
+ * `multicall(deadline, bytes[])` because exactInput has no deadline field.
34
+ */
35
+ export function buildSwapRouter02Calldata(args) {
36
+ const { pools, tokenIn, recipient, amountIn, amountOutMin, deadline } = args;
37
+ if (pools.length === 0) {
38
+ throw new Error("Uniswap v3 route has no pools.");
39
+ }
40
+ const inner = pools.length === 1
41
+ ? encodeFunctionData({
42
+ abi: swapRouter02Abi,
43
+ functionName: "exactInputSingle",
44
+ args: [
45
+ {
46
+ tokenIn,
47
+ tokenOut: otherV3Token(pools[0], tokenIn),
48
+ fee: pools[0].fee,
49
+ recipient,
50
+ amountIn,
51
+ amountOutMinimum: amountOutMin,
52
+ sqrtPriceLimitX96: 0n,
53
+ },
54
+ ],
55
+ })
56
+ : encodeFunctionData({
57
+ abi: swapRouter02Abi,
58
+ functionName: "exactInput",
59
+ args: [
60
+ {
61
+ path: encodeV3Path(tokenIn, pools),
62
+ recipient,
63
+ amountIn,
64
+ amountOutMinimum: amountOutMin,
65
+ },
66
+ ],
67
+ });
68
+ return encodeFunctionData({
69
+ abi: swapRouter02Abi,
70
+ functionName: "multicall",
71
+ args: [deadline, [inner]],
72
+ });
73
+ }
74
+ export function enumerateV3Paths(index, tokenIn, tokenOut) {
75
+ const start = tokenIn.toLowerCase();
76
+ const goal = tokenOut.toLowerCase();
77
+ if (start === goal) {
78
+ return [];
79
+ }
80
+ const results = [];
81
+ const queue = [
82
+ { token: start, pools: [], visited: new Set([start]) },
83
+ ];
84
+ while (queue.length > 0) {
85
+ const node = queue.shift();
86
+ if (node.pools.length >= MAX_POOLS) {
87
+ continue;
88
+ }
89
+ const neighbors = index.adjacency.get(node.token);
90
+ if (!neighbors) {
91
+ continue;
92
+ }
93
+ for (const neighbor of neighbors) {
94
+ if (node.visited.has(neighbor)) {
95
+ continue;
96
+ }
97
+ for (const pool of poolsBetweenV3(index, node.token, neighbor)) {
98
+ const nextPools = [...node.pools, pool];
99
+ if (neighbor === goal) {
100
+ results.push(nextPools);
101
+ continue;
102
+ }
103
+ if (nextPools.length < MAX_POOLS) {
104
+ queue.push({
105
+ token: neighbor,
106
+ pools: nextPools,
107
+ visited: new Set([...node.visited, neighbor]),
108
+ });
109
+ }
110
+ }
111
+ }
112
+ }
113
+ return results;
114
+ }
115
+ export function countV3CandidatePaths(index, tokenIn, tokenOut) {
116
+ return enumerateV3Paths(index, tokenIn, tokenOut).length;
117
+ }
118
+ async function quoteV3Path(client, tokenIn, pools, amountIn) {
119
+ if (pools.length === 0) {
120
+ return 0n;
121
+ }
122
+ if (pools.length === 1) {
123
+ const pool = pools[0];
124
+ const { result } = await client.simulateContract({
125
+ address: UNISWAP_V3.quoterV2,
126
+ abi: v3QuoterAbi,
127
+ functionName: "quoteExactInputSingle",
128
+ args: [
129
+ {
130
+ tokenIn,
131
+ tokenOut: otherV3Token(pool, tokenIn),
132
+ amountIn,
133
+ fee: pool.fee,
134
+ sqrtPriceLimitX96: 0n,
135
+ },
136
+ ],
137
+ });
138
+ return result[0];
139
+ }
140
+ const { result } = await client.simulateContract({
141
+ address: UNISWAP_V3.quoterV2,
142
+ abi: v3QuoterAbi,
143
+ functionName: "quoteExactInput",
144
+ args: [encodeV3Path(tokenIn, pools), amountIn],
145
+ });
146
+ return result[0];
147
+ }
148
+ /**
149
+ * Quote candidate v3 paths and return the highest output.
150
+ * @param maxPaths - Cap on simulateContract calls for this venue
151
+ */
152
+ export async function findBestV3Route(client, tokenIn, tokenOut, amountIn, maxPaths, index) {
153
+ const poolIndex = index ?? (await getUniswapV3PoolIndex(client));
154
+ const candidatePaths = enumerateV3Paths(poolIndex, tokenIn, tokenOut)
155
+ .sort((a, b) => a.length - b.length)
156
+ .slice(0, Math.max(0, maxPaths));
157
+ const quotes = await Promise.allSettled(candidatePaths.map(async (pools) => ({
158
+ pools,
159
+ amountOut: await quoteV3Path(client, tokenIn, pools, amountIn),
160
+ })));
161
+ let best = null;
162
+ for (const quote of quotes) {
163
+ if (quote.status !== "fulfilled" || quote.value.amountOut <= 0n) {
164
+ continue;
165
+ }
166
+ if (!best || quote.value.amountOut > best.amountOut) {
167
+ best = {
168
+ amountOut: quote.value.amountOut,
169
+ route: {
170
+ tokenIn,
171
+ tokenOut,
172
+ pools: quote.value.pools,
173
+ hops: quote.value.pools.length,
174
+ },
175
+ };
176
+ }
177
+ }
178
+ if (!best) {
179
+ return null;
180
+ }
181
+ return { ...best, indexSource: poolIndex.source };
182
+ }
183
+ //# sourceMappingURL=uniswap-v3-path-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniswap-v3-path-router.js","sourceRoot":"","sources":["../../../src/services/uniswap-v3-path-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Uniswap v3 pool discovery: on-chain hub probing via the Celo v3 factory.
3
+ * Hub-to-hub pools only — there is no v3 subgraph in this SDK.
4
+ */
5
+ import type { PublicClient } from "viem";
6
+ import { type UniswapV3Pool } from "../config/uniswap.js";
7
+ /** One edge in the v3 pool routing graph. */
8
+ export type UniswapV3PoolEdge = {
9
+ pool: UniswapV3Pool;
10
+ tokenA: `0x${string}`;
11
+ tokenB: `0x${string}`;
12
+ };
13
+ /** Cached routing graph of v3 hub pools on Celo mainnet. */
14
+ export type UniswapV3PoolIndex = {
15
+ edges: UniswapV3PoolEdge[];
16
+ adjacency: Map<string, Set<string>>;
17
+ /** Sorted pair key (`tokenLo|tokenHi`) → pools across fee tiers. */
18
+ poolsByPair: Map<string, UniswapV3Pool[]>;
19
+ source: "onchain";
20
+ fetchedAt: number;
21
+ };
22
+ /**
23
+ * Load or refresh the v3 hub-pool index.
24
+ * @param client - Celo public client for factory probing
25
+ * @param options.forceRefresh - Bypass TTL cache when true
26
+ */
27
+ export declare function getUniswapV3PoolIndex(client: PublicClient, options?: {
28
+ forceRefresh?: boolean;
29
+ }): Promise<UniswapV3PoolIndex>;
30
+ /** All v3 pools connecting two tokens in a cached index. */
31
+ export declare function poolsBetweenV3(index: UniswapV3PoolIndex, tokenA: `0x${string}`, tokenB: `0x${string}`): UniswapV3Pool[];
32
+ /** Reset cached v3 index (for tests). */
33
+ export declare function resetUniswapV3PoolIndexCache(): void;
@@ -0,0 +1,141 @@
1
+ import { uniswapV3FactoryAbi, uniswapV3PoolAbi } from "../abis/uniswap-v3.js";
2
+ import { UNISWAP_HUB_CURRENCIES, UNISWAP_POOL_CACHE_TTL_MS, UNISWAP_V3, UNISWAP_V3_FEE_TIERS, UNISWAP_V4, } from "../config/uniswap.js";
3
+ const ZERO_ADDRESS = UNISWAP_V4.nativeCurrency.toLowerCase();
4
+ const MULTICALL_CHUNK_SIZE = 100;
5
+ let cachedIndex = null;
6
+ function pairKey(a, b) {
7
+ const lo = a.toLowerCase();
8
+ const hi = b.toLowerCase();
9
+ return lo < hi ? `${lo}|${hi}` : `${hi}|${lo}`;
10
+ }
11
+ function chunk(items, size) {
12
+ const chunks = [];
13
+ for (let i = 0; i < items.length; i += size) {
14
+ chunks.push(items.slice(i, i + size));
15
+ }
16
+ return chunks;
17
+ }
18
+ function sortTokens(a, b) {
19
+ return a.toLowerCase() < b.toLowerCase() ? [a, b] : [b, a];
20
+ }
21
+ function buildPoolIndex(pools) {
22
+ const edges = [];
23
+ const adjacency = new Map();
24
+ const poolsByPair = new Map();
25
+ for (const pool of pools) {
26
+ const tokenA = pool.token0.toLowerCase();
27
+ const tokenB = pool.token1.toLowerCase();
28
+ edges.push({ pool, tokenA, tokenB });
29
+ const key = pairKey(tokenA, tokenB);
30
+ const existing = poolsByPair.get(key) ?? [];
31
+ existing.push(pool);
32
+ poolsByPair.set(key, existing);
33
+ for (const [from, to] of [
34
+ [tokenA, tokenB],
35
+ [tokenB, tokenA],
36
+ ]) {
37
+ const neighbors = adjacency.get(from) ?? new Set();
38
+ neighbors.add(to);
39
+ adjacency.set(from, neighbors);
40
+ }
41
+ }
42
+ return {
43
+ edges,
44
+ adjacency,
45
+ poolsByPair,
46
+ source: "onchain",
47
+ fetchedAt: Date.now(),
48
+ };
49
+ }
50
+ async function probeHubPools(client) {
51
+ const hubs = UNISWAP_HUB_CURRENCIES.filter((currency) => currency.toLowerCase() !== ZERO_ADDRESS);
52
+ const candidates = [];
53
+ for (let i = 0; i < hubs.length; i++) {
54
+ for (let j = i + 1; j < hubs.length; j++) {
55
+ const [token0, token1] = sortTokens(hubs[i], hubs[j]);
56
+ for (const fee of UNISWAP_V3_FEE_TIERS) {
57
+ candidates.push({ token0, token1, fee });
58
+ }
59
+ }
60
+ }
61
+ const discovered = [];
62
+ for (const batch of chunk(candidates, MULTICALL_CHUNK_SIZE)) {
63
+ const results = await client.multicall({
64
+ allowFailure: true,
65
+ contracts: batch.map((candidate) => ({
66
+ address: UNISWAP_V3.factory,
67
+ abi: uniswapV3FactoryAbi,
68
+ functionName: "getPool",
69
+ args: [candidate.token0, candidate.token1, candidate.fee],
70
+ })),
71
+ });
72
+ for (let i = 0; i < batch.length; i++) {
73
+ const result = results[i];
74
+ const candidate = batch[i];
75
+ if (result?.status !== "success") {
76
+ continue;
77
+ }
78
+ const address = result.result;
79
+ if (address.toLowerCase() === ZERO_ADDRESS) {
80
+ continue;
81
+ }
82
+ discovered.push({
83
+ address,
84
+ pool: {
85
+ token0: candidate.token0,
86
+ token1: candidate.token1,
87
+ fee: candidate.fee,
88
+ },
89
+ });
90
+ }
91
+ }
92
+ if (discovered.length === 0) {
93
+ return [];
94
+ }
95
+ const withLiquidity = [];
96
+ for (const batch of chunk(discovered, MULTICALL_CHUNK_SIZE)) {
97
+ const results = await client.multicall({
98
+ allowFailure: true,
99
+ contracts: batch.map((entry) => ({
100
+ address: entry.address,
101
+ abi: uniswapV3PoolAbi,
102
+ functionName: "liquidity",
103
+ })),
104
+ });
105
+ for (let i = 0; i < batch.length; i++) {
106
+ const result = results[i];
107
+ if (result?.status !== "success") {
108
+ continue;
109
+ }
110
+ const liquidity = result.result;
111
+ if (liquidity > 0n) {
112
+ withLiquidity.push(batch[i].pool);
113
+ }
114
+ }
115
+ }
116
+ return withLiquidity;
117
+ }
118
+ /**
119
+ * Load or refresh the v3 hub-pool index.
120
+ * @param client - Celo public client for factory probing
121
+ * @param options.forceRefresh - Bypass TTL cache when true
122
+ */
123
+ export async function getUniswapV3PoolIndex(client, options) {
124
+ const now = Date.now();
125
+ if (!options?.forceRefresh &&
126
+ cachedIndex &&
127
+ now - cachedIndex.fetchedAt < UNISWAP_POOL_CACHE_TTL_MS) {
128
+ return cachedIndex;
129
+ }
130
+ cachedIndex = buildPoolIndex(await probeHubPools(client));
131
+ return cachedIndex;
132
+ }
133
+ /** All v3 pools connecting two tokens in a cached index. */
134
+ export function poolsBetweenV3(index, tokenA, tokenB) {
135
+ return index.poolsByPair.get(pairKey(tokenA, tokenB)) ?? [];
136
+ }
137
+ /** Reset cached v3 index (for tests). */
138
+ export function resetUniswapV3PoolIndexCache() {
139
+ cachedIndex = null;
140
+ }
141
+ //# sourceMappingURL=uniswap-v3-pool-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniswap-v3-pool-discovery.js","sourceRoot":"","sources":["../../../src/services/uniswap-v3-pool-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Pick the better of the best Uniswap v3 path and the best Uniswap v4 path.
3
+ * A quote simulates at most MAX_QUOTE_PATHS paths across both venues.
4
+ */
5
+ import type { PublicClient } from "viem";
6
+ import type { UniswapProtocol } from "../config/uniswap.js";
7
+ import { type UniswapV3SwapRoute } from "./uniswap-v3-path-router.js";
8
+ import { type UniswapSwapRoute } from "./uniswap-path-router.js";
9
+ export type UniswapQuotedRoute = {
10
+ protocol: "uniswap_v4";
11
+ amountOut: bigint;
12
+ indexSource: string;
13
+ hops: number;
14
+ route: UniswapSwapRoute;
15
+ } | {
16
+ protocol: "uniswap_v3";
17
+ amountOut: bigint;
18
+ indexSource: string;
19
+ hops: number;
20
+ route: UniswapV3SwapRoute;
21
+ };
22
+ /**
23
+ * Quote v3 and v4, or only the pinned venue.
24
+ * @returns The winning route, or null when every attempted venue has no liquidity
25
+ */
26
+ export declare function findBestUniswapQuote(client: PublicClient, currencyIn: `0x${string}`, currencyOut: `0x${string}`, amountIn: bigint, options?: {
27
+ protocol?: UniswapProtocol;
28
+ }): Promise<UniswapQuotedRoute | null>;