@andrewkimjoseph/celina-sdk 0.2.5 → 0.2.7

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 (37) hide show
  1. package/build/abis/permit2.d.ts +43 -0
  2. package/build/abis/permit2.js +30 -0
  3. package/build/abis/permit2.js.map +1 -0
  4. package/build/abis/uniswap-state-view.d.ts +34 -0
  5. package/build/abis/uniswap-state-view.js +22 -0
  6. package/build/abis/uniswap-state-view.js.map +1 -0
  7. package/build/abis/uniswap-v4-quoter.d.ts +86 -0
  8. package/build/abis/uniswap-v4-quoter.js +64 -0
  9. package/build/abis/uniswap-v4-quoter.js.map +1 -0
  10. package/build/abis/universal-router.d.ts +16 -0
  11. package/build/abis/universal-router.js +14 -0
  12. package/build/abis/universal-router.js.map +1 -0
  13. package/build/clients/uniswap-sdk.d.ts +4 -0
  14. package/build/clients/uniswap-sdk.js +9 -0
  15. package/build/clients/uniswap-sdk.js.map +1 -0
  16. package/build/config/uniswap.d.ts +36 -0
  17. package/build/config/uniswap.js +67 -0
  18. package/build/config/uniswap.js.map +1 -0
  19. package/build/index.d.ts +4 -0
  20. package/build/index.js +2 -0
  21. package/build/index.js.map +1 -1
  22. package/build/services/mento-fx.service.d.ts +2 -1
  23. package/build/services/mento-fx.service.js +16 -3
  24. package/build/services/mento-fx.service.js.map +1 -1
  25. package/build/services/uniswap-path-router.d.ts +22 -0
  26. package/build/services/uniswap-path-router.js +155 -0
  27. package/build/services/uniswap-path-router.js.map +1 -0
  28. package/build/services/uniswap-pool-discovery.d.ts +21 -0
  29. package/build/services/uniswap-pool-discovery.js +183 -0
  30. package/build/services/uniswap-pool-discovery.js.map +1 -0
  31. package/build/services/uniswap.service.d.ts +53 -0
  32. package/build/services/uniswap.service.js +317 -0
  33. package/build/services/uniswap.service.js.map +1 -0
  34. package/build/utils/erc20-allowance-storage.d.ts +1 -1
  35. package/build/utils/erc20-allowance-storage.js +7 -0
  36. package/build/utils/erc20-allowance-storage.js.map +1 -1
  37. package/package.json +5 -1
@@ -0,0 +1,155 @@
1
+ import { v4QuoterAbi } from "../abis/uniswap-v4-quoter.js";
2
+ import { normalizeUniswapPoolKey, UNISWAP_V4, } from "../config/uniswap.js";
3
+ import { getUniswapPoolIndex, } from "./uniswap-pool-discovery.js";
4
+ const MAX_HOPS = 2;
5
+ function otherToken(poolKey, currency) {
6
+ const c = currency.toLowerCase();
7
+ if (poolKey.currency0.toLowerCase() === c)
8
+ return poolKey.currency1;
9
+ if (poolKey.currency1.toLowerCase() === c)
10
+ return poolKey.currency0;
11
+ return null;
12
+ }
13
+ function buildPathKeys(pools, currencyIn) {
14
+ let current = currencyIn;
15
+ const pathKeys = [];
16
+ for (const poolKey of pools) {
17
+ const out = otherToken(poolKey, current);
18
+ if (!out) {
19
+ throw new Error("Invalid swap path for Uniswap v4 pools.");
20
+ }
21
+ pathKeys.push({
22
+ intermediateCurrency: out,
23
+ fee: poolKey.fee,
24
+ tickSpacing: poolKey.tickSpacing,
25
+ hooks: poolKey.hooks,
26
+ hookData: "0x",
27
+ });
28
+ current = out;
29
+ }
30
+ return pathKeys;
31
+ }
32
+ function enumeratePaths(index, currencyIn, currencyOut) {
33
+ const start = currencyIn.toLowerCase();
34
+ const goal = currencyOut.toLowerCase();
35
+ if (start === goal) {
36
+ return [];
37
+ }
38
+ const results = [];
39
+ const queue = [{ currency: start, pools: [], visited: new Set([start]) }];
40
+ while (queue.length > 0) {
41
+ const node = queue.shift();
42
+ if (node.pools.length >= MAX_HOPS + 1) {
43
+ continue;
44
+ }
45
+ const neighbors = index.adjacency.get(node.currency);
46
+ if (!neighbors) {
47
+ continue;
48
+ }
49
+ for (const neighbor of neighbors) {
50
+ if (node.visited.has(neighbor)) {
51
+ continue;
52
+ }
53
+ const poolKey = index.edges.find((edge) => {
54
+ const a = edge.tokenA.toLowerCase();
55
+ const b = edge.tokenB.toLowerCase();
56
+ return ((a === node.currency && b === neighbor) ||
57
+ (a === neighbor && b === node.currency));
58
+ })?.poolKey;
59
+ if (!poolKey) {
60
+ continue;
61
+ }
62
+ const nextPools = [...node.pools, poolKey];
63
+ if (neighbor === goal) {
64
+ results.push(nextPools);
65
+ continue;
66
+ }
67
+ if (nextPools.length <= MAX_HOPS) {
68
+ queue.push({
69
+ currency: neighbor,
70
+ pools: nextPools,
71
+ visited: new Set([...node.visited, neighbor]),
72
+ });
73
+ }
74
+ }
75
+ }
76
+ return results;
77
+ }
78
+ async function quotePath(client, currencyIn, pools, amountIn) {
79
+ if (pools.length === 0) {
80
+ return 0n;
81
+ }
82
+ if (pools.length === 1) {
83
+ const poolKey = normalizeUniswapPoolKey(pools[0]);
84
+ const zeroForOne = currencyIn.toLowerCase() === poolKey.currency0.toLowerCase();
85
+ const { result } = await client.simulateContract({
86
+ address: UNISWAP_V4.v4Quoter,
87
+ abi: v4QuoterAbi,
88
+ functionName: "quoteExactInputSingle",
89
+ args: [
90
+ {
91
+ poolKey,
92
+ zeroForOne,
93
+ exactAmount: amountIn,
94
+ hookData: "0x",
95
+ },
96
+ ],
97
+ });
98
+ return result[0];
99
+ }
100
+ const pathKeys = buildPathKeys(pools, currencyIn);
101
+ const { result } = await client.simulateContract({
102
+ address: UNISWAP_V4.v4Quoter,
103
+ abi: v4QuoterAbi,
104
+ functionName: "quoteExactInput",
105
+ args: [
106
+ {
107
+ exactCurrency: currencyIn,
108
+ path: pathKeys,
109
+ exactAmount: amountIn,
110
+ },
111
+ ],
112
+ });
113
+ return result[0];
114
+ }
115
+ export async function findBestUniswapRoute(client, currencyIn, currencyOut, amountIn) {
116
+ const index = await getUniswapPoolIndex(client);
117
+ const candidatePaths = enumeratePaths(index, currencyIn, currencyOut);
118
+ let best = null;
119
+ for (const pools of candidatePaths) {
120
+ try {
121
+ const amountOut = await quotePath(client, currencyIn, pools, amountIn);
122
+ if (amountOut <= 0n) {
123
+ continue;
124
+ }
125
+ if (!best || amountOut > best.amountOut) {
126
+ best = {
127
+ amountOut,
128
+ route: {
129
+ currencyIn,
130
+ currencyOut,
131
+ pools,
132
+ pathKeys: buildPathKeys(pools, currencyIn),
133
+ hops: pools.length,
134
+ },
135
+ };
136
+ }
137
+ }
138
+ catch {
139
+ // skip paths that fail to quote
140
+ }
141
+ }
142
+ if (!best) {
143
+ return null;
144
+ }
145
+ return {
146
+ route: best.route,
147
+ amountOut: best.amountOut,
148
+ indexSource: index.source,
149
+ };
150
+ }
151
+ export function applySlippage(amountOut, slippagePercent) {
152
+ const bps = BigInt(Math.round(slippagePercent * 100));
153
+ return (amountOut * (10000n - bps)) / 10000n;
154
+ }
155
+ //# sourceMappingURL=uniswap-path-router.js.map
@@ -0,0 +1 @@
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,21 @@
1
+ import { type PublicClient } from "viem";
2
+ import { type UniswapPoolKey } from "../config/uniswap.js";
3
+ export type UniswapPoolEdge = {
4
+ poolKey: UniswapPoolKey;
5
+ tokenA: `0x${string}`;
6
+ tokenB: `0x${string}`;
7
+ };
8
+ export type UniswapPoolIndex = {
9
+ edges: UniswapPoolEdge[];
10
+ /** currency address (lowercase) → neighbor currencies */
11
+ adjacency: Map<string, Set<string>>;
12
+ source: "subgraph" | "onchain";
13
+ fetchedAt: number;
14
+ };
15
+ export declare function computeUniswapPoolId(poolKey: UniswapPoolKey): `0x${string}`;
16
+ export declare function getUniswapPoolIndex(client: PublicClient, options?: {
17
+ forceRefresh?: boolean;
18
+ }): Promise<UniswapPoolIndex>;
19
+ export declare function findPoolBetween(index: UniswapPoolIndex, tokenA: `0x${string}`, tokenB: `0x${string}`): UniswapPoolKey | null;
20
+ /** Reset cached index (for tests). */
21
+ export declare function resetUniswapPoolIndexCache(): void;
@@ -0,0 +1,183 @@
1
+ import { encodeAbiParameters, keccak256, parseAbiParameters, } from "viem";
2
+ import { stateViewAbi } from "../abis/uniswap-state-view.js";
3
+ import { normalizeUniswapPoolKey, UNISWAP_DEFAULT_TICK_SPACING, UNISWAP_FEE_TIERS, UNISWAP_HUB_CURRENCIES, UNISWAP_POOL_CACHE_TTL_MS, UNISWAP_SUBGRAPH_URL, UNISWAP_V4, } from "../config/uniswap.js";
4
+ let cachedIndex = null;
5
+ export function computeUniswapPoolId(poolKey) {
6
+ const normalized = normalizeUniswapPoolKey(poolKey);
7
+ return keccak256(encodeAbiParameters(parseAbiParameters("address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks"), [
8
+ normalized.currency0,
9
+ normalized.currency1,
10
+ normalized.fee,
11
+ normalized.tickSpacing,
12
+ normalized.hooks,
13
+ ]));
14
+ }
15
+ function addEdge(edges, adjacency, poolKey) {
16
+ const normalized = normalizeUniswapPoolKey(poolKey);
17
+ const a = normalized.currency0.toLowerCase();
18
+ const b = normalized.currency1.toLowerCase();
19
+ if (edges.some((edge) => edge.poolKey === normalized)) {
20
+ return;
21
+ }
22
+ edges.push({
23
+ poolKey: normalized,
24
+ tokenA: normalized.currency0,
25
+ tokenB: normalized.currency1,
26
+ });
27
+ if (!adjacency.has(a))
28
+ adjacency.set(a, new Set());
29
+ if (!adjacency.has(b))
30
+ adjacency.set(b, new Set());
31
+ adjacency.get(a).add(b);
32
+ adjacency.get(b).add(a);
33
+ }
34
+ async function fetchSubgraphPools() {
35
+ try {
36
+ const response = await fetch(UNISWAP_SUBGRAPH_URL, {
37
+ method: "POST",
38
+ headers: { "Content-Type": "application/json" },
39
+ body: JSON.stringify({
40
+ query: `{
41
+ pools(first: 500, orderBy: totalValueLockedUSD, orderDirection: desc) {
42
+ feeTier
43
+ tickSpacing
44
+ hooks
45
+ token0 { id }
46
+ token1 { id }
47
+ }
48
+ }`,
49
+ }),
50
+ });
51
+ if (!response.ok) {
52
+ return null;
53
+ }
54
+ const json = (await response.json());
55
+ const pools = json.data?.pools;
56
+ if (!pools?.length) {
57
+ return null;
58
+ }
59
+ const edges = [];
60
+ const adjacency = new Map();
61
+ for (const pool of pools) {
62
+ const poolKey = {
63
+ currency0: pool.token0.id,
64
+ currency1: pool.token1.id,
65
+ fee: Number(pool.feeTier),
66
+ tickSpacing: Number(pool.tickSpacing),
67
+ hooks: (pool.hooks || UNISWAP_V4.zeroHooks),
68
+ };
69
+ addEdge(edges, adjacency, poolKey);
70
+ }
71
+ return edges;
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ }
77
+ async function probePoolOnChain(client, currencyA, currencyB, fee, tickSpacing) {
78
+ const poolKey = normalizeUniswapPoolKey({
79
+ currency0: currencyA,
80
+ currency1: currencyB,
81
+ fee,
82
+ tickSpacing,
83
+ hooks: UNISWAP_V4.zeroHooks,
84
+ });
85
+ const poolId = computeUniswapPoolId(poolKey);
86
+ try {
87
+ const [slot0, liquidity] = await Promise.all([
88
+ client.readContract({
89
+ address: UNISWAP_V4.stateView,
90
+ abi: stateViewAbi,
91
+ functionName: "getSlot0",
92
+ args: [poolId],
93
+ }),
94
+ client.readContract({
95
+ address: UNISWAP_V4.stateView,
96
+ abi: stateViewAbi,
97
+ functionName: "getLiquidity",
98
+ args: [poolId],
99
+ }),
100
+ ]);
101
+ if (slot0[0] > 0n && liquidity > 0n) {
102
+ return poolKey;
103
+ }
104
+ }
105
+ catch {
106
+ // pool not initialized
107
+ }
108
+ return null;
109
+ }
110
+ async function buildOnChainIndex(client) {
111
+ const edges = [];
112
+ const adjacency = new Map();
113
+ const hubs = [...UNISWAP_HUB_CURRENCIES];
114
+ for (let i = 0; i < hubs.length; i++) {
115
+ for (let j = i + 1; j < hubs.length; j++) {
116
+ const [currency0, currency1] = hubs[i].toLowerCase() < hubs[j].toLowerCase()
117
+ ? [hubs[i], hubs[j]]
118
+ : [hubs[j], hubs[i]];
119
+ for (const fee of UNISWAP_FEE_TIERS) {
120
+ const tickSpacing = UNISWAP_DEFAULT_TICK_SPACING[fee] ??
121
+ UNISWAP_DEFAULT_TICK_SPACING[3000];
122
+ const poolKey = await probePoolOnChain(client, currency0, currency1, fee, tickSpacing);
123
+ if (poolKey) {
124
+ addEdge(edges, adjacency, poolKey);
125
+ }
126
+ }
127
+ }
128
+ }
129
+ return {
130
+ edges,
131
+ adjacency,
132
+ source: "onchain",
133
+ fetchedAt: Date.now(),
134
+ };
135
+ }
136
+ export async function getUniswapPoolIndex(client, options) {
137
+ const now = Date.now();
138
+ if (!options?.forceRefresh &&
139
+ cachedIndex &&
140
+ now - cachedIndex.fetchedAt < UNISWAP_POOL_CACHE_TTL_MS) {
141
+ return cachedIndex;
142
+ }
143
+ const subgraphEdges = await fetchSubgraphPools();
144
+ if (subgraphEdges?.length) {
145
+ const adjacency = new Map();
146
+ for (const edge of subgraphEdges) {
147
+ const a = edge.tokenA.toLowerCase();
148
+ const b = edge.tokenB.toLowerCase();
149
+ if (!adjacency.has(a))
150
+ adjacency.set(a, new Set());
151
+ if (!adjacency.has(b))
152
+ adjacency.set(b, new Set());
153
+ adjacency.get(a).add(b);
154
+ adjacency.get(b).add(a);
155
+ }
156
+ cachedIndex = {
157
+ edges: subgraphEdges,
158
+ adjacency,
159
+ source: "subgraph",
160
+ fetchedAt: now,
161
+ };
162
+ return cachedIndex;
163
+ }
164
+ cachedIndex = await buildOnChainIndex(client);
165
+ return cachedIndex;
166
+ }
167
+ export function findPoolBetween(index, tokenA, tokenB) {
168
+ const a = tokenA.toLowerCase();
169
+ const b = tokenB.toLowerCase();
170
+ for (const edge of index.edges) {
171
+ const e0 = edge.tokenA.toLowerCase();
172
+ const e1 = edge.tokenB.toLowerCase();
173
+ if ((e0 === a && e1 === b) || (e0 === b && e1 === a)) {
174
+ return edge.poolKey;
175
+ }
176
+ }
177
+ return null;
178
+ }
179
+ /** Reset cached index (for tests). */
180
+ export function resetUniswapPoolIndexCache() {
181
+ cachedIndex = null;
182
+ }
183
+ //# sourceMappingURL=uniswap-pool-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniswap-pool-discovery.js","sourceRoot":"","sources":["../../src/services/uniswap-pool-discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { CeloClientFactory } from "../clients/celo-client.js";
2
+ import { type SerializedPreparedFlow } from "../types/prepared.js";
3
+ export interface UniswapSwapParams {
4
+ slippageTolerance?: number;
5
+ deadlineMinutes?: number;
6
+ recipient?: `0x${string}`;
7
+ }
8
+ export declare class UniswapService {
9
+ private readonly clientFactory;
10
+ private readonly tokenService;
11
+ constructor(clientFactory: CeloClientFactory);
12
+ private resolvePair;
13
+ private baseQuoteFields;
14
+ private buildSwapRoute;
15
+ private buildUniversalRouterCalldata;
16
+ private getApprovalSteps;
17
+ private estimateCallGas;
18
+ private estimateSwapGasWithAllowance;
19
+ getSwapQuote(tokenIn: string, tokenOut: string, amount: string): Promise<{
20
+ route: {
21
+ pools: import("../config/uniswap.js").UniswapPoolKey[];
22
+ };
23
+ protocol: "uniswap_v4";
24
+ network: "mainnet";
25
+ tokenIn: string;
26
+ tokenOut: string;
27
+ amountIn: string;
28
+ expectedOut: string;
29
+ routeHops: number;
30
+ indexSource: string | undefined;
31
+ }>;
32
+ estimateSwap(from: `0x${string}`, tokenIn: string, tokenOut: string, amount: string, params?: UniswapSwapParams): Promise<{
33
+ from: `0x${string}`;
34
+ recipient: `0x${string}`;
35
+ amountOutMin: string;
36
+ approvalStepsNeeded: number;
37
+ approvalGas: string[];
38
+ swapGas: string | undefined;
39
+ swapGasEstimated: boolean;
40
+ slippageTolerance: number;
41
+ deadline: string;
42
+ deadlineMinutes: number;
43
+ protocol: "uniswap_v4";
44
+ network: "mainnet";
45
+ tokenIn: string;
46
+ tokenOut: string;
47
+ amountIn: string;
48
+ expectedOut: string;
49
+ routeHops: number;
50
+ indexSource: string | undefined;
51
+ }>;
52
+ prepareSwap(from: `0x${string}`, tokenIn: string, tokenOut: string, amount: string, params?: UniswapSwapParams): Promise<SerializedPreparedFlow>;
53
+ }