@steerprotocol/liquidity-meter 1.0.0 → 2.0.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.
- package/README.md +18 -56
- package/bin/liquidity-depth.js +887 -0
- package/package.json +23 -32
- package/src/api.js +490 -0
- package/src/depth.js +492 -0
- package/src/index.js +6 -0
- package/src/prices.js +188 -0
- package/src/uniswapv3-subgraph.js +141 -0
- package/src/viem-onchain.js +233 -0
- package/src/withdraw.js +333 -0
- package/templates/README.md +37 -0
- package/templates/pools_minimal.csv +3 -0
- package/templates/pools_with_vault.csv +3 -0
- package/dist/adapters/onchain.d.ts +0 -51
- package/dist/adapters/onchain.js +0 -158
- package/dist/adapters/uniswapv3-subgraph.d.ts +0 -44
- package/dist/adapters/uniswapv3-subgraph.js +0 -105
- package/dist/adapters/withdraw.d.ts +0 -14
- package/dist/adapters/withdraw.js +0 -150
- package/dist/api.d.ts +0 -72
- package/dist/api.js +0 -180
- package/dist/cli/liquidity-depth.d.ts +0 -2
- package/dist/cli/liquidity-depth.js +0 -1160
- package/dist/core/depth.d.ts +0 -48
- package/dist/core/depth.js +0 -314
- package/dist/handlers/cron.d.ts +0 -27
- package/dist/handlers/cron.js +0 -68
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -7
- package/dist/prices.d.ts +0 -15
- package/dist/prices.js +0 -205
- package/dist/wagmi/config.d.ts +0 -2106
- package/dist/wagmi/config.js +0 -24
- package/dist/wagmi/generated.d.ts +0 -2019
- package/dist/wagmi/generated.js +0 -346
package/dist/api.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { createMemoryClient, http as tevmHttp } from 'tevm';
|
|
2
|
-
import { computeMarketDepthBands, computePriceImpactsBySizes } from './core/depth.js';
|
|
3
|
-
import { fetchPoolSnapshot as fetchFromSubgraph } from './adapters/uniswapv3-subgraph.js';
|
|
4
|
-
import { fetchPoolSnapshotViem } from './adapters/onchain.js';
|
|
5
|
-
import { fetchTokenUSDPrices } from './prices.js';
|
|
6
|
-
import { resolveTevmCommon, simulateVaultWithdraw } from './adapters/withdraw.js';
|
|
7
|
-
export async function analyzePool(opts) {
|
|
8
|
-
const { poolAddress, source = 'auto', rpcUrl, subgraphUrl, percentBuckets = [1, 2, 5, 10], usdSizes = [], token0USD: token0Override, token1USD: token1Override, assumeStable, prices = 'auto', reserveLimit = 100, debug = false, withdraw, } = opts;
|
|
9
|
-
// Decide source
|
|
10
|
-
let used;
|
|
11
|
-
let client = null;
|
|
12
|
-
if (source === 'tevm' || (source === 'auto' && rpcUrl)) {
|
|
13
|
-
if (!rpcUrl)
|
|
14
|
-
throw new Error('analyzePool: rpcUrl required for tevm source');
|
|
15
|
-
const common = await resolveTevmCommon(rpcUrl);
|
|
16
|
-
client = createMemoryClient({ fork: { transport: tevmHttp(rpcUrl), blockTag: 'latest' }, loggingLevel: 'error', ...(common ? { common } : {}) });
|
|
17
|
-
if (client.tevmReady)
|
|
18
|
-
await client.tevmReady();
|
|
19
|
-
used = 'tevm';
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
used = 'subgraph';
|
|
23
|
-
}
|
|
24
|
-
// Snapshot
|
|
25
|
-
const snap = used === 'tevm'
|
|
26
|
-
? await fetchPoolSnapshotViem({ poolAddress, rpcUrl: rpcUrl, percentBuckets, client })
|
|
27
|
-
: await fetchFromSubgraph({ poolAddress, percentBuckets, subgraphUrl });
|
|
28
|
-
const before = await computeSnapshotMetrics({
|
|
29
|
-
poolAddress,
|
|
30
|
-
args: { token0USD: token0Override, token1USD: token1Override, assumeStable, usdSizes, prices, reserveLimit, debug, rpcUrl },
|
|
31
|
-
snap,
|
|
32
|
-
percentBuckets,
|
|
33
|
-
});
|
|
34
|
-
// Optional withdraw simulation on TEVM
|
|
35
|
-
let after;
|
|
36
|
-
if (used === 'tevm' && withdraw?.vault && withdraw?.owner && (Number.isFinite(withdraw.withdrawPct) || withdraw.withdrawShares != null)) {
|
|
37
|
-
await simulateVaultWithdraw({ client, vault: withdraw.vault, owner: withdraw.owner, withdrawPct: withdraw.withdrawPct, withdrawShares: withdraw.withdrawShares, debug });
|
|
38
|
-
const snap2 = await fetchPoolSnapshotViem({ poolAddress, client, percentBuckets });
|
|
39
|
-
after = await computeSnapshotMetrics({ poolAddress, args: { token0USD: token0Override, token1USD: token1Override, assumeStable, usdSizes, prices, reserveLimit, debug, rpcUrl }, snap: snap2, percentBuckets });
|
|
40
|
-
}
|
|
41
|
-
return { before, after };
|
|
42
|
-
}
|
|
43
|
-
async function computeSnapshotMetrics({ poolAddress, args, snap, percentBuckets }) {
|
|
44
|
-
const usd0 = Number.isFinite(args.token0USD) ? args.token0USD : snap.token0.usdPrice;
|
|
45
|
-
const usd1 = Number.isFinite(args.token1USD) ? args.token1USD : snap.token1.usdPrice;
|
|
46
|
-
let token0USD = usd0;
|
|
47
|
-
let token1USD = usd1;
|
|
48
|
-
const dec0 = snap.token0.decimals;
|
|
49
|
-
const dec1 = snap.token1.decimals;
|
|
50
|
-
const price1Per0 = Math.pow(1.0001, snap.tick) * Math.pow(10, dec0 - dec1);
|
|
51
|
-
if (!usd0 && usd1)
|
|
52
|
-
token0USD = usd1 * price1Per0;
|
|
53
|
-
if (usd0 && !usd1)
|
|
54
|
-
token1USD = usd0 / price1Per0;
|
|
55
|
-
let priceSource0 = usd0 ? 'override' : undefined;
|
|
56
|
-
let priceSource1 = usd1 ? 'override' : undefined;
|
|
57
|
-
if ((!token0USD || !token1USD)) {
|
|
58
|
-
try {
|
|
59
|
-
const addrs = [snap.meta?.token0?.id || snap.token0.id, snap.meta?.token1?.id || snap.token1.id].map((x) => x.toLowerCase());
|
|
60
|
-
let chainIdForPrices;
|
|
61
|
-
if (args.rpcUrl) {
|
|
62
|
-
try {
|
|
63
|
-
const clientCID = createMemoryClient({ fork: { transport: tevmHttp(args.rpcUrl), blockTag: 'latest' }, loggingLevel: 'error' });
|
|
64
|
-
if (clientCID.tevmReady)
|
|
65
|
-
await clientCID.tevmReady();
|
|
66
|
-
chainIdForPrices = await clientCID.getChainId();
|
|
67
|
-
}
|
|
68
|
-
catch { }
|
|
69
|
-
}
|
|
70
|
-
if (args.debug)
|
|
71
|
-
console.error(`[api] price fetch: addrs=${addrs.join(',')} source=${args.prices} rpc=${args.rpcUrl ? 'yes' : 'no'} chainId=${chainIdForPrices ?? 'n/a'}`);
|
|
72
|
-
const { byAddress } = await fetchTokenUSDPrices({ addresses: addrs, source: args.prices, chainId: chainIdForPrices, rpcUrl: args.rpcUrl, debug: !!args.debug, reserveLimit: args.reserveLimit });
|
|
73
|
-
const p0 = byAddress[addrs[0]];
|
|
74
|
-
const p1 = byAddress[addrs[1]];
|
|
75
|
-
if (!token0USD && p0) {
|
|
76
|
-
token0USD = p0.price;
|
|
77
|
-
priceSource0 = p0.source;
|
|
78
|
-
}
|
|
79
|
-
if (!token1USD && p1) {
|
|
80
|
-
token1USD = p1.price;
|
|
81
|
-
priceSource1 = p1.source;
|
|
82
|
-
}
|
|
83
|
-
if (token0USD && !token1USD) {
|
|
84
|
-
token1USD = token0USD / price1Per0;
|
|
85
|
-
if (!priceSource1)
|
|
86
|
-
priceSource1 = 'derived';
|
|
87
|
-
}
|
|
88
|
-
if (!token0USD && token1USD) {
|
|
89
|
-
token0USD = token1USD * price1Per0;
|
|
90
|
-
if (!priceSource0)
|
|
91
|
-
priceSource0 = 'derived';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
catch { }
|
|
95
|
-
}
|
|
96
|
-
if (!priceSource0 && usd0)
|
|
97
|
-
priceSource0 = 'subgraph';
|
|
98
|
-
if (!priceSource1 && usd1)
|
|
99
|
-
priceSource1 = 'subgraph';
|
|
100
|
-
if ((!token0USD || !token1USD)) {
|
|
101
|
-
if (args.assumeStable === 0 || /USD|USDC|USDT|DAI/i.test((snap.meta?.token0?.symbol || ''))) {
|
|
102
|
-
if (!token0USD) {
|
|
103
|
-
token0USD = 1;
|
|
104
|
-
priceSource0 = 'inferred';
|
|
105
|
-
}
|
|
106
|
-
if (!token1USD) {
|
|
107
|
-
token1USD = 1 / price1Per0;
|
|
108
|
-
priceSource1 = 'inferred';
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else if (args.assumeStable === 1 || /USD|USDC|USDT|DAI/i.test((snap.meta?.token1?.symbol || ''))) {
|
|
112
|
-
if (!token1USD) {
|
|
113
|
-
token1USD = 1;
|
|
114
|
-
priceSource1 = 'inferred';
|
|
115
|
-
}
|
|
116
|
-
if (!token0USD) {
|
|
117
|
-
token0USD = price1Per0;
|
|
118
|
-
priceSource0 = 'inferred';
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (!priceSource0 && token0USD)
|
|
123
|
-
priceSource0 = 'inferred';
|
|
124
|
-
if (!priceSource1 && token1USD)
|
|
125
|
-
priceSource1 = 'inferred';
|
|
126
|
-
const metrics = computeMarketDepthBands({
|
|
127
|
-
sqrtPriceX96: snap.sqrtPriceX96,
|
|
128
|
-
tick: snap.tick,
|
|
129
|
-
liquidity: snap.liquidity,
|
|
130
|
-
feePips: snap.feePips,
|
|
131
|
-
ticks: snap.ticks,
|
|
132
|
-
token0: { decimals: snap.token0.decimals, usdPrice: token0USD || 0 },
|
|
133
|
-
token1: { decimals: snap.token1.decimals, usdPrice: token1USD || 0 },
|
|
134
|
-
percentBuckets,
|
|
135
|
-
});
|
|
136
|
-
const usdSizes = (args.usdSizes || []);
|
|
137
|
-
const usdToRaw = (usd, usdPrice, decimals) => {
|
|
138
|
-
if (!usdPrice || usdPrice <= 0)
|
|
139
|
-
return 0n;
|
|
140
|
-
const micros = Math.round(usd * 1e6);
|
|
141
|
-
const usdMicrosPrice = Math.round(usdPrice * 1e6);
|
|
142
|
-
if (usdMicrosPrice <= 0)
|
|
143
|
-
return 0n;
|
|
144
|
-
const scale = 10n ** BigInt(decimals);
|
|
145
|
-
return (BigInt(micros) * scale) / BigInt(usdMicrosPrice);
|
|
146
|
-
};
|
|
147
|
-
let priceImpacts;
|
|
148
|
-
if (usdSizes.length && token0USD && token1USD) {
|
|
149
|
-
const buySizesToken1 = usdSizes.map((u) => usdToRaw(u, token1USD, snap.token1.decimals));
|
|
150
|
-
const sellSizesToken0 = usdSizes.map((u) => usdToRaw(u, token0USD, snap.token0.decimals));
|
|
151
|
-
priceImpacts = computePriceImpactsBySizes({
|
|
152
|
-
sqrtPriceX96: snap.sqrtPriceX96,
|
|
153
|
-
tick: snap.tick,
|
|
154
|
-
liquidity: snap.liquidity,
|
|
155
|
-
feePips: snap.feePips,
|
|
156
|
-
ticks: snap.ticks,
|
|
157
|
-
buySizesToken1,
|
|
158
|
-
sellSizesToken0,
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
pool: snap.meta?.poolId ?? poolAddress,
|
|
163
|
-
tokens: { token0: snap.meta?.token0 ?? {}, token1: snap.meta?.token1 ?? {} },
|
|
164
|
-
ethPriceUSD: snap.meta?.ethPriceUSD,
|
|
165
|
-
tick: snap.tick,
|
|
166
|
-
sqrtPriceX96: String(snap.sqrtPriceX96),
|
|
167
|
-
liquidity: String(snap.liquidity),
|
|
168
|
-
feePips: snap.feePips,
|
|
169
|
-
range: snap.meta?.range ?? { start: snap.tick, end: snap.tick },
|
|
170
|
-
percentBuckets,
|
|
171
|
-
prices: {
|
|
172
|
-
token0: { address: snap.meta?.token0?.id, symbol: snap.meta?.token0?.symbol, usd: token0USD, source: priceSource0 },
|
|
173
|
-
token1: { address: snap.meta?.token1?.id, symbol: snap.meta?.token1?.symbol, usd: token1USD, source: priceSource1 },
|
|
174
|
-
},
|
|
175
|
-
buyCumToken1: metrics.buyCumToken1.map((x) => String(x)),
|
|
176
|
-
sellCumToken0: metrics.sellCumToken0.map((x) => String(x)),
|
|
177
|
-
metrics,
|
|
178
|
-
priceImpacts: priceImpacts ? { usdSizes, buyPct: priceImpacts.buyPct, sellPct: priceImpacts.sellPct } : undefined,
|
|
179
|
-
};
|
|
180
|
-
}
|