@yummybait/uniswap-tx-builder-mcp 0.3.1
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/.claude-plugin/marketplace.json +11 -0
- package/.claude-plugin/plugin.json +16 -0
- package/LICENSE +201 -0
- package/README.md +195 -0
- package/bin/install-skill.mjs +34 -0
- package/dist/abi.d.ts +310 -0
- package/dist/abi.js +205 -0
- package/dist/abi.js.map +1 -0
- package/dist/builder.d.ts +149 -0
- package/dist/builder.js +335 -0
- package/dist/builder.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +56 -0
- package/dist/config.js.map +1 -0
- package/dist/mcp.d.ts +2 -0
- package/dist/mcp.js +363 -0
- package/dist/mcp.js.map +1 -0
- package/dist/operations.d.ts +82 -0
- package/dist/operations.js +114 -0
- package/dist/operations.js.map +1 -0
- package/dist/ticks.d.ts +69 -0
- package/dist/ticks.js +174 -0
- package/dist/ticks.js.map +1 -0
- package/package.json +64 -0
- package/skills/uniswap-tx-builder/SKILL.md +100 -0
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { closeOp, collectOp, increaseOp, mintOp, planOp, poolStateOp, swapOp, wrapOp, } from "./operations.js";
|
|
9
|
+
// uniswap-tx-builder-mcp — a PUBLIC, KEYLESS MCP server.
|
|
10
|
+
//
|
|
11
|
+
// It builds *unsigned* Uniswap v3 position transactions (collect / close /
|
|
12
|
+
// mint) and, optionally, simulates them via eth_call. It never holds keys and
|
|
13
|
+
// never signs or broadcasts — signing is the caller's wallet's job. Simulation
|
|
14
|
+
// is opt-in to let a caller prove a tx would succeed before signing, which
|
|
15
|
+
// boosts trust without taking custody.
|
|
16
|
+
const addressSchema = z
|
|
17
|
+
.string()
|
|
18
|
+
.regex(/^0x[a-fA-F0-9]{40}$/, "must be a 0x EVM address");
|
|
19
|
+
// uint256 token ids / amounts exceed JS safe integers → accept decimal strings.
|
|
20
|
+
const uintStringSchema = z.string().regex(/^\d+$/, "must be a decimal integer string");
|
|
21
|
+
// Single-source the version from package.json (resolves from src/ in dev and
|
|
22
|
+
// dist/ once built — package.json sits one level up in both layouts).
|
|
23
|
+
const { version } = createRequire(import.meta.url)("../package.json");
|
|
24
|
+
// All logging goes to stderr: in stdio mode stdout carries the MCP protocol.
|
|
25
|
+
function log(msg) {
|
|
26
|
+
process.stderr.write(`${new Date().toISOString()} [uniswap-tx-builder] ${msg}\n`);
|
|
27
|
+
}
|
|
28
|
+
// JSON for log lines: long hex blobs (calldata) collapse to a prefix + byte
|
|
29
|
+
// count so the readable parts of a result (to, value, description, position)
|
|
30
|
+
// aren't drowned out; anything still oversized is hard-capped.
|
|
31
|
+
function loggable(data, max = 1200) {
|
|
32
|
+
const json = JSON.stringify(data, (_key, value) => typeof value === "string" && value.length > 80 && /^0x[0-9a-fA-F]+$/.test(value)
|
|
33
|
+
? `${value.slice(0, 18)}…(${(value.length - 2) / 2} bytes)`
|
|
34
|
+
: value);
|
|
35
|
+
return json.length <= max ? json : `${json.slice(0, max)}…(+${json.length - max} chars)`;
|
|
36
|
+
}
|
|
37
|
+
function ok(data) {
|
|
38
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
39
|
+
}
|
|
40
|
+
function fail(message) {
|
|
41
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
42
|
+
}
|
|
43
|
+
// Shared tool-call wrapper: logs the call with its args, the outcome with
|
|
44
|
+
// duration, and converts thrown errors into MCP tool errors.
|
|
45
|
+
async function run(name, args, fn) {
|
|
46
|
+
const started = Date.now();
|
|
47
|
+
log(`→ ${name} ${loggable(args)}`);
|
|
48
|
+
try {
|
|
49
|
+
const data = await fn();
|
|
50
|
+
log(`← ${name} ok ${Date.now() - started}ms ${loggable(data)}`);
|
|
51
|
+
return ok(data);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const message = `${name} failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
55
|
+
log(`← ${name} ERROR ${Date.now() - started}ms ${message}`);
|
|
56
|
+
return fail(message);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// A factory rather than a singleton: an SDK server/transport pair is 1:1 with
|
|
60
|
+
// a session, so the HTTP mode below builds a fresh instance per request.
|
|
61
|
+
function buildServer() {
|
|
62
|
+
const server = new McpServer({ name: "uniswap-tx-builder", version });
|
|
63
|
+
server.registerTool("build_collect", {
|
|
64
|
+
title: "Build a collect-fees transaction",
|
|
65
|
+
description: "Build an UNSIGNED tx that collects all uncollected fees from a Uniswap v3 " +
|
|
66
|
+
"position to `recipient`. Returns tx={to,data,value,chainId} plus rlp (the " +
|
|
67
|
+
"unsigned EIP-1559 serialization for signing services). Set simulate=false " +
|
|
68
|
+
"to skip the eth_call dry-run (on by default).",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
chainId: z.number().int(),
|
|
71
|
+
positionId: uintStringSchema,
|
|
72
|
+
recipient: addressSchema,
|
|
73
|
+
simulate: z.boolean().optional(),
|
|
74
|
+
},
|
|
75
|
+
}, async (args) => run("build_collect", args, () => collectOp({
|
|
76
|
+
chainId: args.chainId,
|
|
77
|
+
positionId: BigInt(args.positionId),
|
|
78
|
+
recipient: args.recipient,
|
|
79
|
+
simulate: args.simulate,
|
|
80
|
+
})));
|
|
81
|
+
server.registerTool("build_close", {
|
|
82
|
+
title: "Build a close-position transaction",
|
|
83
|
+
description: "Build an UNSIGNED tx that removes all liquidity and collects everything from a " +
|
|
84
|
+
"Uniswap v3 position (multicalls when needed). Returns the tx (+ unsigned rlp) " +
|
|
85
|
+
"plus the read position. Set burn=true to also burn the now-empty NFT in the " +
|
|
86
|
+
"same multicall. Set simulate=false to skip the eth_call dry-run (on by default).",
|
|
87
|
+
inputSchema: {
|
|
88
|
+
chainId: z.number().int(),
|
|
89
|
+
positionId: uintStringSchema,
|
|
90
|
+
recipient: addressSchema,
|
|
91
|
+
burn: z.boolean().optional(),
|
|
92
|
+
simulate: z.boolean().optional(),
|
|
93
|
+
},
|
|
94
|
+
}, async (args) => run("build_close", args, () => closeOp({
|
|
95
|
+
chainId: args.chainId,
|
|
96
|
+
positionId: BigInt(args.positionId),
|
|
97
|
+
recipient: args.recipient,
|
|
98
|
+
burn: args.burn,
|
|
99
|
+
simulate: args.simulate,
|
|
100
|
+
})));
|
|
101
|
+
server.registerTool("build_mint", {
|
|
102
|
+
title: "Build a mint-position transaction",
|
|
103
|
+
description: "Build an UNSIGNED tx that mints a new Uniswap v3 position. Amounts are decimal " +
|
|
104
|
+
"strings (wei) — compute them with get_pool_state (live ratio) right before " +
|
|
105
|
+
"minting, or stale prices revert the mint. Returns the tx plus unsigned rlp. " +
|
|
106
|
+
"Simulation is OFF by default here (minting needs token approvals and balances, " +
|
|
107
|
+
"so eth_call usually reverts); pass simulate=true to attempt it.",
|
|
108
|
+
inputSchema: {
|
|
109
|
+
chainId: z.number().int(),
|
|
110
|
+
token0: addressSchema,
|
|
111
|
+
token1: addressSchema,
|
|
112
|
+
fee: z.number().int(),
|
|
113
|
+
tickLower: z.number().int(),
|
|
114
|
+
tickUpper: z.number().int(),
|
|
115
|
+
amount0Desired: uintStringSchema,
|
|
116
|
+
amount1Desired: uintStringSchema,
|
|
117
|
+
recipient: addressSchema,
|
|
118
|
+
slippageBps: z.number().int().optional(),
|
|
119
|
+
simulate: z.boolean().optional(),
|
|
120
|
+
},
|
|
121
|
+
}, async (args) => run("build_mint", args, () => mintOp({
|
|
122
|
+
chainId: args.chainId,
|
|
123
|
+
token0: args.token0,
|
|
124
|
+
token1: args.token1,
|
|
125
|
+
fee: args.fee,
|
|
126
|
+
tickLower: args.tickLower,
|
|
127
|
+
tickUpper: args.tickUpper,
|
|
128
|
+
amount0Desired: BigInt(args.amount0Desired),
|
|
129
|
+
amount1Desired: BigInt(args.amount1Desired),
|
|
130
|
+
recipient: args.recipient,
|
|
131
|
+
slippageBps: args.slippageBps,
|
|
132
|
+
simulate: args.simulate,
|
|
133
|
+
})));
|
|
134
|
+
server.registerTool("build_increase", {
|
|
135
|
+
title: "Build an increase-liquidity transaction",
|
|
136
|
+
description: "Build an UNSIGNED tx that adds liquidity to an EXISTING Uniswap v3 position. " +
|
|
137
|
+
"Amounts are decimal strings (wei); mins are derived from slippageBps (default 0.5%). " +
|
|
138
|
+
"Returns the tx plus unsigned rlp. Simulation is OFF by default (needs token " +
|
|
139
|
+
"approvals + balances); pass simulate=true to attempt it.",
|
|
140
|
+
inputSchema: {
|
|
141
|
+
chainId: z.number().int(),
|
|
142
|
+
positionId: uintStringSchema,
|
|
143
|
+
amount0Desired: uintStringSchema,
|
|
144
|
+
amount1Desired: uintStringSchema,
|
|
145
|
+
recipient: addressSchema,
|
|
146
|
+
slippageBps: z.number().int().optional(),
|
|
147
|
+
simulate: z.boolean().optional(),
|
|
148
|
+
},
|
|
149
|
+
}, async (args) => run("build_increase", args, () => increaseOp({
|
|
150
|
+
chainId: args.chainId,
|
|
151
|
+
positionId: BigInt(args.positionId),
|
|
152
|
+
amount0Desired: BigInt(args.amount0Desired),
|
|
153
|
+
amount1Desired: BigInt(args.amount1Desired),
|
|
154
|
+
recipient: args.recipient,
|
|
155
|
+
slippageBps: args.slippageBps,
|
|
156
|
+
simulate: args.simulate,
|
|
157
|
+
})));
|
|
158
|
+
server.registerTool("plan_position", {
|
|
159
|
+
title: "Plan a position from a human price range",
|
|
160
|
+
description: "READ-ONLY helper (builds no tx). Given a human price range (token1 per token0) and " +
|
|
161
|
+
"optional human token amounts, reads each token's decimals over RPC and returns the " +
|
|
162
|
+
"aligned tickLower/tickUpper (for the fee's tick spacing) plus wei amount0Desired/" +
|
|
163
|
+
"amount1Desired — ready to feed into build_mint. token0 must be < token1 by address. " +
|
|
164
|
+
"Does NOT compute the optimal amount ratio for the range.",
|
|
165
|
+
inputSchema: {
|
|
166
|
+
chainId: z.number().int(),
|
|
167
|
+
token0: addressSchema,
|
|
168
|
+
token1: addressSchema,
|
|
169
|
+
fee: z.number().int(),
|
|
170
|
+
priceLower: z.number().positive(),
|
|
171
|
+
priceUpper: z.number().positive(),
|
|
172
|
+
amount0: z.string().optional(),
|
|
173
|
+
amount1: z.string().optional(),
|
|
174
|
+
},
|
|
175
|
+
}, async (args) => run("plan_position", args, () => planOp({
|
|
176
|
+
chainId: args.chainId,
|
|
177
|
+
token0: args.token0,
|
|
178
|
+
token1: args.token1,
|
|
179
|
+
fee: args.fee,
|
|
180
|
+
priceLower: args.priceLower,
|
|
181
|
+
priceUpper: args.priceUpper,
|
|
182
|
+
amount0: args.amount0,
|
|
183
|
+
amount1: args.amount1,
|
|
184
|
+
})));
|
|
185
|
+
server.registerTool("get_pool_state", {
|
|
186
|
+
title: "Read live pool state; plan a range and mint amounts from it",
|
|
187
|
+
description: "READ-ONLY (builds no tx). Returns the pool's LIVE state: pool address, tick, " +
|
|
188
|
+
"sqrtPriceX96, price (token1 per token0, human units), tickSpacing. " +
|
|
189
|
+
"With rangePct: suggested tickLower/tickUpper within ±pct of spot, rounded INWARD " +
|
|
190
|
+
"to tick spacing. With balance0+balance1 (raw wei) + tickLower/tickUpper: " +
|
|
191
|
+
"amount0Desired/amount1Desired for build_mint computed from the live sqrtPrice " +
|
|
192
|
+
"ratio, plus which side limits. Errors if spot is outside the range. ALWAYS " +
|
|
193
|
+
"recompute amounts with this right before build_mint — stale ratios revert with " +
|
|
194
|
+
"'Price slippage check'.",
|
|
195
|
+
inputSchema: {
|
|
196
|
+
chainId: z.number().int(),
|
|
197
|
+
token0: addressSchema,
|
|
198
|
+
token1: addressSchema,
|
|
199
|
+
fee: z.number().int(),
|
|
200
|
+
rangePct: z.number().positive().optional(),
|
|
201
|
+
tickLower: z.number().int().optional(),
|
|
202
|
+
tickUpper: z.number().int().optional(),
|
|
203
|
+
balance0: uintStringSchema.optional(),
|
|
204
|
+
balance1: uintStringSchema.optional(),
|
|
205
|
+
},
|
|
206
|
+
}, async (args) => run("get_pool_state", args, () => poolStateOp({
|
|
207
|
+
chainId: args.chainId,
|
|
208
|
+
token0: args.token0,
|
|
209
|
+
token1: args.token1,
|
|
210
|
+
fee: args.fee,
|
|
211
|
+
rangePct: args.rangePct,
|
|
212
|
+
tickLower: args.tickLower,
|
|
213
|
+
tickUpper: args.tickUpper,
|
|
214
|
+
balance0: args.balance0 === undefined ? undefined : BigInt(args.balance0),
|
|
215
|
+
balance1: args.balance1 === undefined ? undefined : BigInt(args.balance1),
|
|
216
|
+
})));
|
|
217
|
+
server.registerTool("build_wrap", {
|
|
218
|
+
title: "Build a wrap-native-ETH transaction (Universal Router)",
|
|
219
|
+
description: "Build an UNSIGNED payable tx that wraps `amountWei` native ETH into WETH via the " +
|
|
220
|
+
"Universal Router WRAP_ETH command (works under UR-allowlisting wallet policies " +
|
|
221
|
+
"where a direct WETH.deposit() doesn't). `recipient` defaults to the tx sender — " +
|
|
222
|
+
"omit it unless the WETH should go elsewhere. Returns the tx plus unsigned rlp. " +
|
|
223
|
+
"Pass `sender` (the signing wallet) to eth_call-simulate before signing.",
|
|
224
|
+
inputSchema: {
|
|
225
|
+
chainId: z.number().int(),
|
|
226
|
+
amountWei: uintStringSchema,
|
|
227
|
+
recipient: addressSchema.optional(),
|
|
228
|
+
sender: addressSchema.optional(),
|
|
229
|
+
deadline: z.number().int().positive().optional(),
|
|
230
|
+
simulate: z.boolean().optional(),
|
|
231
|
+
},
|
|
232
|
+
}, async (args) => run("build_wrap", args, () => wrapOp({
|
|
233
|
+
chainId: args.chainId,
|
|
234
|
+
amountWei: BigInt(args.amountWei),
|
|
235
|
+
recipient: args.recipient,
|
|
236
|
+
sender: args.sender,
|
|
237
|
+
deadline: args.deadline,
|
|
238
|
+
simulate: args.simulate,
|
|
239
|
+
})));
|
|
240
|
+
server.registerTool("build_swap", {
|
|
241
|
+
title: "Build a WETH→token swap transaction (Universal Router)",
|
|
242
|
+
description: "Build an UNSIGNED tx that swaps `amountInWei` WETH for `tokenOut` (exact-in, " +
|
|
243
|
+
"single hop through the `fee` pool) via the Universal Router. With `wrapWei` " +
|
|
244
|
+
"(≥ amountInWei) the tx is payable and wraps that much native ETH first, swaps " +
|
|
245
|
+
"amountInWei of it, and sweeps the WETH remainder — use this when the wallet " +
|
|
246
|
+
"holds native ETH. Without wrapWei the wallet's WETH pays via Permit2 (needs a " +
|
|
247
|
+
"Permit2 approval). `recipient` defaults to the tx sender. Returns the tx plus " +
|
|
248
|
+
"unsigned rlp. Pass `sender` to eth_call-simulate before signing.",
|
|
249
|
+
inputSchema: {
|
|
250
|
+
chainId: z.number().int(),
|
|
251
|
+
amountInWei: uintStringSchema,
|
|
252
|
+
tokenOut: addressSchema,
|
|
253
|
+
fee: z.number().int(),
|
|
254
|
+
amountOutMin: uintStringSchema,
|
|
255
|
+
recipient: addressSchema.optional(),
|
|
256
|
+
wrapWei: uintStringSchema.optional(),
|
|
257
|
+
sender: addressSchema.optional(),
|
|
258
|
+
deadline: z.number().int().positive().optional(),
|
|
259
|
+
simulate: z.boolean().optional(),
|
|
260
|
+
},
|
|
261
|
+
}, async (args) => run("build_swap", args, () => swapOp({
|
|
262
|
+
chainId: args.chainId,
|
|
263
|
+
amountInWei: BigInt(args.amountInWei),
|
|
264
|
+
tokenOut: args.tokenOut,
|
|
265
|
+
fee: args.fee,
|
|
266
|
+
amountOutMin: BigInt(args.amountOutMin),
|
|
267
|
+
recipient: args.recipient,
|
|
268
|
+
wrapWei: args.wrapWei === undefined ? undefined : BigInt(args.wrapWei),
|
|
269
|
+
sender: args.sender,
|
|
270
|
+
deadline: args.deadline,
|
|
271
|
+
simulate: args.simulate,
|
|
272
|
+
})));
|
|
273
|
+
return server;
|
|
274
|
+
}
|
|
275
|
+
function jsonRpcError(res, status, code, message) {
|
|
276
|
+
res
|
|
277
|
+
.writeHead(status, { "content-type": "application/json" })
|
|
278
|
+
.end(JSON.stringify({ jsonrpc: "2.0", error: { code, message }, id: null }));
|
|
279
|
+
}
|
|
280
|
+
function readBody(req) {
|
|
281
|
+
return new Promise((resolve, reject) => {
|
|
282
|
+
const chunks = [];
|
|
283
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
284
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
285
|
+
req.on("error", reject);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
// One-glance label for a JSON-RPC payload, e.g. "initialize#1 (claude-code 2.1)"
|
|
289
|
+
// or "tools/call#3" or "notifications/initialized".
|
|
290
|
+
function describeRpc(body) {
|
|
291
|
+
const messages = Array.isArray(body) ? body : [body];
|
|
292
|
+
return messages
|
|
293
|
+
.map((msg) => {
|
|
294
|
+
if (!msg || typeof msg !== "object")
|
|
295
|
+
return "invalid";
|
|
296
|
+
const { method, id, params } = msg;
|
|
297
|
+
if (!method)
|
|
298
|
+
return `response#${String(id)}`;
|
|
299
|
+
let label = id === undefined ? method : `${method}#${String(id)}`;
|
|
300
|
+
if (method === "initialize" && params?.clientInfo?.name) {
|
|
301
|
+
label += ` (${params.clientInfo.name} ${params.clientInfo.version ?? "?"})`;
|
|
302
|
+
}
|
|
303
|
+
return label;
|
|
304
|
+
})
|
|
305
|
+
.join(",");
|
|
306
|
+
}
|
|
307
|
+
// Transport: HTTP (streamable) when MCP_HTTP_PORT is set — for running as a
|
|
308
|
+
// docker-compose service a local agent connects to — otherwise stdio.
|
|
309
|
+
//
|
|
310
|
+
// HTTP runs in STATELESS mode: every tool here is pure request/response, so
|
|
311
|
+
// each POST gets its own server + transport (sessionIdGenerator: undefined —
|
|
312
|
+
// no Mcp-Session-Id issued or required). Any number of clients can connect,
|
|
313
|
+
// and a client vanishing mid-session can't wedge the server. GET (standalone
|
|
314
|
+
// SSE) and DELETE (session teardown) only make sense with sessions → 405.
|
|
315
|
+
const httpPort = process.env.MCP_HTTP_PORT;
|
|
316
|
+
if (httpPort) {
|
|
317
|
+
createServer((req, res) => {
|
|
318
|
+
void (async () => {
|
|
319
|
+
if (req.method !== "POST") {
|
|
320
|
+
res.setHeader("Allow", "POST");
|
|
321
|
+
jsonRpcError(res, 405, -32000, "Method Not Allowed: stateless server accepts POST only");
|
|
322
|
+
log(`HTTP 405 ${req.method} ${req.url}`);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
let rpcBody;
|
|
326
|
+
try {
|
|
327
|
+
rpcBody = JSON.parse(await readBody(req));
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
jsonRpcError(res, 400, -32700, "Parse error: request body is not valid JSON");
|
|
331
|
+
log("HTTP 400 POST — body is not valid JSON");
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const rpc = describeRpc(rpcBody);
|
|
335
|
+
const started = Date.now();
|
|
336
|
+
res.on("finish", () => log(`HTTP ${res.statusCode} ${rpc} ${Date.now() - started}ms`));
|
|
337
|
+
const server = buildServer();
|
|
338
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
|
|
339
|
+
res.on("close", () => {
|
|
340
|
+
void transport.close();
|
|
341
|
+
void server.close();
|
|
342
|
+
});
|
|
343
|
+
try {
|
|
344
|
+
await server.connect(transport);
|
|
345
|
+
await transport.handleRequest(req, res, rpcBody);
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
log(`HTTP request failed (${rpc}): ${err instanceof Error ? err.message : String(err)}`);
|
|
349
|
+
if (!res.headersSent) {
|
|
350
|
+
jsonRpcError(res, 500, -32603, "Internal server error");
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
})();
|
|
354
|
+
}).listen(Number(httpPort), "0.0.0.0", () => {
|
|
355
|
+
log(`v${version} — streamable HTTP (stateless) listening on :${httpPort}/mcp`);
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
const transport = new StdioServerTransport();
|
|
360
|
+
await buildServer().connect(transport);
|
|
361
|
+
log(`v${version} — stdio transport connected`);
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation layer — the code path behind the MCP tools in `mcp.ts`, kept
|
|
3
|
+
* separate from transport so it stays unit-testable and ready to host a second
|
|
4
|
+
* (e.g. Uniswap v4) tool set. Each op builds an unsigned tx, optionally
|
|
5
|
+
* dry-runs it via `eth_call`, and returns a JSON-serializable payload. A failed
|
|
6
|
+
* simulation throws {@link SimulationError} so a caller can distinguish a
|
|
7
|
+
* reverted dry-run from a malformed request.
|
|
8
|
+
*/
|
|
9
|
+
import type { Address } from "viem";
|
|
10
|
+
import { type PlanPositionParams, type PlanPositionResult, type PoolStateParams, type PoolStateResult, type SwapParams, type UnsignedTx, type WrapParams } from "./builder.js";
|
|
11
|
+
/** Thrown when the opt-in `eth_call` dry-run reverts — never sign such a tx. */
|
|
12
|
+
export declare class SimulationError extends Error {
|
|
13
|
+
constructor(message: string);
|
|
14
|
+
}
|
|
15
|
+
export interface TxResult {
|
|
16
|
+
tx: UnsignedTx;
|
|
17
|
+
/** Unsigned EIP-1559 serialization of `tx` (nonce/fees/gas zeroed). */
|
|
18
|
+
rlp: string;
|
|
19
|
+
simulated: boolean;
|
|
20
|
+
description: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CollectArgs {
|
|
23
|
+
chainId: number;
|
|
24
|
+
positionId: bigint;
|
|
25
|
+
recipient: Address;
|
|
26
|
+
simulate?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function collectOp(args: CollectArgs): Promise<TxResult>;
|
|
29
|
+
export interface CloseArgs {
|
|
30
|
+
chainId: number;
|
|
31
|
+
positionId: bigint;
|
|
32
|
+
recipient: Address;
|
|
33
|
+
burn?: boolean;
|
|
34
|
+
simulate?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface CloseResult extends TxResult {
|
|
37
|
+
position: {
|
|
38
|
+
token0: Address;
|
|
39
|
+
token1: Address;
|
|
40
|
+
fee: number;
|
|
41
|
+
tickLower: number;
|
|
42
|
+
tickUpper: number;
|
|
43
|
+
liquidity: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function closeOp(args: CloseArgs): Promise<CloseResult>;
|
|
47
|
+
export interface MintArgs {
|
|
48
|
+
chainId: number;
|
|
49
|
+
token0: Address;
|
|
50
|
+
token1: Address;
|
|
51
|
+
fee: number;
|
|
52
|
+
tickLower: number;
|
|
53
|
+
tickUpper: number;
|
|
54
|
+
amount0Desired: bigint;
|
|
55
|
+
amount1Desired: bigint;
|
|
56
|
+
recipient: Address;
|
|
57
|
+
slippageBps?: number;
|
|
58
|
+
simulate?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare function mintOp(args: MintArgs): Promise<TxResult>;
|
|
61
|
+
export interface IncreaseArgs {
|
|
62
|
+
chainId: number;
|
|
63
|
+
positionId: bigint;
|
|
64
|
+
amount0Desired: bigint;
|
|
65
|
+
amount1Desired: bigint;
|
|
66
|
+
recipient: Address;
|
|
67
|
+
slippageBps?: number;
|
|
68
|
+
simulate?: boolean;
|
|
69
|
+
}
|
|
70
|
+
export declare function increaseOp(args: IncreaseArgs): Promise<TxResult>;
|
|
71
|
+
export declare function planOp(args: PlanPositionParams): Promise<PlanPositionResult>;
|
|
72
|
+
export declare function poolStateOp(args: PoolStateParams): Promise<PoolStateResult>;
|
|
73
|
+
export interface WrapArgs extends WrapParams {
|
|
74
|
+
sender?: Address;
|
|
75
|
+
simulate?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export declare function wrapOp(args: WrapArgs): Promise<TxResult>;
|
|
78
|
+
export interface SwapArgs extends SwapParams {
|
|
79
|
+
sender?: Address;
|
|
80
|
+
simulate?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export declare function swapOp(args: SwapArgs): Promise<TxResult>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { buildCloseTx, buildCollectTx, buildIncreaseLiquidityTx, buildMintTx, buildSwapTx, buildWrapTx, getPoolState, planPosition, simulateTx, toUnsignedRlp, } from "./builder.js";
|
|
2
|
+
/** Thrown when the opt-in `eth_call` dry-run reverts — never sign such a tx. */
|
|
3
|
+
export class SimulationError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "SimulationError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
async function maybeSimulate(chainId, tx, from, simulate) {
|
|
10
|
+
if (!simulate)
|
|
11
|
+
return false;
|
|
12
|
+
try {
|
|
13
|
+
await simulateTx(chainId, tx, from);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
throw new SimulationError(err instanceof Error ? err.message : String(err));
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
export async function collectOp(args) {
|
|
21
|
+
const tx = await buildCollectTx(args.chainId, args.positionId, args.recipient);
|
|
22
|
+
const simulated = await maybeSimulate(args.chainId, tx, args.recipient, args.simulate !== false);
|
|
23
|
+
return {
|
|
24
|
+
tx,
|
|
25
|
+
rlp: toUnsignedRlp(tx),
|
|
26
|
+
simulated,
|
|
27
|
+
description: `Collect fees from position #${args.positionId}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export async function closeOp(args) {
|
|
31
|
+
const { tx, position } = await buildCloseTx(args.chainId, args.positionId, args.recipient, args.burn ?? false);
|
|
32
|
+
const simulated = await maybeSimulate(args.chainId, tx, args.recipient, args.simulate !== false);
|
|
33
|
+
const action = position.liquidity > 0n
|
|
34
|
+
? "Close position"
|
|
35
|
+
: "Collect remaining tokens from position";
|
|
36
|
+
const suffix = args.burn ? " + burn NFT" : "";
|
|
37
|
+
return {
|
|
38
|
+
tx,
|
|
39
|
+
rlp: toUnsignedRlp(tx),
|
|
40
|
+
simulated,
|
|
41
|
+
position: {
|
|
42
|
+
token0: position.token0,
|
|
43
|
+
token1: position.token1,
|
|
44
|
+
fee: position.fee,
|
|
45
|
+
tickLower: position.tickLower,
|
|
46
|
+
tickUpper: position.tickUpper,
|
|
47
|
+
liquidity: position.liquidity.toString(),
|
|
48
|
+
},
|
|
49
|
+
description: `${action} #${args.positionId}${suffix}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export async function mintOp(args) {
|
|
53
|
+
const tx = buildMintTx(args);
|
|
54
|
+
const simulated = await maybeSimulate(args.chainId, tx, args.recipient, args.simulate === true);
|
|
55
|
+
return {
|
|
56
|
+
tx,
|
|
57
|
+
rlp: toUnsignedRlp(tx),
|
|
58
|
+
simulated,
|
|
59
|
+
description: `Mint new position: ${args.token0}/${args.token1} fee=${args.fee} range=[${args.tickLower}, ${args.tickUpper}]`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export async function increaseOp(args) {
|
|
63
|
+
const tx = buildIncreaseLiquidityTx(args);
|
|
64
|
+
const simulated = await maybeSimulate(args.chainId, tx, args.recipient, args.simulate === true);
|
|
65
|
+
return {
|
|
66
|
+
tx,
|
|
67
|
+
rlp: toUnsignedRlp(tx),
|
|
68
|
+
simulated,
|
|
69
|
+
description: `Increase liquidity of position #${args.positionId}`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export async function planOp(args) {
|
|
73
|
+
return planPosition(args);
|
|
74
|
+
}
|
|
75
|
+
export async function poolStateOp(args) {
|
|
76
|
+
return getPoolState(args);
|
|
77
|
+
}
|
|
78
|
+
// Wrap/swap txs are payable and spend the sender's native ETH, so simulation
|
|
79
|
+
// needs the actual signer as `from` — `sender` opts it in (unlike collect/
|
|
80
|
+
// close, where `recipient` doubles as a plausible `from`).
|
|
81
|
+
async function maybeSimulateAsSender(chainId, tx, sender, simulate) {
|
|
82
|
+
if (!sender) {
|
|
83
|
+
if (simulate === true) {
|
|
84
|
+
throw new Error("simulate: true requires `sender` (the wallet that will sign)");
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return maybeSimulate(chainId, tx, sender, simulate !== false);
|
|
89
|
+
}
|
|
90
|
+
export async function wrapOp(args) {
|
|
91
|
+
const tx = buildWrapTx(args);
|
|
92
|
+
const simulated = await maybeSimulateAsSender(args.chainId, tx, args.sender, args.simulate);
|
|
93
|
+
return {
|
|
94
|
+
tx,
|
|
95
|
+
rlp: toUnsignedRlp(tx),
|
|
96
|
+
simulated,
|
|
97
|
+
description: `Wrap ${args.amountWei} wei native ETH to WETH via Universal Router`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export async function swapOp(args) {
|
|
101
|
+
const tx = buildSwapTx(args);
|
|
102
|
+
const simulated = await maybeSimulateAsSender(args.chainId, tx, args.sender, args.simulate);
|
|
103
|
+
const swap = `swap ${args.amountInWei} wei WETH → ${args.tokenOut} (fee ${args.fee})`;
|
|
104
|
+
const description = args.wrapWei === undefined
|
|
105
|
+
? `Universal Router: ${swap}`
|
|
106
|
+
: `Universal Router: wrap ${args.wrapWei} wei native ETH, ${swap}, sweep WETH remainder`;
|
|
107
|
+
return {
|
|
108
|
+
tx,
|
|
109
|
+
rlp: toUnsignedRlp(tx),
|
|
110
|
+
simulated,
|
|
111
|
+
description,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"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"}
|
package/dist/ticks.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure Uniswap v3 tick math — no RPC, no I/O. Converts human-readable prices
|
|
3
|
+
* into the aligned ticks a position uses, and live pool readings into
|
|
4
|
+
* range suggestions and mint amounts.
|
|
5
|
+
*
|
|
6
|
+
* A pool price is `token1` per `token0` expressed in each token's *smallest*
|
|
7
|
+
* unit. A human price `P` ("how many whole token1 per whole token0") relates
|
|
8
|
+
* to the raw price by `raw = P * 10^(decimals1 - decimals0)`, and
|
|
9
|
+
* `tick = log(raw) / log(1.0001)`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MIN_TICK = -887272;
|
|
12
|
+
export declare const MAX_TICK = 887272;
|
|
13
|
+
/** Standard fee tier → tick spacing. */
|
|
14
|
+
export declare const FEE_TO_TICK_SPACING: Record<number, number>;
|
|
15
|
+
export declare function feeToTickSpacing(fee: number): number;
|
|
16
|
+
/**
|
|
17
|
+
* Convert a human price (token1 per token0) to the (unaligned) tick.
|
|
18
|
+
* `price` must be > 0.
|
|
19
|
+
*/
|
|
20
|
+
export declare function priceToTick(price: number, decimals0: number, decimals1: number): number;
|
|
21
|
+
/** Snap a tick to the nearest usable tick for `spacing`, clamped to bounds. */
|
|
22
|
+
export declare function alignTick(tick: number, spacing: number): number;
|
|
23
|
+
export interface TickRange {
|
|
24
|
+
tickLower: number;
|
|
25
|
+
tickUpper: number;
|
|
26
|
+
tickSpacing: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Convert a human price range to aligned [tickLower, tickUpper] for `fee`.
|
|
30
|
+
* Prices are reordered if given high→low, and the bounds are guaranteed to
|
|
31
|
+
* differ by at least one tick spacing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function priceRangeToTicks(priceLower: number, priceUpper: number, fee: number, decimals0: number, decimals1: number): TickRange;
|
|
34
|
+
/**
|
|
35
|
+
* Q64.96 sqrt price at a tick — bit-for-bit identical to the on-chain
|
|
36
|
+
* `TickMath.getSqrtRatioAtTick`, so amounts derived from it match what the
|
|
37
|
+
* pool computes.
|
|
38
|
+
*/
|
|
39
|
+
export declare function getSqrtRatioAtTick(tick: number): bigint;
|
|
40
|
+
export interface SuggestedRange {
|
|
41
|
+
tickLower: number;
|
|
42
|
+
tickUpper: number;
|
|
43
|
+
/** Actual (post-rounding) range edges relative to spot, in percent. */
|
|
44
|
+
pctBelow: number;
|
|
45
|
+
pctAbove: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Ticks within ±`rangePct` of the spot tick, rounded INWARD to `tickSpacing`
|
|
49
|
+
* — outward rounding would exceed the caller's stated max width.
|
|
50
|
+
*/
|
|
51
|
+
export declare function suggestRangeTicks(tick: number, tickSpacing: number, rangePct: number): SuggestedRange;
|
|
52
|
+
export interface MintAmounts {
|
|
53
|
+
amount0Desired: bigint;
|
|
54
|
+
amount1Desired: bigint;
|
|
55
|
+
/** Which balance caps the position's liquidity. */
|
|
56
|
+
limitingSide: "token0" | "token1";
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The largest both-sided deposit the balances allow at the LIVE pool price:
|
|
60
|
+
* per-side liquidity `L0`/`L1` from the full balances, `L = min(L0, L1)`,
|
|
61
|
+
* then back out the exact amounts that liquidity consumes. Feeding these to
|
|
62
|
+
* `mint` matches the pool's own math, so slippage mins can stay tight.
|
|
63
|
+
*
|
|
64
|
+
* Throws when the spot price is outside [tickLower, tickUpper] — such a mint
|
|
65
|
+
* is single-sided and the caller should recompute the range instead.
|
|
66
|
+
*/
|
|
67
|
+
export declare function computeMintAmounts(sqrtPriceX96: bigint, tickLower: number, tickUpper: number, balance0: bigint, balance1: bigint): MintAmounts;
|
|
68
|
+
/** Human price (token1 per token0) from a Q64.96 sqrt price. */
|
|
69
|
+
export declare function sqrtPriceX96ToPrice(sqrtPriceX96: bigint, decimals0: number, decimals1: number): number;
|