@continuumdao/ctm-mpc-defi 0.2.0 → 0.2.2
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 +20 -78
- package/dist/agent/catalog.cjs +563 -5
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +166 -20
- package/dist/agent/catalog.js +551 -7
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +43 -0
- package/dist/agent/skills/curve-dao/SKILL.md +13 -0
- package/dist/agent/skills/ethena/SKILL.md +10 -0
- package/dist/agent/skills/euler-v2/SKILL.md +10 -0
- package/dist/agent/skills/lido/SKILL.md +22 -0
- package/dist/agent/skills/maple-syrup/SKILL.md +10 -0
- package/dist/agent/skills/sky/SKILL.md +10 -0
- package/dist/agent/skills/uniswap-v4/SKILL.md +22 -0
- package/dist/chains/evm/index.cjs +79 -224
- package/dist/chains/evm/index.cjs.map +1 -1
- package/dist/chains/evm/index.d.ts +26 -26
- package/dist/chains/evm/index.js +69 -209
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/near/index.d.ts +1 -1
- package/dist/chains/solana/index.d.ts +1 -1
- package/dist/core/index.cjs +68 -106
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +21 -36
- package/dist/core/index.js +57 -96
- package/dist/core/index.js.map +1 -1
- package/dist/{envelope-CcE5Cz_q.d.ts → envelope-CpBUh9eP.d.ts} +1 -1
- package/dist/index.cjs +356 -1855
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -11
- package/dist/index.js +332 -1826
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs +1152 -669
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.d.ts +418 -3
- package/dist/protocols/evm/aave-v4/index.js +1126 -670
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +257 -131
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.d.ts +69 -5
- package/dist/protocols/evm/curve-dao/index.js +242 -124
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/ethena/index.cjs +394 -402
- package/dist/protocols/evm/ethena/index.cjs.map +1 -1
- package/dist/protocols/evm/ethena/index.d.ts +47 -3
- package/dist/protocols/evm/ethena/index.js +390 -404
- package/dist/protocols/evm/ethena/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +2810 -1191
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.d.ts +465 -3
- package/dist/protocols/evm/euler-v2/index.js +2761 -1192
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/lido/index.cjs +351 -236
- package/dist/protocols/evm/lido/index.cjs.map +1 -1
- package/dist/protocols/evm/lido/index.d.ts +34 -4
- package/dist/protocols/evm/lido/index.js +348 -238
- package/dist/protocols/evm/lido/index.js.map +1 -1
- package/dist/protocols/evm/maple/index.cjs +390 -395
- package/dist/protocols/evm/maple/index.cjs.map +1 -1
- package/dist/protocols/evm/maple/index.d.ts +23 -3
- package/dist/protocols/evm/maple/index.js +390 -397
- package/dist/protocols/evm/maple/index.js.map +1 -1
- package/dist/protocols/evm/sky/index.cjs +454 -232
- package/dist/protocols/evm/sky/index.cjs.map +1 -1
- package/dist/protocols/evm/sky/index.d.ts +57 -3
- package/dist/protocols/evm/sky/index.js +444 -231
- package/dist/protocols/evm/sky/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +423 -658
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +3 -4
- package/dist/protocols/evm/uniswap-v4/index.js +422 -657
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/dist/{registry-oMKlO_5z.d.ts → registry-Bv5o37_w.d.ts} +1 -1
- package/dist/{types-Ce2qNHai.d.cts → types-BfjWdw1j.d.ts} +3 -1
- package/dist/{types-5u863Fd9.d.ts → types-DUeNJLr9.d.ts} +1 -1
- package/package.json +7 -6
- package/dist/agent/catalog.d.cts +0 -939
- package/dist/chains/evm/index.d.cts +0 -64
- package/dist/chains/near/index.d.cts +0 -37
- package/dist/chains/solana/index.d.cts +0 -40
- package/dist/core/index.d.cts +0 -43
- package/dist/envelope-DYDPnrHZ.d.cts +0 -35
- package/dist/index.d.cts +0 -16
- package/dist/keygen-CfNp8yKJ.d.cts +0 -9
- package/dist/keygen-DsINazx8.d.ts +0 -9
- package/dist/nodeRead-BnmSaMGO.d.cts +0 -8
- package/dist/nodeRead-BnmSaMGO.d.ts +0 -8
- package/dist/protocols/evm/aave-v4/index.d.cts +0 -500
- package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
- package/dist/protocols/evm/ethena/index.d.cts +0 -161
- package/dist/protocols/evm/euler-v2/index.d.cts +0 -317
- package/dist/protocols/evm/lido/index.d.cts +0 -120
- package/dist/protocols/evm/maple/index.d.cts +0 -109
- package/dist/protocols/evm/sky/index.d.cts +0 -218
- package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
- package/dist/registry-BwZoE668.d.cts +0 -8
- package/dist/txParams-BC7ogvdR.d.cts +0 -19
- package/dist/txParams-BC7ogvdR.d.ts +0 -19
- package/dist/types-B8idm_gu.d.cts +0 -34
- package/dist/types-Ce2qNHai.d.ts +0 -57
package/dist/index.cjs
CHANGED
|
@@ -1,26 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var continuumNodeSdk = require('@continuumdao/continuum-node-sdk');
|
|
3
4
|
var viem = require('viem');
|
|
4
|
-
var zodToJsonSchema = require('zod-to-json-schema');
|
|
5
|
-
var zod = require('zod');
|
|
6
5
|
|
|
7
|
-
// src/core/
|
|
8
|
-
function firstClientIdFromKeyGen(data) {
|
|
9
|
-
const map = data?.ClientKeys;
|
|
10
|
-
if (!map || typeof map !== "object") return null;
|
|
11
|
-
for (const v of Object.values(map)) {
|
|
12
|
-
if (typeof v === "string" && v.trim()) return v.trim();
|
|
13
|
-
}
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
function requirePubKeyHex(keyGen) {
|
|
17
|
-
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
18
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
19
|
-
return ph;
|
|
20
|
-
}
|
|
21
|
-
function keyListFromKeyGen(keyGen) {
|
|
22
|
-
return keyGen.keylist ?? [];
|
|
23
|
-
}
|
|
6
|
+
// src/core/index.ts
|
|
24
7
|
|
|
25
8
|
// src/core/purpose.ts
|
|
26
9
|
function mergePurposeText(purposeText, purposeSuffix) {
|
|
@@ -31,8 +14,6 @@ function mergePurposeText(purposeText, purposeSuffix) {
|
|
|
31
14
|
|
|
32
15
|
${suffix}` : suffix;
|
|
33
16
|
}
|
|
34
|
-
|
|
35
|
-
// src/core/envelope.ts
|
|
36
17
|
function finalizeMultisign(input) {
|
|
37
18
|
const { keyGen, destinationChainID, legs } = input;
|
|
38
19
|
if (legs.length === 0) {
|
|
@@ -41,7 +22,7 @@ function finalizeMultisign(input) {
|
|
|
41
22
|
const ph = (keyGen.pubkeyhex ?? "").trim();
|
|
42
23
|
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
43
24
|
const keyList = keyGen.keylist ?? [];
|
|
44
|
-
const clientId =
|
|
25
|
+
const clientId = continuumNodeSdk.getClientIdFromKeyGenResult(keyGen);
|
|
45
26
|
const first = legs[0];
|
|
46
27
|
const messageHashes = legs.map((l) => l.msgHash);
|
|
47
28
|
const messageRawBatch = legs.map((l) => l.msgRaw);
|
|
@@ -107,83 +88,59 @@ function getActionsByChainCategory(category) {
|
|
|
107
88
|
return modules.filter((m) => m.chainCategory === category).flatMap((m) => m.actions);
|
|
108
89
|
}
|
|
109
90
|
|
|
110
|
-
// src/core/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return fetch(url, { ...init, headers });
|
|
91
|
+
// src/core/defiProxy.ts
|
|
92
|
+
var aaveGraphqlProxyUrl;
|
|
93
|
+
var eulerGraphqlProxyUrl;
|
|
94
|
+
var mapleGraphqlProxyUrl;
|
|
95
|
+
var coingeckoProxyUrl;
|
|
96
|
+
function setAaveGraphqlProxyUrl(url) {
|
|
97
|
+
aaveGraphqlProxyUrl = url?.trim() || void 0;
|
|
118
98
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
function normalizeManagementNodeKey(nodeKey) {
|
|
122
|
-
const nk = nodeKey?.trim().replace(/^0x/i, "");
|
|
123
|
-
if (!nk || !/^[0-9a-fA-F]{128}$/.test(nk)) {
|
|
124
|
-
throw new Error("nodeKey is required (128 hex from GET /getNodeKey).");
|
|
125
|
-
}
|
|
126
|
-
return nk.toLowerCase();
|
|
99
|
+
function getAaveGraphqlProxyUrl() {
|
|
100
|
+
return aaveGraphqlProxyUrl;
|
|
127
101
|
}
|
|
128
|
-
function
|
|
129
|
-
|
|
102
|
+
function setEulerGraphqlProxyUrl(url) {
|
|
103
|
+
eulerGraphqlProxyUrl = url?.trim() || void 0;
|
|
130
104
|
}
|
|
131
|
-
function
|
|
132
|
-
return
|
|
105
|
+
function getEulerGraphqlProxyUrl() {
|
|
106
|
+
return eulerGraphqlProxyUrl;
|
|
133
107
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
108
|
+
function setMapleGraphqlProxyUrl(url) {
|
|
109
|
+
mapleGraphqlProxyUrl = url?.trim() || void 0;
|
|
136
110
|
}
|
|
137
|
-
function
|
|
138
|
-
return
|
|
111
|
+
function getMapleGraphqlProxyUrl() {
|
|
112
|
+
return mapleGraphqlProxyUrl;
|
|
139
113
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
function mpcAuthData(raw) {
|
|
143
|
-
const code = raw.Code ?? raw.code;
|
|
144
|
-
if (code !== 0 && code !== void 0) return void 0;
|
|
145
|
-
return raw.Data ?? raw.data;
|
|
146
|
-
}
|
|
147
|
-
async function fetchNodeKey(nodeUrl, readAuth = { bearerOnGet: false, jwt: null }) {
|
|
148
|
-
const base = nodeUrl.trim().replace(/\/$/, "");
|
|
149
|
-
const res = await nodeFetchWithReadAuth(`${base}/getNodeKey`, { cache: "no-store" }, readAuth);
|
|
150
|
-
const text = await res.text();
|
|
151
|
-
let raw;
|
|
152
|
-
try {
|
|
153
|
-
raw = JSON.parse(text);
|
|
154
|
-
} catch {
|
|
155
|
-
return { nodeKey: "", ok: false };
|
|
156
|
-
}
|
|
157
|
-
const data = mpcAuthData(raw);
|
|
158
|
-
const nk = typeof data === "string" ? data : data != null && typeof data === "object" && !Array.isArray(data) ? String(data.nodeKey ?? data.NodeKey ?? "") : data != null ? String(data) : "";
|
|
159
|
-
const trimmed = nk.trim().replace(/^0x/i, "");
|
|
160
|
-
if (!/^[0-9a-fA-F]{128}$/.test(trimmed)) {
|
|
161
|
-
return { nodeKey: "", ok: false };
|
|
162
|
-
}
|
|
163
|
-
return { nodeKey: trimmed.toLowerCase(), ok: res.ok };
|
|
114
|
+
function setCoingeckoProxyUrl(url) {
|
|
115
|
+
coingeckoProxyUrl = url?.trim() || void 0;
|
|
164
116
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
117
|
+
function getCoingeckoProxyUrl() {
|
|
118
|
+
return coingeckoProxyUrl;
|
|
119
|
+
}
|
|
120
|
+
async function postJsonViaOptionalProxy(args) {
|
|
121
|
+
const proxy = args.proxyUrl?.trim();
|
|
122
|
+
if (proxy) {
|
|
123
|
+
const r2 = await fetch(proxy, {
|
|
124
|
+
method: "POST",
|
|
125
|
+
headers: { "content-type": "application/json" },
|
|
126
|
+
body: JSON.stringify(args.proxyEnvelope ?? args.body)
|
|
127
|
+
});
|
|
128
|
+
if (!r2.ok) {
|
|
129
|
+
const t = await r2.text().catch(() => "");
|
|
130
|
+
throw new Error(t ? `Proxy HTTP ${r2.status}: ${t.slice(0, 200)}` : `Proxy HTTP ${r2.status}`);
|
|
131
|
+
}
|
|
132
|
+
return await r2.json();
|
|
176
133
|
}
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
134
|
+
const r = await fetch(args.directUrl, {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: { "content-type": "application/json" },
|
|
137
|
+
body: JSON.stringify(args.body)
|
|
138
|
+
});
|
|
139
|
+
if (!r.ok) {
|
|
140
|
+
const t = await r.text().catch(() => "");
|
|
141
|
+
throw new Error(t ? `HTTP ${r.status}: ${t.slice(0, 200)}` : `HTTP ${r.status}`);
|
|
185
142
|
}
|
|
186
|
-
return
|
|
143
|
+
return await r.json();
|
|
187
144
|
}
|
|
188
145
|
function isEvmNativeToken(address) {
|
|
189
146
|
try {
|
|
@@ -199,161 +156,12 @@ function matchEvmTokenKind(kind, address) {
|
|
|
199
156
|
}
|
|
200
157
|
return true;
|
|
201
158
|
}
|
|
202
|
-
|
|
203
|
-
// src/chains/evm/txParams.ts
|
|
204
|
-
function gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit) {
|
|
205
|
-
if (chainGasLimit == null || !Number.isFinite(chainGasLimit) || chainGasLimit <= 0) {
|
|
206
|
-
return estimatedGas;
|
|
207
|
-
}
|
|
208
|
-
const cfg = BigInt(Math.floor(chainGasLimit));
|
|
209
|
-
return cfg > estimatedGas ? cfg : estimatedGas;
|
|
210
|
-
}
|
|
211
159
|
function routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimit) {
|
|
212
160
|
if (chainGasLimit != null && Number.isFinite(chainGasLimit) && chainGasLimit > 0) {
|
|
213
|
-
return gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
161
|
+
return continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, chainGasLimit);
|
|
214
162
|
}
|
|
215
163
|
return (estimatedGas * 12n + 9n) / 10n;
|
|
216
164
|
}
|
|
217
|
-
function composeFeePayloadToTxParams(p, legacy) {
|
|
218
|
-
const gl = p.txGasLimit ?? p.txgaslimit;
|
|
219
|
-
if (gl == null || String(gl).trim() === "") return void 0;
|
|
220
|
-
const n = p.txNonce ?? p.txnonce;
|
|
221
|
-
let nonce = 0;
|
|
222
|
-
if (typeof n === "bigint") nonce = Number(n);
|
|
223
|
-
else if (typeof n === "number") nonce = n;
|
|
224
|
-
else if (n != null) nonce = parseInt(String(n), 10);
|
|
225
|
-
if (!Number.isFinite(nonce)) nonce = 0;
|
|
226
|
-
const gasLimit = String(gl);
|
|
227
|
-
if (legacy) {
|
|
228
|
-
const gp = p.txGasPrice ?? p.txgasprice;
|
|
229
|
-
return {
|
|
230
|
-
nonce,
|
|
231
|
-
gasLimit,
|
|
232
|
-
txType: "legacy",
|
|
233
|
-
gasPrice: gp != null ? String(gp) : "0"
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
nonce,
|
|
238
|
-
gasLimit,
|
|
239
|
-
txType: "eip1559",
|
|
240
|
-
maxFeePerGas: String(p.txMaxFeePerGas ?? ""),
|
|
241
|
-
maxPriorityFeePerGas: String(p.txMaxPriorityFeePerGas ?? "")
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function triggerTxParamsFromComposeBody(body) {
|
|
245
|
-
const existing = body.txParams;
|
|
246
|
-
if (existing && typeof existing === "object" && !Array.isArray(existing)) {
|
|
247
|
-
const o = existing;
|
|
248
|
-
if (String(o.gasLimit ?? "").trim() !== "") {
|
|
249
|
-
return { ...o };
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
const pb = body.proposalTxParams;
|
|
253
|
-
if (Array.isArray(pb) && pb.length > 0 && typeof pb[0] === "object" && pb[0] !== null) {
|
|
254
|
-
const first = pb[0];
|
|
255
|
-
if (String(first.gasLimit ?? "").trim() !== "") {
|
|
256
|
-
return { ...first };
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
const fromSnapshot = composeFeePayloadToTxParams(
|
|
260
|
-
body,
|
|
261
|
-
body.txMaxFeePerGas == null && body.txMaxPriorityFeePerGas == null
|
|
262
|
-
);
|
|
263
|
-
if (fromSnapshot) return fromSnapshot;
|
|
264
|
-
return {
|
|
265
|
-
nonce: 0,
|
|
266
|
-
gasLimit: "",
|
|
267
|
-
txType: "legacy",
|
|
268
|
-
gasPrice: "0"
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
function proposalTxParamsToFeeSnapshot(params) {
|
|
272
|
-
if (params.txType === "legacy") {
|
|
273
|
-
return {
|
|
274
|
-
txNonce: params.nonce,
|
|
275
|
-
txGasLimit: params.gasLimit,
|
|
276
|
-
txGasPrice: params.gasPrice ?? "0"
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
return {
|
|
280
|
-
txNonce: params.nonce,
|
|
281
|
-
txGasLimit: params.gasLimit,
|
|
282
|
-
txMaxFeePerGas: params.maxFeePerGas ?? "",
|
|
283
|
-
txMaxPriorityFeePerGas: params.maxPriorityFeePerGas ?? ""
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
async function fetchChainFeeParams(rpcUrl, chainId) {
|
|
287
|
-
const url = rpcUrl.trim();
|
|
288
|
-
if (!url) return { isEip1559: false };
|
|
289
|
-
const chainIdNum = typeof chainId === "string" ? parseInt(chainId, 10) : chainId;
|
|
290
|
-
if (Number.isNaN(chainIdNum)) return { isEip1559: false };
|
|
291
|
-
const chain = viem.defineChain({
|
|
292
|
-
id: chainIdNum,
|
|
293
|
-
name: "Discovery",
|
|
294
|
-
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
295
|
-
rpcUrls: { default: { http: [url] } }
|
|
296
|
-
});
|
|
297
|
-
const publicClient = viem.createPublicClient({
|
|
298
|
-
chain,
|
|
299
|
-
transport: viem.http(url)
|
|
300
|
-
});
|
|
301
|
-
const getGasPriceGwei = async () => {
|
|
302
|
-
const gasPriceWei = await publicClient.getGasPrice();
|
|
303
|
-
return parseFloat(viem.formatUnits(gasPriceWei, 9));
|
|
304
|
-
};
|
|
305
|
-
try {
|
|
306
|
-
const block = await publicClient.getBlock({ blockTag: "latest" });
|
|
307
|
-
const baseFeePerGas = block?.baseFeePerGas;
|
|
308
|
-
if (baseFeePerGas == null || baseFeePerGas === void 0) {
|
|
309
|
-
const gasPriceGwei2 = await getGasPriceGwei();
|
|
310
|
-
return { isEip1559: false, gasPriceGwei: gasPriceGwei2 };
|
|
311
|
-
}
|
|
312
|
-
const baseFeeGwei = parseFloat(viem.formatUnits(baseFeePerGas, 9));
|
|
313
|
-
let priorityFeeGwei;
|
|
314
|
-
try {
|
|
315
|
-
const priorityWei = await publicClient.estimateMaxPriorityFeePerGas();
|
|
316
|
-
priorityFeeGwei = parseFloat(viem.formatUnits(priorityWei, 9));
|
|
317
|
-
} catch {
|
|
318
|
-
}
|
|
319
|
-
const gasPriceGwei = await getGasPriceGwei();
|
|
320
|
-
return {
|
|
321
|
-
isEip1559: true,
|
|
322
|
-
baseFeeGwei,
|
|
323
|
-
priorityFeeGwei,
|
|
324
|
-
gasPriceGwei
|
|
325
|
-
};
|
|
326
|
-
} catch {
|
|
327
|
-
try {
|
|
328
|
-
const gasPriceWei = await publicClient.getGasPrice();
|
|
329
|
-
const gasPriceGwei = parseFloat(viem.formatUnits(gasPriceWei, 9));
|
|
330
|
-
return { isEip1559: false, gasPriceGwei };
|
|
331
|
-
} catch {
|
|
332
|
-
return { isEip1559: false };
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, floor, baseWei) {
|
|
337
|
-
let maxP = maxPriorityFeePerGas;
|
|
338
|
-
let maxF = maxFeePerGas;
|
|
339
|
-
if (baseWei > 0n && maxF < baseWei + maxP) {
|
|
340
|
-
maxF = baseWei + maxP + viem.parseGwei("0.001");
|
|
341
|
-
}
|
|
342
|
-
if (maxF < maxP) {
|
|
343
|
-
maxF = baseWei > 0n ? baseWei + maxP + viem.parseGwei("0.001") : maxP * 2n;
|
|
344
|
-
}
|
|
345
|
-
return { maxFeePerGas: maxF, maxPriorityFeePerGas: maxP };
|
|
346
|
-
}
|
|
347
|
-
function alignEip1559FeesWithLatestBase(maxFeePerGas, maxPriorityFeePerGas, latestBlockBaseFeeWei) {
|
|
348
|
-
return finalizeEip1559Fees(maxFeePerGas, maxPriorityFeePerGas, null, latestBlockBaseFeeWei);
|
|
349
|
-
}
|
|
350
|
-
function gweiToDecimalString(n) {
|
|
351
|
-
if (!Number.isFinite(n)) return "0";
|
|
352
|
-
if (n === 0) return "0";
|
|
353
|
-
const s = String(n);
|
|
354
|
-
if (s.indexOf("e") !== -1 || s.indexOf("E") !== -1) return n.toFixed(9).replace(/\.?0+$/, "") || "0";
|
|
355
|
-
return s;
|
|
356
|
-
}
|
|
357
165
|
|
|
358
166
|
// src/chains/evm/buildBatch.ts
|
|
359
167
|
async function buildEvmMultisignBatch(args) {
|
|
@@ -376,7 +184,7 @@ async function buildEvmMultisignBatch(args) {
|
|
|
376
184
|
rpcUrls: { default: { http: [rpcUrl] } }
|
|
377
185
|
});
|
|
378
186
|
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(rpcUrl) });
|
|
379
|
-
const feeParams = await fetchChainFeeParams(rpcUrl, chainId);
|
|
187
|
+
const feeParams = await continuumNodeSdk.fetchChainFeeParams(rpcUrl, chainId);
|
|
380
188
|
const legacy = Boolean(chainDetail?.legacy) || !feeParams.isEip1559;
|
|
381
189
|
const latestBaseFeeWei = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
382
190
|
const gasLimitConfig = useCustomGas && chainDetail?.gasLimit != null ? Number(chainDetail.gasLimit) : void 0;
|
|
@@ -389,15 +197,19 @@ async function buildEvmMultisignBatch(args) {
|
|
|
389
197
|
const step = steps[i];
|
|
390
198
|
const currentNonce = baseNonce + i;
|
|
391
199
|
let estimatedGas;
|
|
392
|
-
|
|
393
|
-
estimatedGas = await
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
200
|
+
if (args.estimateGasForStep) {
|
|
201
|
+
estimatedGas = await args.estimateGasForStep({ step, index: i, publicClient, executor });
|
|
202
|
+
} else {
|
|
203
|
+
try {
|
|
204
|
+
estimatedGas = await publicClient.estimateGas({
|
|
205
|
+
to: step.to,
|
|
206
|
+
data: step.data,
|
|
207
|
+
value: step.value,
|
|
208
|
+
account: executor
|
|
209
|
+
});
|
|
210
|
+
} catch {
|
|
211
|
+
estimatedGas = step.fallbackGas ?? 100000n;
|
|
212
|
+
}
|
|
401
213
|
}
|
|
402
214
|
let gasLimitI;
|
|
403
215
|
if (args.resolveGasLimit) {
|
|
@@ -405,7 +217,7 @@ async function buildEvmMultisignBatch(args) {
|
|
|
405
217
|
} else if (step.routerSwap) {
|
|
406
218
|
gasLimitI = routerSwapGasLimitFromEstimate(estimatedGas, chainGasLimitRouter);
|
|
407
219
|
} else {
|
|
408
|
-
gasLimitI = useCustomGas ? gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
220
|
+
gasLimitI = useCustomGas ? continuumNodeSdk.gasLimitFromEstimateAndChainConfig(estimatedGas, gasLimitConfig) : estimatedGas;
|
|
409
221
|
}
|
|
410
222
|
let proposalTxParams;
|
|
411
223
|
let feeSnapshot;
|
|
@@ -416,7 +228,7 @@ async function buildEvmMultisignBatch(args) {
|
|
|
416
228
|
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
417
229
|
}
|
|
418
230
|
if (useCustomGas && chainDetail?.gasPrice != null && chainDetail.gasPrice > 0) {
|
|
419
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
231
|
+
const configured = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(Number(chainDetail.gasPrice)));
|
|
420
232
|
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
421
233
|
}
|
|
422
234
|
serialized = viem.serializeTransaction({
|
|
@@ -435,7 +247,7 @@ async function buildEvmMultisignBatch(args) {
|
|
|
435
247
|
txType: "legacy",
|
|
436
248
|
gasPrice: gasPriceWei.toString()
|
|
437
249
|
};
|
|
438
|
-
feeSnapshot = proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
250
|
+
feeSnapshot = continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams);
|
|
439
251
|
} else {
|
|
440
252
|
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
441
253
|
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
@@ -446,13 +258,13 @@ async function buildEvmMultisignBatch(args) {
|
|
|
446
258
|
const baseFeeMultiplierPct = useCustomGas && chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(chainDetail.baseFeeMultiplier)) : 100;
|
|
447
259
|
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
448
260
|
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
449
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
450
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
261
|
+
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(continuumNodeSdk.gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
262
|
+
let maxFeePerGas = viem.parseGwei(continuumNodeSdk.gweiToDecimalString(maxFeePerGasGwei));
|
|
451
263
|
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
452
264
|
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
453
265
|
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
454
266
|
}
|
|
455
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
267
|
+
({ maxFeePerGas, maxPriorityFeePerGas } = continuumNodeSdk.alignEip1559FeesWithLatestBase(
|
|
456
268
|
maxFeePerGas,
|
|
457
269
|
maxPriorityFeePerGas,
|
|
458
270
|
latestBaseFeeWei
|
|
@@ -475,7 +287,7 @@ async function buildEvmMultisignBatch(args) {
|
|
|
475
287
|
maxFeePerGas: maxFeePerGas.toString(),
|
|
476
288
|
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
477
289
|
};
|
|
478
|
-
feeSnapshot = i === 0 ? proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
290
|
+
feeSnapshot = i === 0 ? continuumNodeSdk.proposalTxParamsToFeeSnapshot(proposalTxParams) : {};
|
|
479
291
|
}
|
|
480
292
|
const h = viem.keccak256(serialized);
|
|
481
293
|
const msgHash = h.startsWith("0x") ? h.slice(2) : h;
|
|
@@ -519,30 +331,6 @@ var evmChainCategoryModule = {
|
|
|
519
331
|
buildEvmMultisignBatch
|
|
520
332
|
};
|
|
521
333
|
|
|
522
|
-
// src/chains/evm/fees/customGas.ts
|
|
523
|
-
function chainSnapshotForCustomGasExtraJSON(chainDetail) {
|
|
524
|
-
const lr = chainDetail.legacy;
|
|
525
|
-
const legacy = lr === true || typeof lr === "string" && lr.toLowerCase() === "true";
|
|
526
|
-
const push = (o, key, v) => {
|
|
527
|
-
if (v === void 0 || v === null) return;
|
|
528
|
-
if (typeof v === "string" && v.trim() === "") return;
|
|
529
|
-
o[key] = v;
|
|
530
|
-
};
|
|
531
|
-
const fields = {};
|
|
532
|
-
push(fields, "gasLimit", chainDetail.gasLimit);
|
|
533
|
-
if (legacy) {
|
|
534
|
-
push(fields, "gasMultiplier", chainDetail.gasMultiplier);
|
|
535
|
-
push(fields, "gasPrice", chainDetail.gasPrice);
|
|
536
|
-
} else {
|
|
537
|
-
push(fields, "gasMultiplier", chainDetail.gasMultiplier);
|
|
538
|
-
push(fields, "baseFee", chainDetail.baseFee);
|
|
539
|
-
push(fields, "priorityFee", chainDetail.priorityFee);
|
|
540
|
-
push(fields, "baseFeeMultiplier", chainDetail.baseFeeMultiplier);
|
|
541
|
-
}
|
|
542
|
-
push(fields, "legacy", legacy);
|
|
543
|
-
return fields;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
334
|
// src/chains/evm/chainIdParse.ts
|
|
547
335
|
function parseEvmChainIdToNumber(chainId) {
|
|
548
336
|
if (chainId == null) return Number.NaN;
|
|
@@ -566,17 +354,55 @@ function parseEvmChainIdToNumber(chainId) {
|
|
|
566
354
|
}
|
|
567
355
|
return Number.parseInt(t, 10);
|
|
568
356
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
try {
|
|
575
|
-
const u = new URL(t);
|
|
576
|
-
return u.protocol === "http:" || u.protocol === "https:";
|
|
577
|
-
} catch {
|
|
578
|
-
return false;
|
|
357
|
+
function normalizeHumanDecimalAmount(raw, tokenDecimals) {
|
|
358
|
+
const t = raw.trim().replace(/,/g, "");
|
|
359
|
+
if (!t) return "";
|
|
360
|
+
if (!Number.isInteger(tokenDecimals) || tokenDecimals < 0 || tokenDecimals > 18) {
|
|
361
|
+
throw new Error("Invalid token decimals for amount normalization.");
|
|
579
362
|
}
|
|
363
|
+
const wei = viem.parseUnits(t, tokenDecimals);
|
|
364
|
+
return viem.formatUnits(wei, tokenDecimals);
|
|
365
|
+
}
|
|
366
|
+
var normalizeCurveRouterAmountString = normalizeHumanDecimalAmount;
|
|
367
|
+
|
|
368
|
+
// src/chains/evm/coingecko.ts
|
|
369
|
+
var COINGECKO_PLATFORM_BY_CHAIN_ID = {
|
|
370
|
+
"1": "ethereum",
|
|
371
|
+
"56": "binance-smart-chain",
|
|
372
|
+
"137": "polygon-pos",
|
|
373
|
+
"42161": "arbitrum-one",
|
|
374
|
+
"10": "optimistic-ethereum",
|
|
375
|
+
"43114": "avalanche",
|
|
376
|
+
"8453": "base",
|
|
377
|
+
"324": "zk-sync-era",
|
|
378
|
+
"42220": "celo",
|
|
379
|
+
"250": "fantom",
|
|
380
|
+
"100": "gnosis",
|
|
381
|
+
"204": "op-bnb",
|
|
382
|
+
"534352": "scroll",
|
|
383
|
+
"5000": "mantle",
|
|
384
|
+
"169": "manta-pacific",
|
|
385
|
+
"1116": "core",
|
|
386
|
+
"30": "rootstock",
|
|
387
|
+
"288": "boba",
|
|
388
|
+
"1088": "metis-andromeda",
|
|
389
|
+
"34443": "mode",
|
|
390
|
+
"80084": "berachain",
|
|
391
|
+
"146": "sonic",
|
|
392
|
+
"60808": "bob-network",
|
|
393
|
+
"80094": "berachain",
|
|
394
|
+
"130": "unichain",
|
|
395
|
+
"57073": "ink",
|
|
396
|
+
"999": "hyperevm",
|
|
397
|
+
"239": "tac",
|
|
398
|
+
"9745": "plasma",
|
|
399
|
+
"1923": "swellchain",
|
|
400
|
+
"59144": "linea",
|
|
401
|
+
"81457": "blast",
|
|
402
|
+
"7777777": "zora"
|
|
403
|
+
};
|
|
404
|
+
function coingeckoPlatformForChainId(chainId) {
|
|
405
|
+
return COINGECKO_PLATFORM_BY_CHAIN_ID[String(chainId).trim()];
|
|
580
406
|
}
|
|
581
407
|
|
|
582
408
|
// src/chains/solana/types.ts
|
|
@@ -696,7 +522,7 @@ async function fetchEthereumAddressForKeyGen(managementNodeUrl, keyGenId, readAu
|
|
|
696
522
|
throw new Error("keyGen is required");
|
|
697
523
|
}
|
|
698
524
|
const url = `${base}/getKeyGenResultById?id=${encodeURIComponent(id)}`;
|
|
699
|
-
const res = await nodeFetchWithReadAuth(url, { ...init, method: "GET", cache: "no-store" }, readAuth);
|
|
525
|
+
const res = await continuumNodeSdk.nodeFetchWithReadAuth(url, { ...init, method: "GET", cache: "no-store" }, readAuth);
|
|
700
526
|
if (!res.ok) {
|
|
701
527
|
const t = await res.text().catch(() => "");
|
|
702
528
|
throw new Error(
|
|
@@ -1002,6 +828,35 @@ async function uniswapCreateSwap(args) {
|
|
|
1002
828
|
}
|
|
1003
829
|
return parsed;
|
|
1004
830
|
}
|
|
831
|
+
async function estimateUniswapRouterSwapGas(args) {
|
|
832
|
+
const fromTradeApi = parseOptionalGasLimitString(args.swapRecord.gasLimit) ?? parseOptionalGasLimitString(args.swapRecord.gas);
|
|
833
|
+
if (fromTradeApi != null && fromTradeApi > 0n) {
|
|
834
|
+
return { baseGasUnits: fromTradeApi, source: "tradeApi" };
|
|
835
|
+
}
|
|
836
|
+
try {
|
|
837
|
+
const est = await args.publicClient.estimateGas({
|
|
838
|
+
to: args.to,
|
|
839
|
+
data: args.data,
|
|
840
|
+
value: args.value,
|
|
841
|
+
account: args.executor
|
|
842
|
+
});
|
|
843
|
+
return { baseGasUnits: est, source: "rpcEstimate" };
|
|
844
|
+
} catch (e) {
|
|
845
|
+
const estimateGasError = e instanceof Error ? e.message : String(e);
|
|
846
|
+
const minRouterGas = 500000n;
|
|
847
|
+
if (args.useCustomGas) {
|
|
848
|
+
const cfg = args.chainDetail?.gasLimit != null ? parseOptionalGasLimitString(String(args.chainDetail.gasLimit)) : null;
|
|
849
|
+
if (cfg != null && cfg >= minRouterGas) {
|
|
850
|
+
return { baseGasUnits: cfg, source: "estimateFailedFallback", estimateGasError };
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
return {
|
|
854
|
+
baseGasUnits: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK,
|
|
855
|
+
source: "estimateFailedFallback",
|
|
856
|
+
estimateGasError
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
}
|
|
1005
860
|
var permit2ApproveRouterAbi = [
|
|
1006
861
|
{
|
|
1007
862
|
name: "approve",
|
|
@@ -1102,10 +957,6 @@ function permit2SpenderAndApproveWeiFromSwapCalldata(dataHex, tokenIn, quoteInpu
|
|
|
1102
957
|
}
|
|
1103
958
|
}
|
|
1104
959
|
async function buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei) {
|
|
1105
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1106
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1107
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1108
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1109
960
|
const toRouter = viem.getAddress(
|
|
1110
961
|
(args.swap.to ?? "").trim().startsWith("0x") ? args.swap.to.trim() : `0x${args.swap.to.trim()}`
|
|
1111
962
|
);
|
|
@@ -1123,214 +974,90 @@ async function buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei) {
|
|
|
1123
974
|
"Native (ETH) in swap: could not determine payable value (no `swap.value`, no `execute` amount in calldata, and quote input is zero). Refresh the quote and request /swap again."
|
|
1124
975
|
);
|
|
1125
976
|
}
|
|
1126
|
-
const ch = viem.defineChain({
|
|
1127
|
-
id: args.chainId,
|
|
1128
|
-
name: "Destination",
|
|
1129
|
-
nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" },
|
|
1130
|
-
rpcUrls: { default: { http: [args.rpcUrl] } }
|
|
1131
|
-
});
|
|
1132
|
-
const publicClient = viem.createPublicClient({ chain: ch, transport: viem.http(args.rpcUrl) });
|
|
1133
|
-
const feeParams = await fetchChainFeeParams(args.rpcUrl, args.chainId);
|
|
1134
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1135
|
-
const latestBaseFeeWeiNativeIn = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1136
|
-
const useCustomGas = args.useCustomGas;
|
|
1137
|
-
const chainGasLimitRouter = args.chainDetail?.gasLimit != null && Number.isFinite(Number(args.chainDetail.gasLimit)) && Number(args.chainDetail.gasLimit) > 0 ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1138
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
1139
|
-
const nonce = await publicClient.getTransactionCount({ address: args.executorAddress, blockTag: "pending" });
|
|
1140
|
-
const proposalTxParamsBatch = [];
|
|
1141
|
-
const messageHashes = [];
|
|
1142
|
-
const messageRawBatch = [];
|
|
1143
977
|
const swapRecord = args.swap;
|
|
1144
|
-
const fromTradeApi = parseOptionalGasLimitString(swapRecord.gasLimit) ?? parseOptionalGasLimitString(swapRecord.gas);
|
|
1145
978
|
let gasBuildSource = "rpcEstimate";
|
|
1146
979
|
let estimateGasError;
|
|
1147
|
-
let
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
980
|
+
let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
981
|
+
const dataNo0x = dataHex.startsWith("0x") ? dataHex.slice(2) : dataHex;
|
|
982
|
+
const purposeSuffix = "Uniswap V4: 1-tx batch \u2014 native gas token in (no ERC-20 approve) \u2014 single payable swap (Trade /swap).";
|
|
983
|
+
return buildEvmMultisignBatch({
|
|
984
|
+
context: {
|
|
985
|
+
chainCategory: "evm",
|
|
986
|
+
keyGen: args.keyGen,
|
|
987
|
+
purposeText: args.purposeText,
|
|
988
|
+
chainId: args.chainId,
|
|
989
|
+
rpcUrl: args.rpcUrl,
|
|
990
|
+
executorAddress: args.executorAddress,
|
|
991
|
+
chainDetail: args.chainDetail,
|
|
992
|
+
useCustomGas: args.useCustomGas,
|
|
993
|
+
customGasChainDetails: args.customGasChainDetails
|
|
994
|
+
},
|
|
995
|
+
steps: [
|
|
996
|
+
{
|
|
1154
997
|
to: toRouter,
|
|
1155
998
|
data: dataHex,
|
|
1156
999
|
value: valueWei,
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
gasBuildSource = "rpcEstimate";
|
|
1160
|
-
} catch (e) {
|
|
1161
|
-
estimateGasError = e instanceof Error ? e.message : String(e);
|
|
1162
|
-
const minRouterGas = 500000n;
|
|
1163
|
-
if (useCustomGas) {
|
|
1164
|
-
const cfg = args.chainDetail?.gasLimit != null ? parseOptionalGasLimitString(String(args.chainDetail.gasLimit)) : null;
|
|
1165
|
-
if (cfg != null && cfg >= minRouterGas) {
|
|
1166
|
-
baseGasUnits1 = cfg;
|
|
1167
|
-
} else {
|
|
1168
|
-
baseGasUnits1 = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
1169
|
-
}
|
|
1170
|
-
} else {
|
|
1171
|
-
baseGasUnits1 = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
1172
|
-
}
|
|
1173
|
-
gasBuildSource = "estimateFailedFallback";
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
const gasLimit1 = routerSwapGasLimitFromEstimate(baseGasUnits1, chainGasLimitRouter);
|
|
1177
|
-
const currentNonce0 = nonce;
|
|
1178
|
-
let firstTxFeePayload = {};
|
|
1179
|
-
if (legacy) {
|
|
1180
|
-
let gasPriceWei1 = await publicClient.getGasPrice();
|
|
1181
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1182
|
-
gasPriceWei1 = gasPriceWei1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1183
|
-
}
|
|
1184
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
1185
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
1186
|
-
if (configured > gasPriceWei1) gasPriceWei1 = configured;
|
|
1187
|
-
}
|
|
1188
|
-
firstTxFeePayload = { txNonce: nonce, txGasLimit: gasLimit1.toString(), txGasPrice: gasPriceWei1.toString() };
|
|
1189
|
-
const ser0 = viem.serializeTransaction({
|
|
1190
|
-
type: "legacy",
|
|
1191
|
-
to: toRouter,
|
|
1192
|
-
data: dataHex,
|
|
1193
|
-
value: valueWei,
|
|
1194
|
-
gas: gasLimit1,
|
|
1195
|
-
gasPrice: gasPriceWei1,
|
|
1196
|
-
nonce: currentNonce0,
|
|
1197
|
-
chainId: args.chainId
|
|
1198
|
-
});
|
|
1199
|
-
const h0 = viem.keccak256(ser0);
|
|
1200
|
-
messageHashes.push(h0.startsWith("0x") ? h0.slice(2) : h0);
|
|
1201
|
-
messageRawBatch.push(ser0);
|
|
1202
|
-
proposalTxParamsBatch.push({
|
|
1203
|
-
nonce: currentNonce0,
|
|
1204
|
-
gasLimit: gasLimit1.toString(),
|
|
1205
|
-
txType: "legacy",
|
|
1206
|
-
gasPrice: gasPriceWei1.toString()
|
|
1207
|
-
});
|
|
1208
|
-
} else {
|
|
1209
|
-
const fetchedBase1 = feeParams.baseFeeGwei ?? 0;
|
|
1210
|
-
const fetchedPriority1 = feeParams.priorityFeeGwei ?? 0;
|
|
1211
|
-
const configuredBase1 = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1212
|
-
const configuredPriority1 = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1213
|
-
const effectiveBaseFeeGwei1 = Math.max(fetchedBase1, configuredBase1);
|
|
1214
|
-
const effectivePriorityFeeGwei1 = Math.max(fetchedPriority1, configuredPriority1);
|
|
1215
|
-
const baseFeeMultiplierPct1 = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1216
|
-
const baseComponentGwei1 = effectiveBaseFeeGwei1 * baseFeeMultiplierPct1 / 100;
|
|
1217
|
-
const maxFeePerGasGwei1 = baseComponentGwei1 + effectivePriorityFeeGwei1;
|
|
1218
|
-
let maxPriorityFeePerGas1 = effectivePriorityFeeGwei1 > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei1)) : viem.parseGwei("1");
|
|
1219
|
-
let maxFeePerGas1 = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei1));
|
|
1220
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1221
|
-
maxPriorityFeePerGas1 = maxPriorityFeePerGas1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1222
|
-
maxFeePerGas1 = maxFeePerGas1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1223
|
-
}
|
|
1224
|
-
({ maxFeePerGas: maxFeePerGas1, maxPriorityFeePerGas: maxPriorityFeePerGas1 } = alignEip1559FeesWithLatestBase(maxFeePerGas1, maxPriorityFeePerGas1, latestBaseFeeWeiNativeIn));
|
|
1225
|
-
firstTxFeePayload = {
|
|
1226
|
-
txNonce: nonce,
|
|
1227
|
-
txGasLimit: gasLimit1.toString(),
|
|
1228
|
-
txMaxFeePerGas: maxFeePerGas1.toString(),
|
|
1229
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas1.toString()
|
|
1230
|
-
};
|
|
1231
|
-
const ser0 = viem.serializeTransaction({
|
|
1232
|
-
type: "eip1559",
|
|
1233
|
-
to: toRouter,
|
|
1234
|
-
data: dataHex,
|
|
1235
|
-
value: valueWei,
|
|
1236
|
-
gas: gasLimit1,
|
|
1237
|
-
maxFeePerGas: maxFeePerGas1,
|
|
1238
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas1,
|
|
1239
|
-
nonce: currentNonce0,
|
|
1240
|
-
chainId: args.chainId
|
|
1241
|
-
});
|
|
1242
|
-
const h0 = viem.keccak256(ser0);
|
|
1243
|
-
messageHashes.push(h0.startsWith("0x") ? h0.slice(2) : h0);
|
|
1244
|
-
messageRawBatch.push(ser0);
|
|
1245
|
-
proposalTxParamsBatch.push({
|
|
1246
|
-
nonce: currentNonce0,
|
|
1247
|
-
gasLimit: gasLimit1.toString(),
|
|
1248
|
-
txType: "eip1559",
|
|
1249
|
-
maxFeePerGas: maxFeePerGas1.toString(),
|
|
1250
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas1.toString()
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
const dataNo0x = dataHex.startsWith("0x") ? dataHex.slice(2) : dataHex;
|
|
1254
|
-
const audit = {
|
|
1255
|
-
skipPermit2Batch: true,
|
|
1256
|
-
inputKind: "native_eth",
|
|
1257
|
-
noErc20Approve: true,
|
|
1258
|
-
quoteInputWei: quoteInputWei.toString(),
|
|
1259
|
-
swapValueWei: valueWei.toString(),
|
|
1260
|
-
uniswapCreateSwap: {
|
|
1261
|
-
requestId: args.createSwapResponse.requestId,
|
|
1262
|
-
gasFee: args.createSwapResponse.gasFee,
|
|
1263
|
-
gasBuildSwap: {
|
|
1264
|
-
useCustomGas,
|
|
1265
|
-
source: gasBuildSource,
|
|
1266
|
-
baseGasUnits: baseGasUnits1.toString(),
|
|
1267
|
-
...estimateGasError != null && estimateGasError !== "" ? { estimateGasError } : {}
|
|
1268
|
-
},
|
|
1269
|
-
swap: {
|
|
1270
|
-
to: args.createSwapResponse.swap.to,
|
|
1271
|
-
value: args.createSwapResponse.swap.value,
|
|
1272
|
-
dataNibbles: (() => {
|
|
1273
|
-
const t = (args.createSwapResponse.swap.data ?? "").toString().trim();
|
|
1274
|
-
return t.startsWith("0x") ? t.length - 2 : t.length;
|
|
1275
|
-
})()
|
|
1000
|
+
routerSwap: true,
|
|
1001
|
+
fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK
|
|
1276
1002
|
}
|
|
1003
|
+
],
|
|
1004
|
+
purposeSuffix,
|
|
1005
|
+
firstMsgRawNo0x: dataNo0x,
|
|
1006
|
+
destinationAddress: toRouter,
|
|
1007
|
+
estimateGasForStep: async ({ publicClient, executor }) => {
|
|
1008
|
+
const r = await estimateUniswapRouterSwapGas({
|
|
1009
|
+
publicClient,
|
|
1010
|
+
executor,
|
|
1011
|
+
to: toRouter,
|
|
1012
|
+
data: dataHex,
|
|
1013
|
+
value: valueWei,
|
|
1014
|
+
swapRecord,
|
|
1015
|
+
useCustomGas: args.useCustomGas,
|
|
1016
|
+
chainDetail: args.chainDetail
|
|
1017
|
+
});
|
|
1018
|
+
gasBuildSource = r.source;
|
|
1019
|
+
estimateGasError = r.estimateGasError;
|
|
1020
|
+
swapBaseGasUnits = r.baseGasUnits;
|
|
1021
|
+
return r.baseGasUnits;
|
|
1277
1022
|
},
|
|
1278
|
-
|
|
1279
|
-
originalPurpose: args.purposeText
|
|
1280
|
-
};
|
|
1281
|
-
const batchMeta = [
|
|
1282
|
-
{
|
|
1283
|
-
destinationAddress: toRouter,
|
|
1023
|
+
buildBatchMeta: () => ({
|
|
1284
1024
|
signatureText: JSON.stringify({
|
|
1285
1025
|
kind: "UniswapV4",
|
|
1286
1026
|
name: "UniversalRouter (payable, native in)",
|
|
1287
1027
|
note: "Single tx from Trade POST /swap; no ERC-20 approve. Calldata in messageHashes[0] / messageRawBatch[0]."
|
|
1288
1028
|
}),
|
|
1289
1029
|
evm: { type: "uniswap_v4_swap_tx", version: 1, chainId: String(args.chainId) },
|
|
1290
|
-
uniswapV4:
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
})(),
|
|
1320
|
-
...firstTxFeePayload,
|
|
1321
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1322
|
-
};
|
|
1323
|
-
if (valueWei > 0n) {
|
|
1324
|
-
bodyForSign.value = valueWei.toString();
|
|
1325
|
-
}
|
|
1326
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1327
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1030
|
+
uniswapV4: {
|
|
1031
|
+
skipPermit2Batch: true,
|
|
1032
|
+
inputKind: "native_eth",
|
|
1033
|
+
noErc20Approve: true,
|
|
1034
|
+
quoteInputWei: quoteInputWei.toString(),
|
|
1035
|
+
swapValueWei: valueWei.toString(),
|
|
1036
|
+
uniswapCreateSwap: {
|
|
1037
|
+
requestId: args.createSwapResponse.requestId,
|
|
1038
|
+
gasFee: args.createSwapResponse.gasFee,
|
|
1039
|
+
gasBuildSwap: {
|
|
1040
|
+
useCustomGas: args.useCustomGas,
|
|
1041
|
+
source: gasBuildSource,
|
|
1042
|
+
baseGasUnits: swapBaseGasUnits.toString(),
|
|
1043
|
+
...estimateGasError != null && estimateGasError !== "" ? { estimateGasError } : {}
|
|
1044
|
+
},
|
|
1045
|
+
swap: {
|
|
1046
|
+
to: args.createSwapResponse.swap.to,
|
|
1047
|
+
value: args.createSwapResponse.swap.value,
|
|
1048
|
+
dataNibbles: (() => {
|
|
1049
|
+
const t = (args.createSwapResponse.swap.data ?? "").toString().trim();
|
|
1050
|
+
return t.startsWith("0x") ? t.length - 2 : t.length;
|
|
1051
|
+
})()
|
|
1052
|
+
}
|
|
1053
|
+
},
|
|
1054
|
+
fullQuoteFromPermitSnapshot: args.fullQuoteSnapshot,
|
|
1055
|
+
originalPurpose: args.purposeText
|
|
1056
|
+
}
|
|
1057
|
+
})
|
|
1058
|
+
});
|
|
1328
1059
|
}
|
|
1329
1060
|
async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
|
|
1330
|
-
const ph = (args.keyGen.pubkeyhex ?? "").trim();
|
|
1331
|
-
if (!ph) throw new Error("keyGen pubKey (pubkeyhex) is required");
|
|
1332
|
-
const keyList = args.keyGen.keylist ?? [];
|
|
1333
|
-
const clientId = firstClientIdFromKeyGen(args.keyGen);
|
|
1334
1061
|
const tokenIn = viem.getAddress(args.tokenIn);
|
|
1335
1062
|
const parsedInOut = parseUniswapQuoteClassicInOut(args.fullQuoteSnapshot);
|
|
1336
1063
|
const quoteInputWei = parsedInOut?.inputWei;
|
|
@@ -1385,298 +1112,33 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
|
|
|
1385
1112
|
return 0n;
|
|
1386
1113
|
}
|
|
1387
1114
|
})();
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
const legacy = Boolean(args.chainDetail?.legacy) || !feeParams.isEip1559;
|
|
1397
|
-
const latestBaseFeeWeiSkipBatch = !legacy ? (await publicClient.getBlock({ blockTag: "latest" })).baseFeePerGas ?? 0n : 0n;
|
|
1398
|
-
const useCustomGas = args.useCustomGas;
|
|
1399
|
-
const gasLimitConfig = useCustomGas && args.chainDetail?.gasLimit != null ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1400
|
-
const chainGasLimitRouter = args.chainDetail?.gasLimit != null && Number.isFinite(Number(args.chainDetail.gasLimit)) && Number(args.chainDetail.gasLimit) > 0 ? Number(args.chainDetail.gasLimit) : void 0;
|
|
1401
|
-
const gasFeeMultiplier = useCustomGas && args.chainDetail?.gasMultiplier != null ? Number(args.chainDetail.gasMultiplier) : void 0;
|
|
1402
|
-
const nonce = await publicClient.getTransactionCount({ address: args.executorAddress, blockTag: "pending" });
|
|
1403
|
-
const proposalTxParamsBatch = [];
|
|
1404
|
-
const messageHashes = [];
|
|
1405
|
-
const messageRawBatch = [];
|
|
1406
|
-
const approveMsgRawNo0x = approveData.startsWith("0x") ? approveData.slice(2) : approveData;
|
|
1407
|
-
let firstTxFeePayload = {};
|
|
1408
|
-
const approveGas = await publicClient.estimateGas({
|
|
1409
|
-
to: tokenIn,
|
|
1410
|
-
data: approveData,
|
|
1411
|
-
value: 0n,
|
|
1412
|
-
account: args.executorAddress
|
|
1413
|
-
});
|
|
1414
|
-
const gasLimit0 = useCustomGas ? gasLimitFromEstimateAndChainConfig(approveGas, gasLimitConfig) : approveGas;
|
|
1415
|
-
const currentNonce0 = nonce;
|
|
1416
|
-
if (legacy) {
|
|
1417
|
-
let gasPriceWei = await publicClient.getGasPrice();
|
|
1418
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1419
|
-
gasPriceWei = gasPriceWei * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1420
|
-
}
|
|
1421
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
1422
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
1423
|
-
if (configured > gasPriceWei) gasPriceWei = configured;
|
|
1424
|
-
}
|
|
1425
|
-
firstTxFeePayload = { txNonce: nonce, txGasLimit: gasLimit0.toString(), txGasPrice: gasPriceWei.toString() };
|
|
1426
|
-
const ser0 = viem.serializeTransaction({
|
|
1427
|
-
type: "legacy",
|
|
1428
|
-
to: tokenIn,
|
|
1429
|
-
data: approveData,
|
|
1430
|
-
value: 0n,
|
|
1431
|
-
gas: gasLimit0,
|
|
1432
|
-
gasPrice: gasPriceWei,
|
|
1433
|
-
nonce: currentNonce0,
|
|
1434
|
-
chainId: args.chainId
|
|
1435
|
-
});
|
|
1436
|
-
const h0 = viem.keccak256(ser0);
|
|
1437
|
-
messageHashes.push(h0.startsWith("0x") ? h0.slice(2) : h0);
|
|
1438
|
-
messageRawBatch.push(ser0);
|
|
1439
|
-
proposalTxParamsBatch.push({
|
|
1440
|
-
nonce: currentNonce0,
|
|
1441
|
-
gasLimit: gasLimit0.toString(),
|
|
1442
|
-
txType: "legacy",
|
|
1443
|
-
gasPrice: gasPriceWei.toString()
|
|
1444
|
-
});
|
|
1445
|
-
} else {
|
|
1446
|
-
const fetchedBase = feeParams.baseFeeGwei ?? 0;
|
|
1447
|
-
const fetchedPriority = feeParams.priorityFeeGwei ?? 0;
|
|
1448
|
-
const configuredBase = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1449
|
-
const configuredPriority = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1450
|
-
const effectiveBaseFeeGwei = Math.max(fetchedBase, configuredBase);
|
|
1451
|
-
const effectivePriorityFeeGwei = Math.max(fetchedPriority, configuredPriority);
|
|
1452
|
-
const baseFeeMultiplierPct = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1453
|
-
const baseComponentGwei = effectiveBaseFeeGwei * baseFeeMultiplierPct / 100;
|
|
1454
|
-
const maxFeePerGasGwei = baseComponentGwei + effectivePriorityFeeGwei;
|
|
1455
|
-
let maxPriorityFeePerGas = effectivePriorityFeeGwei > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei)) : viem.parseGwei("1");
|
|
1456
|
-
let maxFeePerGas = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei));
|
|
1457
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1458
|
-
maxPriorityFeePerGas = maxPriorityFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1459
|
-
maxFeePerGas = maxFeePerGas * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1460
|
-
}
|
|
1461
|
-
({ maxFeePerGas, maxPriorityFeePerGas } = alignEip1559FeesWithLatestBase(
|
|
1462
|
-
maxFeePerGas,
|
|
1463
|
-
maxPriorityFeePerGas,
|
|
1464
|
-
latestBaseFeeWeiSkipBatch
|
|
1465
|
-
));
|
|
1466
|
-
firstTxFeePayload = {
|
|
1467
|
-
txNonce: nonce,
|
|
1468
|
-
txGasLimit: gasLimit0.toString(),
|
|
1469
|
-
txMaxFeePerGas: maxFeePerGas.toString(),
|
|
1470
|
-
txMaxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1471
|
-
};
|
|
1472
|
-
const ser0 = viem.serializeTransaction({
|
|
1473
|
-
type: "eip1559",
|
|
1474
|
-
to: tokenIn,
|
|
1475
|
-
data: approveData,
|
|
1476
|
-
value: 0n,
|
|
1477
|
-
gas: gasLimit0,
|
|
1478
|
-
maxFeePerGas,
|
|
1479
|
-
maxPriorityFeePerGas,
|
|
1480
|
-
nonce: currentNonce0,
|
|
1481
|
-
chainId: args.chainId
|
|
1482
|
-
});
|
|
1483
|
-
const h0 = viem.keccak256(ser0);
|
|
1484
|
-
messageHashes.push(h0.startsWith("0x") ? h0.slice(2) : h0);
|
|
1485
|
-
messageRawBatch.push(ser0);
|
|
1486
|
-
proposalTxParamsBatch.push({
|
|
1487
|
-
nonce: currentNonce0,
|
|
1488
|
-
gasLimit: gasLimit0.toString(),
|
|
1489
|
-
txType: "eip1559",
|
|
1490
|
-
maxFeePerGas: maxFeePerGas.toString(),
|
|
1491
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas.toString()
|
|
1492
|
-
});
|
|
1493
|
-
}
|
|
1115
|
+
const swapRecord = args.swap;
|
|
1116
|
+
const swapMsgIndex = usePermit2Triple ? 2 : 1;
|
|
1117
|
+
let gasBuildSource = "rpcEstimate";
|
|
1118
|
+
let estimateGasError;
|
|
1119
|
+
let swapBaseGasUnits = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
1120
|
+
const steps = [
|
|
1121
|
+
{ to: tokenIn, data: approveData, value: 0n, fallbackGas: 100000n }
|
|
1122
|
+
];
|
|
1494
1123
|
if (usePermit2Triple) {
|
|
1495
1124
|
const permit2ApproveData = viem.encodeFunctionData({
|
|
1496
1125
|
abi: permit2ApproveRouterAbi,
|
|
1497
1126
|
functionName: "approve",
|
|
1498
1127
|
args: [tokenIn, permit2Spender, approveAmountWei, Number(expiration48)]
|
|
1499
1128
|
});
|
|
1500
|
-
|
|
1501
|
-
to: PERMIT2_ADDRESS,
|
|
1502
|
-
data: permit2ApproveData,
|
|
1503
|
-
value: 0n,
|
|
1504
|
-
account: args.executorAddress
|
|
1505
|
-
});
|
|
1506
|
-
const gasLimitP2 = useCustomGas ? gasLimitFromEstimateAndChainConfig(approveP2Gas, gasLimitConfig) : approveP2Gas;
|
|
1507
|
-
const currentNonceP2 = nonce + 1;
|
|
1508
|
-
if (legacy) {
|
|
1509
|
-
let gasPriceWeiP2 = await publicClient.getGasPrice();
|
|
1510
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1511
|
-
gasPriceWeiP2 = gasPriceWeiP2 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1512
|
-
}
|
|
1513
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
1514
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
1515
|
-
if (configured > gasPriceWeiP2) gasPriceWeiP2 = configured;
|
|
1516
|
-
}
|
|
1517
|
-
const serP2 = viem.serializeTransaction({
|
|
1518
|
-
type: "legacy",
|
|
1519
|
-
to: PERMIT2_ADDRESS,
|
|
1520
|
-
data: permit2ApproveData,
|
|
1521
|
-
value: 0n,
|
|
1522
|
-
gas: gasLimitP2,
|
|
1523
|
-
gasPrice: gasPriceWeiP2,
|
|
1524
|
-
nonce: currentNonceP2,
|
|
1525
|
-
chainId: args.chainId
|
|
1526
|
-
});
|
|
1527
|
-
const hP2 = viem.keccak256(serP2);
|
|
1528
|
-
messageHashes.push(hP2.startsWith("0x") ? hP2.slice(2) : hP2);
|
|
1529
|
-
messageRawBatch.push(serP2);
|
|
1530
|
-
proposalTxParamsBatch.push({
|
|
1531
|
-
nonce: currentNonceP2,
|
|
1532
|
-
gasLimit: gasLimitP2.toString(),
|
|
1533
|
-
txType: "legacy",
|
|
1534
|
-
gasPrice: gasPriceWeiP2.toString()
|
|
1535
|
-
});
|
|
1536
|
-
} else {
|
|
1537
|
-
const fetchedBaseP2 = feeParams.baseFeeGwei ?? 0;
|
|
1538
|
-
const fetchedPriorityP2 = feeParams.priorityFeeGwei ?? 0;
|
|
1539
|
-
const configuredBaseP2 = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1540
|
-
const configuredPriorityP2 = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1541
|
-
const effectiveBaseFeeGweiP2 = Math.max(fetchedBaseP2, configuredBaseP2);
|
|
1542
|
-
const effectivePriorityFeeGweiP2 = Math.max(fetchedPriorityP2, configuredPriorityP2);
|
|
1543
|
-
const baseFeeMultiplierPctP2 = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1544
|
-
const baseComponentGweiP2 = effectiveBaseFeeGweiP2 * baseFeeMultiplierPctP2 / 100;
|
|
1545
|
-
const maxFeePerGasGweiP2 = baseComponentGweiP2 + effectivePriorityFeeGweiP2;
|
|
1546
|
-
let maxPriorityFeePerGasP2 = effectivePriorityFeeGweiP2 > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGweiP2)) : viem.parseGwei("1");
|
|
1547
|
-
let maxFeePerGasP2 = viem.parseGwei(gweiToDecimalString(maxFeePerGasGweiP2));
|
|
1548
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1549
|
-
maxPriorityFeePerGasP2 = maxPriorityFeePerGasP2 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1550
|
-
maxFeePerGasP2 = maxFeePerGasP2 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1551
|
-
}
|
|
1552
|
-
({ maxFeePerGas: maxFeePerGasP2, maxPriorityFeePerGas: maxPriorityFeePerGasP2 } = alignEip1559FeesWithLatestBase(maxFeePerGasP2, maxPriorityFeePerGasP2, latestBaseFeeWeiSkipBatch));
|
|
1553
|
-
const serP2 = viem.serializeTransaction({
|
|
1554
|
-
type: "eip1559",
|
|
1555
|
-
to: PERMIT2_ADDRESS,
|
|
1556
|
-
data: permit2ApproveData,
|
|
1557
|
-
value: 0n,
|
|
1558
|
-
gas: gasLimitP2,
|
|
1559
|
-
maxFeePerGas: maxFeePerGasP2,
|
|
1560
|
-
maxPriorityFeePerGas: maxPriorityFeePerGasP2,
|
|
1561
|
-
nonce: currentNonceP2,
|
|
1562
|
-
chainId: args.chainId
|
|
1563
|
-
});
|
|
1564
|
-
const hP2 = viem.keccak256(serP2);
|
|
1565
|
-
messageHashes.push(hP2.startsWith("0x") ? hP2.slice(2) : hP2);
|
|
1566
|
-
messageRawBatch.push(serP2);
|
|
1567
|
-
proposalTxParamsBatch.push({
|
|
1568
|
-
nonce: currentNonceP2,
|
|
1569
|
-
gasLimit: gasLimitP2.toString(),
|
|
1570
|
-
txType: "eip1559",
|
|
1571
|
-
maxFeePerGas: maxFeePerGasP2.toString(),
|
|
1572
|
-
maxPriorityFeePerGas: maxPriorityFeePerGasP2.toString()
|
|
1573
|
-
});
|
|
1574
|
-
}
|
|
1129
|
+
steps.push({ to: PERMIT2_ADDRESS, data: permit2ApproveData, value: 0n, fallbackGas: 100000n });
|
|
1575
1130
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
to: toRouter,
|
|
1588
|
-
data: dataHex,
|
|
1589
|
-
value: valueWei,
|
|
1590
|
-
account: args.executorAddress
|
|
1591
|
-
});
|
|
1592
|
-
gasBuildSource = "rpcEstimate";
|
|
1593
|
-
} catch (e) {
|
|
1594
|
-
estimateGasError = e instanceof Error ? e.message : String(e);
|
|
1595
|
-
const minRouterGas = 500000n;
|
|
1596
|
-
if (useCustomGas) {
|
|
1597
|
-
const cfg = args.chainDetail?.gasLimit != null ? parseOptionalGasLimitString(String(args.chainDetail.gasLimit)) : null;
|
|
1598
|
-
if (cfg != null && cfg >= minRouterGas) {
|
|
1599
|
-
baseGasUnits1 = cfg;
|
|
1600
|
-
} else {
|
|
1601
|
-
baseGasUnits1 = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
1602
|
-
}
|
|
1603
|
-
} else {
|
|
1604
|
-
baseGasUnits1 = DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK;
|
|
1605
|
-
}
|
|
1606
|
-
gasBuildSource = "estimateFailedFallback";
|
|
1607
|
-
}
|
|
1608
|
-
}
|
|
1609
|
-
const gasLimit1 = routerSwapGasLimitFromEstimate(baseGasUnits1, chainGasLimitRouter);
|
|
1610
|
-
const currentNonce1 = nonce + (usePermit2Triple ? 2 : 1);
|
|
1611
|
-
if (legacy) {
|
|
1612
|
-
let gasPriceWei1 = await publicClient.getGasPrice();
|
|
1613
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1614
|
-
gasPriceWei1 = gasPriceWei1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1615
|
-
}
|
|
1616
|
-
if (useCustomGas && args.chainDetail?.gasPrice != null && args.chainDetail.gasPrice > 0) {
|
|
1617
|
-
const configured = viem.parseGwei(gweiToDecimalString(Number(args.chainDetail.gasPrice)));
|
|
1618
|
-
if (configured > gasPriceWei1) gasPriceWei1 = configured;
|
|
1619
|
-
}
|
|
1620
|
-
const ser1 = viem.serializeTransaction({
|
|
1621
|
-
type: "legacy",
|
|
1622
|
-
to: toRouter,
|
|
1623
|
-
data: dataHex,
|
|
1624
|
-
value: valueWei,
|
|
1625
|
-
gas: gasLimit1,
|
|
1626
|
-
gasPrice: gasPriceWei1,
|
|
1627
|
-
nonce: currentNonce1,
|
|
1628
|
-
chainId: args.chainId
|
|
1629
|
-
});
|
|
1630
|
-
const h1 = viem.keccak256(ser1);
|
|
1631
|
-
messageHashes.push(h1.startsWith("0x") ? h1.slice(2) : h1);
|
|
1632
|
-
messageRawBatch.push(ser1);
|
|
1633
|
-
proposalTxParamsBatch.push({
|
|
1634
|
-
nonce: currentNonce1,
|
|
1635
|
-
gasLimit: gasLimit1.toString(),
|
|
1636
|
-
txType: "legacy",
|
|
1637
|
-
gasPrice: gasPriceWei1.toString()
|
|
1638
|
-
});
|
|
1639
|
-
} else {
|
|
1640
|
-
const fetchedBase1 = feeParams.baseFeeGwei ?? 0;
|
|
1641
|
-
const fetchedPriority1 = feeParams.priorityFeeGwei ?? 0;
|
|
1642
|
-
const configuredBase1 = useCustomGas && args.chainDetail?.baseFee != null ? Number(args.chainDetail.baseFee) : 0;
|
|
1643
|
-
const configuredPriority1 = useCustomGas && args.chainDetail?.priorityFee != null ? Number(args.chainDetail.priorityFee) : 0;
|
|
1644
|
-
const effectiveBaseFeeGwei1 = Math.max(fetchedBase1, configuredBase1);
|
|
1645
|
-
const effectivePriorityFeeGwei1 = Math.max(fetchedPriority1, configuredPriority1);
|
|
1646
|
-
const baseFeeMultiplierPct1 = useCustomGas && args.chainDetail?.baseFeeMultiplier != null ? Math.max(100, Number(args.chainDetail.baseFeeMultiplier)) : 100;
|
|
1647
|
-
const baseComponentGwei1 = effectiveBaseFeeGwei1 * baseFeeMultiplierPct1 / 100;
|
|
1648
|
-
const maxFeePerGasGwei1 = baseComponentGwei1 + effectivePriorityFeeGwei1;
|
|
1649
|
-
let maxPriorityFeePerGas1 = effectivePriorityFeeGwei1 > 0 ? viem.parseGwei(gweiToDecimalString(effectivePriorityFeeGwei1)) : viem.parseGwei("1");
|
|
1650
|
-
let maxFeePerGas1 = viem.parseGwei(gweiToDecimalString(maxFeePerGasGwei1));
|
|
1651
|
-
if (useCustomGas && gasFeeMultiplier != null && gasFeeMultiplier > 0) {
|
|
1652
|
-
maxPriorityFeePerGas1 = maxPriorityFeePerGas1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1653
|
-
maxFeePerGas1 = maxFeePerGas1 * BigInt(100 + gasFeeMultiplier) / 100n;
|
|
1654
|
-
}
|
|
1655
|
-
({ maxFeePerGas: maxFeePerGas1, maxPriorityFeePerGas: maxPriorityFeePerGas1 } = alignEip1559FeesWithLatestBase(maxFeePerGas1, maxPriorityFeePerGas1, latestBaseFeeWeiSkipBatch));
|
|
1656
|
-
const ser1 = viem.serializeTransaction({
|
|
1657
|
-
type: "eip1559",
|
|
1658
|
-
to: toRouter,
|
|
1659
|
-
data: dataHex,
|
|
1660
|
-
value: valueWei,
|
|
1661
|
-
gas: gasLimit1,
|
|
1662
|
-
maxFeePerGas: maxFeePerGas1,
|
|
1663
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas1,
|
|
1664
|
-
nonce: currentNonce1,
|
|
1665
|
-
chainId: args.chainId
|
|
1666
|
-
});
|
|
1667
|
-
const h1 = viem.keccak256(ser1);
|
|
1668
|
-
messageHashes.push(h1.startsWith("0x") ? h1.slice(2) : h1);
|
|
1669
|
-
messageRawBatch.push(ser1);
|
|
1670
|
-
proposalTxParamsBatch.push({
|
|
1671
|
-
nonce: currentNonce1,
|
|
1672
|
-
gasLimit: gasLimit1.toString(),
|
|
1673
|
-
txType: "eip1559",
|
|
1674
|
-
maxFeePerGas: maxFeePerGas1.toString(),
|
|
1675
|
-
maxPriorityFeePerGas: maxPriorityFeePerGas1.toString()
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
const swapMsgIndex = usePermit2Triple ? 2 : 1;
|
|
1679
|
-
const audit = {
|
|
1131
|
+
steps.push({
|
|
1132
|
+
to: toRouter,
|
|
1133
|
+
data: dataHex,
|
|
1134
|
+
value: valueWei,
|
|
1135
|
+
routerSwap: true,
|
|
1136
|
+
fallbackGas: DEFAULT_UNIVERSAL_ROUTER_GAS_FALLBACK
|
|
1137
|
+
});
|
|
1138
|
+
const swapStepIndex = steps.length - 1;
|
|
1139
|
+
const approveMsgRawNo0x = approveData.startsWith("0x") ? approveData.slice(2) : approveData;
|
|
1140
|
+
const purposeSuffix = usePermit2Triple ? "Uniswap V4: 3-tx batch (classic allowance) \u2014 (1) ERC-20 approve allowance hub, (2) hub approve(Universal Router), (3) swap (Trade /swap)." : "Uniswap V4: 2-tx batch (classic allowance, dispatcher) \u2014 (1) ERC-20 approve swap.to (dispatcher pulls tokens), (2) swap (Trade /swap).";
|
|
1141
|
+
const buildSwapAudit = () => ({
|
|
1680
1142
|
skipPermit2Batch: true,
|
|
1681
1143
|
approvalPath: usePermit2Triple ? "permit2_triple" : "dispatcher",
|
|
1682
1144
|
approveAmount: {
|
|
@@ -1690,9 +1152,9 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
|
|
|
1690
1152
|
requestId: args.createSwapResponse.requestId,
|
|
1691
1153
|
gasFee: args.createSwapResponse.gasFee,
|
|
1692
1154
|
gasBuildSwap: {
|
|
1693
|
-
useCustomGas,
|
|
1155
|
+
useCustomGas: args.useCustomGas,
|
|
1694
1156
|
source: gasBuildSource,
|
|
1695
|
-
baseGasUnits:
|
|
1157
|
+
baseGasUnits: swapBaseGasUnits.toString(),
|
|
1696
1158
|
...estimateGasError != null && estimateGasError !== "" ? { estimateGasError } : {}
|
|
1697
1159
|
},
|
|
1698
1160
|
swap: {
|
|
@@ -1734,92 +1196,98 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
|
|
|
1734
1196
|
note: "Dispatcher pulls via ERC20.transferFrom(user, universalRouter, amount); allowance must be on swap.to (see cast trace TRANSFER_FROM_FAILED when only the hub is approved)."
|
|
1735
1197
|
}
|
|
1736
1198
|
}
|
|
1737
|
-
};
|
|
1738
|
-
|
|
1739
|
-
{
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1199
|
+
});
|
|
1200
|
+
return buildEvmMultisignBatch({
|
|
1201
|
+
context: {
|
|
1202
|
+
chainCategory: "evm",
|
|
1203
|
+
keyGen: args.keyGen,
|
|
1204
|
+
purposeText: args.purposeText,
|
|
1205
|
+
chainId: args.chainId,
|
|
1206
|
+
rpcUrl: args.rpcUrl,
|
|
1207
|
+
executorAddress: args.executorAddress,
|
|
1208
|
+
chainDetail: args.chainDetail,
|
|
1209
|
+
useCustomGas: args.useCustomGas,
|
|
1210
|
+
customGasChainDetails: args.customGasChainDetails
|
|
1211
|
+
},
|
|
1212
|
+
steps,
|
|
1213
|
+
purposeSuffix,
|
|
1214
|
+
firstMsgRawNo0x: approveMsgRawNo0x,
|
|
1215
|
+
destinationAddress: tokenIn,
|
|
1216
|
+
payableValueWei: valueWei > 0n ? valueWei : void 0,
|
|
1217
|
+
estimateGasForStep: async ({ step, index, publicClient, executor }) => {
|
|
1218
|
+
if (index !== swapStepIndex) {
|
|
1219
|
+
return publicClient.estimateGas({
|
|
1220
|
+
to: step.to,
|
|
1221
|
+
data: step.data,
|
|
1222
|
+
value: step.value,
|
|
1223
|
+
account: executor
|
|
1224
|
+
});
|
|
1754
1225
|
}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1226
|
+
const r = await estimateUniswapRouterSwapGas({
|
|
1227
|
+
publicClient,
|
|
1228
|
+
executor,
|
|
1229
|
+
to: toRouter,
|
|
1230
|
+
data: dataHex,
|
|
1231
|
+
value: valueWei,
|
|
1232
|
+
swapRecord,
|
|
1233
|
+
useCustomGas: args.useCustomGas,
|
|
1234
|
+
chainDetail: args.chainDetail
|
|
1235
|
+
});
|
|
1236
|
+
gasBuildSource = r.source;
|
|
1237
|
+
estimateGasError = r.estimateGasError;
|
|
1238
|
+
swapBaseGasUnits = r.baseGasUnits;
|
|
1239
|
+
return r.baseGasUnits;
|
|
1240
|
+
},
|
|
1241
|
+
buildBatchMeta: ({ index }) => {
|
|
1242
|
+
if (index === 0) {
|
|
1243
|
+
return {
|
|
1244
|
+
signatureText: JSON.stringify({
|
|
1245
|
+
kind: "UniswapV4",
|
|
1246
|
+
name: "ERC20.approve",
|
|
1247
|
+
to: usePermit2Triple ? "allowance hub" : "dispatcher(swap.to)",
|
|
1248
|
+
function: "approve(address spender, uint256 amount)",
|
|
1249
|
+
spender: erc20ApproveSpender,
|
|
1250
|
+
amountWei: approveAmountWei.toString()
|
|
1251
|
+
}),
|
|
1252
|
+
evm: {
|
|
1253
|
+
type: usePermit2Triple ? "uniswap_v4_skip_permit2_approve" : "uniswap_v4_skip_permit2_dispatcher_approve",
|
|
1254
|
+
version: 1,
|
|
1255
|
+
chainId: String(args.chainId),
|
|
1256
|
+
...usePermit2Triple ? { permit2: PERMIT2_ADDRESS } : { dispatcher: toRouter }
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1775
1259
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1260
|
+
if (usePermit2Triple && index === 1) {
|
|
1261
|
+
return {
|
|
1262
|
+
signatureText: JSON.stringify({
|
|
1263
|
+
kind: "UniswapV4",
|
|
1264
|
+
name: "AllowanceHub.approve",
|
|
1265
|
+
function: "approve(address token, address spender, uint160 amount, uint48 expiration)",
|
|
1266
|
+
token: tokenIn,
|
|
1267
|
+
spender: permit2Spender,
|
|
1268
|
+
amountWei: approveAmountWei.toString(),
|
|
1269
|
+
expiration: expiration48.toString()
|
|
1270
|
+
}),
|
|
1271
|
+
evm: {
|
|
1272
|
+
type: "uniswap_v4_skip_permit2_permit2_approve",
|
|
1273
|
+
version: 1,
|
|
1274
|
+
chainId: String(args.chainId),
|
|
1275
|
+
permit2: PERMIT2_ADDRESS,
|
|
1276
|
+
permit2Spender
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
return {
|
|
1281
|
+
signatureText: JSON.stringify({
|
|
1282
|
+
kind: "UniswapV4",
|
|
1283
|
+
name: "UniversalRouter.execute",
|
|
1284
|
+
note: `Calldata from Trade API POST /swap; signed tx hash in messageHashes[${swapMsgIndex}].`
|
|
1285
|
+
}),
|
|
1286
|
+
evm: { type: "uniswap_v4_swap_tx", version: 1, chainId: String(args.chainId) },
|
|
1287
|
+
uniswapV4: buildSwapAudit()
|
|
1288
|
+
};
|
|
1793
1289
|
}
|
|
1794
|
-
}
|
|
1795
|
-
const extraJSON = JSON.stringify(extraPayload);
|
|
1796
|
-
const firstSigText = batchMeta[0].signatureText;
|
|
1797
|
-
const bodyForSign = {
|
|
1798
|
-
keyList,
|
|
1799
|
-
pubKey: ph,
|
|
1800
|
-
msgHash: messageHashes[0],
|
|
1801
|
-
msgRaw: approveMsgRawNo0x,
|
|
1802
|
-
messageHashes,
|
|
1803
|
-
messageRawBatch,
|
|
1804
|
-
destinationChainID: String(args.chainId),
|
|
1805
|
-
destinationAddress: tokenIn,
|
|
1806
|
-
extraJSON,
|
|
1807
|
-
signatureText: firstSigText,
|
|
1808
|
-
purpose: (() => {
|
|
1809
|
-
const t = args.purposeText.trim();
|
|
1810
|
-
const batchDesc = usePermit2Triple ? "Uniswap V4: 3-tx batch (classic allowance) \u2014 (1) ERC-20 approve allowance hub, (2) hub approve(Universal Router), (3) swap (Trade /swap)." : "Uniswap V4: 2-tx batch (classic allowance, dispatcher) \u2014 (1) ERC-20 approve swap.to (dispatcher pulls tokens), (2) swap (Trade /swap).";
|
|
1811
|
-
return (t ? `${t}
|
|
1812
|
-
|
|
1813
|
-
` : "") + batchDesc;
|
|
1814
|
-
})(),
|
|
1815
|
-
...firstTxFeePayload,
|
|
1816
|
-
proposalTxParams: proposalTxParamsBatch
|
|
1817
|
-
};
|
|
1818
|
-
if (valueWei > 0n) {
|
|
1819
|
-
bodyForSign.value = valueWei.toString();
|
|
1820
|
-
}
|
|
1821
|
-
if (clientId) bodyForSign.clientId = clientId;
|
|
1822
|
-
return { bodyForSign, messageToSign: JSON.stringify(bodyForSign) };
|
|
1290
|
+
});
|
|
1823
1291
|
}
|
|
1824
1292
|
|
|
1825
1293
|
// src/protocols/evm/uniswap-v4/swap.ts
|
|
@@ -2226,6 +1694,19 @@ var curveDaoProtocolModule = {
|
|
|
2226
1694
|
return token.kind === "native" || token.kind === "erc20";
|
|
2227
1695
|
},
|
|
2228
1696
|
actions: [
|
|
1697
|
+
{
|
|
1698
|
+
id: "curve-dao.quote",
|
|
1699
|
+
protocolId: CURVE_DAO_PROTOCOL_ID,
|
|
1700
|
+
chainCategory: "evm",
|
|
1701
|
+
description: "Quote swap via Curve Router NG (getBestRouteAndOutput)",
|
|
1702
|
+
commonParams: [],
|
|
1703
|
+
params: {
|
|
1704
|
+
chainId: { type: "number", required: true, description: "EVM chain id" },
|
|
1705
|
+
tokenIn: { type: "address", required: true, description: "Token in or native placeholder" },
|
|
1706
|
+
tokenOut: { type: "address", required: true, description: "Token out or native placeholder" },
|
|
1707
|
+
amountHuman: { type: "string", required: true, description: "Human-readable input amount" }
|
|
1708
|
+
}
|
|
1709
|
+
},
|
|
2229
1710
|
{
|
|
2230
1711
|
id: "curve-dao.swap",
|
|
2231
1712
|
protocolId: CURVE_DAO_PROTOCOL_ID,
|
|
@@ -2248,1027 +1729,47 @@ var curveDao = {
|
|
|
2248
1729
|
loadSession: loadFullCurveSessionForRpc
|
|
2249
1730
|
};
|
|
2250
1731
|
|
|
2251
|
-
// src/agent/commonParamDocs.ts
|
|
2252
|
-
var EVM_COMMON_PARAM_DOCS = {
|
|
2253
|
-
keyGen: {
|
|
2254
|
-
type: "object",
|
|
2255
|
-
required: true,
|
|
2256
|
-
description: "MPC key slice: { pubkeyhex: string (required), keylist: string[], ClientKeys?: Record<string,string> }. Used for pubKey/keyList on POST /multiSignRequest."
|
|
2257
|
-
},
|
|
2258
|
-
purposeText: {
|
|
2259
|
-
type: "string",
|
|
2260
|
-
required: true,
|
|
2261
|
-
description: "Human-readable purpose for the sign request. Stored in bodyForSign.purpose (may be appended with an automatic batch suffix)."
|
|
2262
|
-
},
|
|
2263
|
-
useCustomGas: {
|
|
2264
|
-
type: "boolean",
|
|
2265
|
-
required: true,
|
|
2266
|
-
description: "When true, apply chain gas settings from chainDetail / customGasChainDetails instead of raw RPC estimates only."
|
|
2267
|
-
},
|
|
2268
|
-
chainId: {
|
|
2269
|
-
type: "number",
|
|
2270
|
-
required: true,
|
|
2271
|
-
description: "EVM chain id (decimal). Becomes destinationChainID on the sign request."
|
|
2272
|
-
},
|
|
2273
|
-
rpcUrl: {
|
|
2274
|
-
type: "string",
|
|
2275
|
-
required: true,
|
|
2276
|
-
description: "HTTPS JSON-RPC URL for gas estimation, nonce, and allowance reads."
|
|
2277
|
-
},
|
|
2278
|
-
executorAddress: {
|
|
2279
|
-
type: "address",
|
|
2280
|
-
required: true,
|
|
2281
|
-
description: "MPC wallet address (from keyGen ethereumaddress) \u2014 tx sender for estimates and approvals."
|
|
2282
|
-
},
|
|
2283
|
-
chainDetail: {
|
|
2284
|
-
type: "object",
|
|
2285
|
-
required: true,
|
|
2286
|
-
description: "Optional gas config: { legacy?, gasLimit?, gasMultiplier?, gasPrice?, baseFee?, priorityFee?, baseFeeMultiplier? }."
|
|
2287
|
-
},
|
|
2288
|
-
customGasChainDetails: {
|
|
2289
|
-
type: "object",
|
|
2290
|
-
required: false,
|
|
2291
|
-
description: "Snapshot written to extraJSON.customGasChainDetails when useCustomGas is true."
|
|
2292
|
-
}
|
|
2293
|
-
};
|
|
2294
|
-
var MULTISIGN_OUTPUT_DOC = {
|
|
2295
|
-
description: "Unsigned mpc-auth multiSignRequest payload. The caller must sign messageToSign (MetaMask personal_sign or Ed25519) and POST { ...bodyForSign, clientSig, signedMessage: messageToSign } to /multiSignRequest.",
|
|
2296
|
-
fields: {
|
|
2297
|
-
bodyForSign: {
|
|
2298
|
-
type: "object",
|
|
2299
|
-
description: "POST body fields without clientSig: keyList, pubKey, msgHash, msgRaw, destinationChainID, purpose, extraJSON, proposalTxParams (batch), messageHashes/messageRawBatch when N>1 txs."
|
|
2300
|
-
},
|
|
2301
|
-
messageToSign: {
|
|
2302
|
-
type: "string",
|
|
2303
|
-
description: "JSON.stringify(bodyForSign) \u2014 exact string to sign before adding clientSig."
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
};
|
|
2307
|
-
var MANAGEMENT_SIG_DOC = {
|
|
2308
|
-
description: "Management POST bodies embed NodeMgtKeySig: { nonce, clientSig, nodeKey }. Sign JSON with clientSig cleared; POST with clientSig set to the Ed25519 128-hex or EIP-191 signature. Legacy Nonce/Sig/sig field names are not accepted.",
|
|
2309
|
-
fields: {
|
|
2310
|
-
nonce: {
|
|
2311
|
-
type: "number",
|
|
2312
|
-
description: "From GET /getPublicMgtKeyNonce (Ed25519) or GET /getNodeMgtKeyNonce (Ethereum NodeMgtKey)."
|
|
2313
|
-
},
|
|
2314
|
-
clientSig: {
|
|
2315
|
-
type: "string",
|
|
2316
|
-
description: "Management signature; empty string in the message to sign."
|
|
2317
|
-
},
|
|
2318
|
-
nodeKey: {
|
|
2319
|
-
type: "string",
|
|
2320
|
-
description: "Required. 128-hex MPC node id from GET /getNodeKey (no 0x prefix)."
|
|
2321
|
-
}
|
|
2322
|
-
},
|
|
2323
|
-
helpers: {
|
|
2324
|
-
managementSigFields: "Base envelope with clientSig cleared.",
|
|
2325
|
-
buildManagementPostBody: "Spread managementSigFields then endpoint fields.",
|
|
2326
|
-
messageToSignManagementBody: "Canonical JSON string to sign.",
|
|
2327
|
-
withManagementClientSig: "Attach signature to POST body.",
|
|
2328
|
-
fetchNodeKey: "GET /getNodeKey via nodeFetchWithReadAuth.",
|
|
2329
|
-
fetchManagementNonce: "GET nonce for Ed25519 or Ethereum management key."
|
|
2330
|
-
}
|
|
2331
|
-
};
|
|
2332
|
-
function zodSchemaToMcpJsonSchema(schema) {
|
|
2333
|
-
const raw = zodToJsonSchema.zodToJsonSchema(schema, {
|
|
2334
|
-
target: "openApi3",
|
|
2335
|
-
$refStrategy: "none"
|
|
2336
|
-
});
|
|
2337
|
-
if (raw.type === "object" || raw.type === "array" || raw.type === "string") {
|
|
2338
|
-
const { $schema: _s, ...rest } = raw;
|
|
2339
|
-
return rest;
|
|
2340
|
-
}
|
|
2341
|
-
const defs = raw.definitions;
|
|
2342
|
-
if (defs) {
|
|
2343
|
-
const first = Object.values(defs)[0];
|
|
2344
|
-
if (first?.type) {
|
|
2345
|
-
const { $schema: _s, ...rest } = first;
|
|
2346
|
-
return rest;
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
return raw;
|
|
2350
|
-
}
|
|
2351
|
-
var evmAddressSchema = zod.z.string().min(1).describe("EVM address (0x-prefixed, 40 hex nibbles)");
|
|
2352
|
-
var keyGenSchema = zod.z.object({
|
|
2353
|
-
pubkeyhex: zod.z.string().min(1).describe("MPC secp256k1 public key hex (required for multiSignRequest pubKey)"),
|
|
2354
|
-
keylist: zod.z.array(zod.z.string()).optional().describe("Key list on the sign request"),
|
|
2355
|
-
ClientKeys: zod.z.record(zod.z.string()).optional().describe("Optional client key map from keyGen")
|
|
2356
|
-
}).describe(
|
|
2357
|
-
"MPC key slice: { pubkeyhex, keylist?, ClientKeys? }. Used for pubKey/keyList on POST /multiSignRequest."
|
|
2358
|
-
);
|
|
2359
|
-
var chainDetailSchema = zod.z.object({
|
|
2360
|
-
legacy: zod.z.boolean().optional(),
|
|
2361
|
-
gasLimit: zod.z.number().optional(),
|
|
2362
|
-
gasMultiplier: zod.z.number().optional(),
|
|
2363
|
-
gasPrice: zod.z.number().optional(),
|
|
2364
|
-
baseFee: zod.z.number().optional(),
|
|
2365
|
-
priorityFee: zod.z.number().optional(),
|
|
2366
|
-
baseFeeMultiplier: zod.z.number().optional()
|
|
2367
|
-
}).passthrough().describe(
|
|
2368
|
-
"Optional gas config: { legacy?, gasLimit?, gasMultiplier?, gasPrice?, baseFee?, priorityFee?, baseFeeMultiplier? }."
|
|
2369
|
-
);
|
|
2370
|
-
var evmMultisignCommonInputSchema = zod.z.object({
|
|
2371
|
-
keyGen: keyGenSchema,
|
|
2372
|
-
purposeText: zod.z.string().min(1).describe(
|
|
2373
|
-
"Human-readable purpose for the sign request. Stored in bodyForSign.purpose (may be appended with an automatic batch suffix)."
|
|
2374
|
-
),
|
|
2375
|
-
useCustomGas: zod.z.boolean().describe(
|
|
2376
|
-
"When true, apply chain gas settings from chainDetail / customGasChainDetails instead of raw RPC estimates only."
|
|
2377
|
-
),
|
|
2378
|
-
chainId: zod.z.number().int().positive().describe("EVM chain id (decimal). Becomes destinationChainID on the sign request."),
|
|
2379
|
-
rpcUrl: zod.z.string().min(1).describe("HTTPS JSON-RPC URL for gas estimation, nonce, and allowance reads."),
|
|
2380
|
-
executorAddress: evmAddressSchema.describe(
|
|
2381
|
-
"MPC wallet address (from keyGen ethereumaddress) \u2014 tx sender for estimates and approvals."
|
|
2382
|
-
),
|
|
2383
|
-
chainDetail: chainDetailSchema,
|
|
2384
|
-
customGasChainDetails: zod.z.record(zod.z.unknown()).optional().describe("Snapshot written to extraJSON.customGasChainDetails when useCustomGas is true.")
|
|
2385
|
-
});
|
|
2386
|
-
var multisignOutputSchema = zod.z.object({
|
|
2387
|
-
bodyForSign: zod.z.record(zod.z.unknown()).describe(
|
|
2388
|
-
"POST body fields without clientSig: keyList, pubKey, msgHash, msgRaw, destinationChainID, purpose, extraJSON, proposalTxParams (batch), messageHashes/messageRawBatch when N>1 txs."
|
|
2389
|
-
),
|
|
2390
|
-
messageToSign: zod.z.string().describe("JSON.stringify(bodyForSign) \u2014 exact string to sign before adding clientSig.")
|
|
2391
|
-
}).describe(
|
|
2392
|
-
"Unsigned mpc-auth multiSignRequest payload. Sign messageToSign and POST { ...bodyForSign, clientSig, signedMessage } to /multiSignRequest."
|
|
2393
|
-
);
|
|
2394
|
-
var jsonObjectSchema = zod.z.record(zod.z.unknown());
|
|
2395
|
-
var uniswapQuoteTradeTypeSchema = zod.z.enum(["EXACT_INPUT", "EXACT_OUTPUT"]);
|
|
2396
|
-
var mcpUniswapV4QuoteInputSchema = zod.z.object({
|
|
2397
|
-
type: uniswapQuoteTradeTypeSchema.describe("EXACT_INPUT or EXACT_OUTPUT"),
|
|
2398
|
-
amount: zod.z.string().min(1).describe("Amount in token-in base units (wei string for ERC-20)"),
|
|
2399
|
-
tokenIn: zod.z.string().min(1).describe("Input token; 0x0 for native ETH"),
|
|
2400
|
-
tokenOut: zod.z.string().min(1).describe("Output token address"),
|
|
2401
|
-
chainId: zod.z.union([zod.z.number().int().positive(), zod.z.string().min(1)]).describe("tokenInChainId / same-chain default"),
|
|
2402
|
-
uniswapApiKey: zod.z.string().min(1).describe("Uniswap Trade API x-api-key"),
|
|
2403
|
-
swapper: evmAddressSchema.optional().describe("MPC executor; omit if keyGen + managementNodeUrl provided"),
|
|
2404
|
-
slippage: zod.z.union([zod.z.number(), zod.z.string()]).optional().describe("Slippage percent; omit for API auto slippage"),
|
|
2405
|
-
keyGen: zod.z.string().optional().describe("KeyGen id \u2014 resolves swapper via GET /getKeyGenResultById when swapper omitted"),
|
|
2406
|
-
managementNodeUrl: zod.z.string().min(1).optional().describe("MPC node base URL; required with keyGen when swapper is omitted"),
|
|
2407
|
-
tokenInChainId: zod.z.union([zod.z.number(), zod.z.string()]).optional(),
|
|
2408
|
-
tokenOutChainId: zod.z.union([zod.z.number(), zod.z.string()]).optional(),
|
|
2409
|
-
permit2Disabled: zod.z.boolean().optional(),
|
|
2410
|
-
baseUrl: zod.z.string().optional(),
|
|
2411
|
-
universalRouterVersion: zod.z.string().optional()
|
|
2412
|
-
});
|
|
2413
|
-
var mcpUniswapV4QuoteOutputSchema = jsonObjectSchema.describe(
|
|
2414
|
-
"Full Uniswap POST /quote JSON (includes nested quote object with input/output amounts)."
|
|
2415
|
-
);
|
|
2416
|
-
var mcpUniswapV4CreateSwapInputSchema = zod.z.object({
|
|
2417
|
-
uniswapApiKey: zod.z.string().min(1).describe("Uniswap Trade API key"),
|
|
2418
|
-
fullQuoteFromPermit: jsonObjectSchema.describe("Full quote JSON from ctm_uniswap_v4_quote"),
|
|
2419
|
-
swapTransactionDeadlineUnix: zod.z.number().int().positive().optional().describe("On-chain deadline unix seconds; default ~30 min from now"),
|
|
2420
|
-
useServerProxy: zod.z.boolean().optional().describe("Set false in Node/agents; true only in browser via Next API route"),
|
|
2421
|
-
baseUrl: zod.z.string().optional(),
|
|
2422
|
-
universalRouterVersion: zod.z.string().optional()
|
|
2423
|
-
});
|
|
2424
|
-
var mcpUniswapV4CreateSwapOutputSchema = zod.z.object({
|
|
2425
|
-
swap: jsonObjectSchema.describe("Universal Router tx: { to, data, value, gasLimit? }"),
|
|
2426
|
-
requestId: zod.z.string().optional(),
|
|
2427
|
-
gasFee: zod.z.string().optional()
|
|
2428
|
-
}).passthrough().describe("{ swap: TransactionRequest, requestId?, gasFee? }");
|
|
2429
|
-
var swapTxRequestSchema = jsonObjectSchema.describe("swap field from create_swap response (to, data, value)");
|
|
2430
|
-
var mcpUniswapV4BuildSwapMultisignInputSchema = evmMultisignCommonInputSchema.extend({
|
|
2431
|
-
tokenIn: evmAddressSchema.describe("Token in; 0x0 for native ETH"),
|
|
2432
|
-
swap: swapTxRequestSchema,
|
|
2433
|
-
createSwapResponse: zod.z.object({
|
|
2434
|
-
swap: swapTxRequestSchema,
|
|
2435
|
-
requestId: zod.z.string().optional(),
|
|
2436
|
-
gasFee: zod.z.string().optional()
|
|
2437
|
-
}).passthrough().describe("Full create_swap response"),
|
|
2438
|
-
fullQuoteSnapshot: jsonObjectSchema.describe("Quote JSON used for the swap"),
|
|
2439
|
-
swapDeadlineUnix: zod.z.number().describe("Same deadline passed to create_swap"),
|
|
2440
|
-
slippagePercent: zod.z.number().optional().describe("Extra approve headroom for EXACT_OUTPUT")
|
|
2441
|
-
});
|
|
2442
|
-
var mcpCurveDaoBuildSwapMultisignInputSchema = evmMultisignCommonInputSchema.extend({
|
|
2443
|
-
tokenIn: evmAddressSchema.describe("ERC-20 sold (native in uses WETH path in UI)"),
|
|
2444
|
-
tokenOut: zod.z.string().min(1).describe("Output token or 0xeeee\u2026 native placeholder"),
|
|
2445
|
-
amountHuman: zod.z.string().min(1).describe("Human-readable amount of tokenIn"),
|
|
2446
|
-
slippagePercent: zod.z.number().gt(0).lt(100).describe("Slippage 0\u2013100 exclusive")
|
|
2447
|
-
});
|
|
2448
|
-
function mcpMultisignInput(fields) {
|
|
2449
|
-
return evmMultisignCommonInputSchema.extend(fields);
|
|
2450
|
-
}
|
|
2451
|
-
var mcpLidoSubmitInputSchema = mcpMultisignInput({
|
|
2452
|
-
valueWei: zod.z.string().min(1).describe("ETH to stake (wei decimal string)"),
|
|
2453
|
-
referral: evmAddressSchema.optional()
|
|
2454
|
-
});
|
|
2455
|
-
var mcpLidoRequestWithdrawalsInputSchema = mcpMultisignInput({
|
|
2456
|
-
stEthAmountsWei: zod.z.array(zod.z.string()).min(1).describe("stETH amounts per withdrawal request (wei strings)")
|
|
2457
|
-
});
|
|
2458
|
-
var mcpLidoClaimWithdrawalInputSchema = mcpMultisignInput({
|
|
2459
|
-
requestId: zod.z.union([zod.z.string(), zod.z.number()]).describe("Withdrawal queue request id")
|
|
2460
|
-
});
|
|
2461
|
-
var mcpLidoWrapStEthInputSchema = mcpMultisignInput({
|
|
2462
|
-
stEthAmountWei: zod.z.string().min(1)
|
|
2463
|
-
});
|
|
2464
|
-
var mcpLidoUnwrapWstEthInputSchema = mcpMultisignInput({
|
|
2465
|
-
wstEthAmountWei: zod.z.string().min(1)
|
|
2466
|
-
});
|
|
2467
|
-
var mcpEthenaStakeInputSchema = mcpMultisignInput({
|
|
2468
|
-
usdeAmountHuman: zod.z.string().min(1),
|
|
2469
|
-
susdeVault: evmAddressSchema.optional()
|
|
2470
|
-
});
|
|
2471
|
-
var mcpEthenaRedeemInputSchema = mcpMultisignInput({
|
|
2472
|
-
susdeSharesHuman: zod.z.string().min(1),
|
|
2473
|
-
susdeVault: evmAddressSchema.optional()
|
|
2474
|
-
});
|
|
2475
|
-
var mcpEthenaCooldownInputSchema = mcpMultisignInput({
|
|
2476
|
-
susdeSharesHuman: zod.z.string().min(1),
|
|
2477
|
-
susdeVault: evmAddressSchema.optional()
|
|
2478
|
-
});
|
|
2479
|
-
var mcpEthenaClaimInputSchema = mcpMultisignInput({
|
|
2480
|
-
susdeVault: evmAddressSchema.optional()
|
|
2481
|
-
});
|
|
2482
|
-
var mcpMapleDepositInputSchema = mcpMultisignInput({
|
|
2483
|
-
syrupRouter: evmAddressSchema,
|
|
2484
|
-
pool: evmAddressSchema,
|
|
2485
|
-
asset: evmAddressSchema,
|
|
2486
|
-
amountHuman: zod.z.string().min(1),
|
|
2487
|
-
authorizeSig: jsonObjectSchema.optional()
|
|
2488
|
-
});
|
|
2489
|
-
var mcpMapleRequestRedeemInputSchema = mcpMultisignInput({
|
|
2490
|
-
pool: evmAddressSchema,
|
|
2491
|
-
sharesHuman: zod.z.string().min(1),
|
|
2492
|
-
receiver: evmAddressSchema
|
|
2493
|
-
});
|
|
2494
|
-
var mcpSkyLockstakeStakeInputSchema = mcpMultisignInput({
|
|
2495
|
-
skyAmountHuman: zod.z.string().min(1),
|
|
2496
|
-
usdsDrawHuman: zod.z.string().optional(),
|
|
2497
|
-
farmRef: zod.z.string().optional()
|
|
2498
|
-
});
|
|
2499
|
-
var mcpSkyLockstakeDrawInputSchema = mcpMultisignInput({
|
|
2500
|
-
usdsAmountHuman: zod.z.string().min(1),
|
|
2501
|
-
urnIndex: zod.z.number().int().nonnegative()
|
|
2502
|
-
});
|
|
2503
|
-
var mcpSkyLockstakeWipeInputSchema = mcpMultisignInput({
|
|
2504
|
-
usdsAmountHuman: zod.z.string().min(1),
|
|
2505
|
-
urnIndex: zod.z.number().int().nonnegative()
|
|
2506
|
-
});
|
|
2507
|
-
var mcpSkyLockstakeCloseInputSchema = mcpMultisignInput({
|
|
2508
|
-
urnIndex: zod.z.number().int().nonnegative()
|
|
2509
|
-
});
|
|
2510
|
-
var mcpSkyLockstakeGetRewardInputSchema = mcpMultisignInput({
|
|
2511
|
-
urnIndex: zod.z.number().int().nonnegative()
|
|
2512
|
-
});
|
|
2513
|
-
var mcpSkySusdsDepositInputSchema = mcpMultisignInput({
|
|
2514
|
-
usdsAmountHuman: zod.z.string().min(1)
|
|
2515
|
-
});
|
|
2516
|
-
var mcpSkySusdsRedeemInputSchema = mcpMultisignInput({
|
|
2517
|
-
sharesHuman: zod.z.string().min(1)
|
|
2518
|
-
});
|
|
2519
|
-
var mcpAaveV4DepositInputSchema = mcpMultisignInput({
|
|
2520
|
-
spoke: evmAddressSchema,
|
|
2521
|
-
underlying: evmAddressSchema,
|
|
2522
|
-
amountHuman: zod.z.string().min(1),
|
|
2523
|
-
marketId: zod.z.string().min(1)
|
|
2524
|
-
});
|
|
2525
|
-
var mcpAaveV4WithdrawInputSchema = mcpMultisignInput({
|
|
2526
|
-
spoke: evmAddressSchema,
|
|
2527
|
-
underlying: evmAddressSchema,
|
|
2528
|
-
amountHuman: zod.z.string().min(1),
|
|
2529
|
-
marketId: zod.z.string().min(1)
|
|
2530
|
-
});
|
|
2531
|
-
var mcpAaveV4BorrowInputSchema = mcpMultisignInput({
|
|
2532
|
-
spoke: evmAddressSchema,
|
|
2533
|
-
underlying: evmAddressSchema,
|
|
2534
|
-
amountHuman: zod.z.string().min(1),
|
|
2535
|
-
marketId: zod.z.string().min(1)
|
|
2536
|
-
});
|
|
2537
|
-
var mcpAaveV4RepayInputSchema = mcpMultisignInput({
|
|
2538
|
-
spoke: evmAddressSchema,
|
|
2539
|
-
underlying: evmAddressSchema,
|
|
2540
|
-
amountHuman: zod.z.string().min(1),
|
|
2541
|
-
marketId: zod.z.string().min(1)
|
|
2542
|
-
});
|
|
2543
|
-
var mcpEulerV2IsolatedLendInputSchema = mcpMultisignInput({
|
|
2544
|
-
vault: evmAddressSchema,
|
|
2545
|
-
assetAmountHuman: zod.z.string().min(1)
|
|
2546
|
-
});
|
|
2547
|
-
var mcpEulerV2IsolatedBorrowInputSchema = mcpMultisignInput({
|
|
2548
|
-
vault: evmAddressSchema,
|
|
2549
|
-
collateralAsset: evmAddressSchema,
|
|
2550
|
-
borrowAsset: evmAddressSchema,
|
|
2551
|
-
collateralAmountHuman: zod.z.string().min(1),
|
|
2552
|
-
loopBorrowWeis: zod.z.array(zod.z.string()).min(1)
|
|
2553
|
-
});
|
|
2554
|
-
var mcpEulerV2VaultWithdrawInputSchema = mcpMultisignInput({
|
|
2555
|
-
vault: evmAddressSchema,
|
|
2556
|
-
sharesHuman: zod.z.string().min(1)
|
|
2557
|
-
});
|
|
2558
|
-
var mcpEulerV2BorrowRepayInputSchema = mcpMultisignInput({
|
|
2559
|
-
vault: evmAddressSchema,
|
|
2560
|
-
amountHuman: zod.z.string().min(1)
|
|
2561
|
-
});
|
|
2562
|
-
var mcpEulerV2CollateralDepositInputSchema = mcpMultisignInput({
|
|
2563
|
-
vault: evmAddressSchema,
|
|
2564
|
-
collateralAsset: evmAddressSchema,
|
|
2565
|
-
amountHuman: zod.z.string().min(1)
|
|
2566
|
-
});
|
|
2567
|
-
var mcpEulerV2CollateralWithdrawInputSchema = mcpMultisignInput({
|
|
2568
|
-
vault: evmAddressSchema,
|
|
2569
|
-
collateralAsset: evmAddressSchema,
|
|
2570
|
-
amountHuman: zod.z.string().min(1)
|
|
2571
|
-
});
|
|
2572
|
-
|
|
2573
|
-
// src/agent/mcpProtocolTools.ts
|
|
2574
|
-
function defineProtocolMcpTool(def) {
|
|
2575
|
-
return {
|
|
2576
|
-
...def,
|
|
2577
|
-
outputZod: multisignOutputSchema,
|
|
2578
|
-
inputSchema: zodSchemaToMcpJsonSchema(def.inputZod),
|
|
2579
|
-
outputSchema: zodSchemaToMcpJsonSchema(multisignOutputSchema),
|
|
2580
|
-
parseInput: (data) => def.inputZod.parse(data),
|
|
2581
|
-
parseOutput: (data) => multisignOutputSchema.parse(data)
|
|
2582
|
-
};
|
|
2583
|
-
}
|
|
2584
|
-
var MCP_PROTOCOL_TOOL_DEFINITIONS = [
|
|
2585
|
-
defineProtocolMcpTool({
|
|
2586
|
-
name: "ctm_lido_build_submit_multisign",
|
|
2587
|
-
actionId: "lido.submit",
|
|
2588
|
-
protocolId: "lido",
|
|
2589
|
-
chainCategory: "evm",
|
|
2590
|
-
description: "Build mpc-auth multiSignRequest for Lido ETH stake (submit).",
|
|
2591
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2592
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2593
|
-
handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoSubmit" },
|
|
2594
|
-
inputZod: mcpLidoSubmitInputSchema
|
|
2595
|
-
}),
|
|
2596
|
-
defineProtocolMcpTool({
|
|
2597
|
-
name: "ctm_lido_build_request_withdrawals_multisign",
|
|
2598
|
-
actionId: "lido.request-withdrawals",
|
|
2599
|
-
protocolId: "lido",
|
|
2600
|
-
chainCategory: "evm",
|
|
2601
|
-
description: "Build batch for Lido withdrawal queue (approve + requestWithdrawals).",
|
|
2602
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2603
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2604
|
-
handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoRequestWithdrawals" },
|
|
2605
|
-
inputZod: mcpLidoRequestWithdrawalsInputSchema
|
|
2606
|
-
}),
|
|
2607
|
-
defineProtocolMcpTool({
|
|
2608
|
-
name: "ctm_lido_build_claim_withdrawal_multisign",
|
|
2609
|
-
actionId: "lido.claim-withdrawal",
|
|
2610
|
-
protocolId: "lido",
|
|
2611
|
-
chainCategory: "evm",
|
|
2612
|
-
description: "Build tx for Lido claimWithdrawal.",
|
|
2613
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2614
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2615
|
-
handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoClaimWithdrawal" },
|
|
2616
|
-
inputZod: mcpLidoClaimWithdrawalInputSchema
|
|
2617
|
-
}),
|
|
2618
|
-
defineProtocolMcpTool({
|
|
2619
|
-
name: "ctm_lido_build_wrap_steth_multisign",
|
|
2620
|
-
actionId: "lido.wrap-steth",
|
|
2621
|
-
protocolId: "lido",
|
|
2622
|
-
chainCategory: "evm",
|
|
2623
|
-
description: "Build batch for wstETH wrap.",
|
|
2624
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2625
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2626
|
-
handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoWrapStEth" },
|
|
2627
|
-
inputZod: mcpLidoWrapStEthInputSchema
|
|
2628
|
-
}),
|
|
2629
|
-
defineProtocolMcpTool({
|
|
2630
|
-
name: "ctm_lido_build_unwrap_wsteth_multisign",
|
|
2631
|
-
actionId: "lido.unwrap-wsteth",
|
|
2632
|
-
protocolId: "lido",
|
|
2633
|
-
chainCategory: "evm",
|
|
2634
|
-
description: "Build tx for wstETH unwrap.",
|
|
2635
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2636
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2637
|
-
handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoUnwrapWstEth" },
|
|
2638
|
-
inputZod: mcpLidoUnwrapWstEthInputSchema
|
|
2639
|
-
}),
|
|
2640
|
-
defineProtocolMcpTool({
|
|
2641
|
-
name: "ctm_ethena_build_stake_multisign",
|
|
2642
|
-
actionId: "ethena.stake-usde",
|
|
2643
|
-
protocolId: "ethena",
|
|
2644
|
-
chainCategory: "evm",
|
|
2645
|
-
description: "Build batch: USDe approve + sUSDe deposit.",
|
|
2646
|
-
prerequisites: ["keyGen", "executorAddress", "Ethereum mainnet RPC"],
|
|
2647
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2648
|
-
handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaUsdeStakeToSusde" },
|
|
2649
|
-
inputZod: mcpEthenaStakeInputSchema
|
|
2650
|
-
}),
|
|
2651
|
-
defineProtocolMcpTool({
|
|
2652
|
-
name: "ctm_ethena_build_redeem_multisign",
|
|
2653
|
-
actionId: "ethena.redeem-susde",
|
|
2654
|
-
protocolId: "ethena",
|
|
2655
|
-
chainCategory: "evm",
|
|
2656
|
-
description: "Build sUSDe redeem when cooldown is off.",
|
|
2657
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2658
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2659
|
-
handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaSusdeRedeemToUsde" },
|
|
2660
|
-
inputZod: mcpEthenaRedeemInputSchema
|
|
2661
|
-
}),
|
|
2662
|
-
defineProtocolMcpTool({
|
|
2663
|
-
name: "ctm_ethena_build_cooldown_multisign",
|
|
2664
|
-
actionId: "ethena.cooldown-shares",
|
|
2665
|
-
protocolId: "ethena",
|
|
2666
|
-
chainCategory: "evm",
|
|
2667
|
-
description: "Build sUSDe cooldownShares batch step.",
|
|
2668
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2669
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2670
|
-
handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaSusdeCooldownShares" },
|
|
2671
|
-
inputZod: mcpEthenaCooldownInputSchema
|
|
2672
|
-
}),
|
|
2673
|
-
defineProtocolMcpTool({
|
|
2674
|
-
name: "ctm_ethena_build_claim_multisign",
|
|
2675
|
-
actionId: "ethena.claim-unstake",
|
|
2676
|
-
protocolId: "ethena",
|
|
2677
|
-
chainCategory: "evm",
|
|
2678
|
-
description: "Build unstake claim after cooldown.",
|
|
2679
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2680
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2681
|
-
handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaUnstakeClaim" },
|
|
2682
|
-
inputZod: mcpEthenaClaimInputSchema
|
|
2683
|
-
}),
|
|
2684
|
-
defineProtocolMcpTool({
|
|
2685
|
-
name: "ctm_maple_build_deposit_multisign",
|
|
2686
|
-
actionId: "maple-syrup.deposit",
|
|
2687
|
-
protocolId: "maple-syrup",
|
|
2688
|
-
chainCategory: "evm",
|
|
2689
|
-
description: "Build Maple Syrup router deposit batch.",
|
|
2690
|
-
prerequisites: ["keyGen", "executorAddress", "router + pool addresses"],
|
|
2691
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2692
|
-
handler: { importPath: "protocols/evm/maple", exportName: "buildEvmMultisignBodyMapleSyrupDeposit" },
|
|
2693
|
-
inputZod: mcpMapleDepositInputSchema
|
|
2694
|
-
}),
|
|
2695
|
-
defineProtocolMcpTool({
|
|
2696
|
-
name: "ctm_maple_build_request_redeem_multisign",
|
|
2697
|
-
actionId: "maple-syrup.request-redeem",
|
|
2698
|
-
protocolId: "maple-syrup",
|
|
2699
|
-
chainCategory: "evm",
|
|
2700
|
-
description: "Build Maple PoolV2 requestRedeem batch.",
|
|
2701
|
-
prerequisites: ["keyGen", "executorAddress", "pool address"],
|
|
2702
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2703
|
-
handler: { importPath: "protocols/evm/maple", exportName: "buildEvmMultisignBodyMaplePoolRequestRedeem" },
|
|
2704
|
-
inputZod: mcpMapleRequestRedeemInputSchema
|
|
2705
|
-
}),
|
|
2706
|
-
defineProtocolMcpTool({
|
|
2707
|
-
name: "ctm_sky_build_lockstake_stake_multisign",
|
|
2708
|
-
actionId: "sky.lockstake-stake",
|
|
2709
|
-
protocolId: "sky",
|
|
2710
|
-
chainCategory: "evm",
|
|
2711
|
-
description: "Build Sky Lockstake open/stake batch.",
|
|
2712
|
-
prerequisites: ["keyGen", "executorAddress", "Ethereum mainnet RPC"],
|
|
2713
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2714
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeStakePositionBatch" },
|
|
2715
|
-
inputZod: mcpSkyLockstakeStakeInputSchema
|
|
2716
|
-
}),
|
|
2717
|
-
defineProtocolMcpTool({
|
|
2718
|
-
name: "ctm_sky_build_lockstake_draw_multisign",
|
|
2719
|
-
actionId: "sky.lockstake-draw",
|
|
2720
|
-
protocolId: "sky",
|
|
2721
|
-
chainCategory: "evm",
|
|
2722
|
-
description: "Build Lockstake draw (borrow USDS).",
|
|
2723
|
-
prerequisites: ["keyGen", "executorAddress", "open urn"],
|
|
2724
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2725
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeDrawBatch" },
|
|
2726
|
-
inputZod: mcpSkyLockstakeDrawInputSchema
|
|
2727
|
-
}),
|
|
2728
|
-
defineProtocolMcpTool({
|
|
2729
|
-
name: "ctm_sky_build_lockstake_wipe_multisign",
|
|
2730
|
-
actionId: "sky.lockstake-wipe",
|
|
2731
|
-
protocolId: "sky",
|
|
2732
|
-
chainCategory: "evm",
|
|
2733
|
-
description: "Build Lockstake repay/wipe batch.",
|
|
2734
|
-
prerequisites: ["keyGen", "executorAddress", "urn index"],
|
|
2735
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2736
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeWipeBatch" },
|
|
2737
|
-
inputZod: mcpSkyLockstakeWipeInputSchema
|
|
2738
|
-
}),
|
|
2739
|
-
defineProtocolMcpTool({
|
|
2740
|
-
name: "ctm_sky_build_lockstake_close_multisign",
|
|
2741
|
-
actionId: "sky.lockstake-close",
|
|
2742
|
-
protocolId: "sky",
|
|
2743
|
-
chainCategory: "evm",
|
|
2744
|
-
description: "Build Lockstake close position batch.",
|
|
2745
|
-
prerequisites: ["keyGen", "executorAddress", "urn index"],
|
|
2746
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2747
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeCloseBatch" },
|
|
2748
|
-
inputZod: mcpSkyLockstakeCloseInputSchema
|
|
2749
|
-
}),
|
|
2750
|
-
defineProtocolMcpTool({
|
|
2751
|
-
name: "ctm_sky_build_lockstake_get_reward_multisign",
|
|
2752
|
-
actionId: "sky.lockstake-get-reward",
|
|
2753
|
-
protocolId: "sky",
|
|
2754
|
-
chainCategory: "evm",
|
|
2755
|
-
description: "Build Lockstake getReward batch.",
|
|
2756
|
-
prerequisites: ["keyGen", "executorAddress", "urn index"],
|
|
2757
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2758
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeGetRewardBatch" },
|
|
2759
|
-
inputZod: mcpSkyLockstakeGetRewardInputSchema
|
|
2760
|
-
}),
|
|
2761
|
-
defineProtocolMcpTool({
|
|
2762
|
-
name: "ctm_sky_build_susds_deposit_multisign",
|
|
2763
|
-
actionId: "sky.susds-deposit",
|
|
2764
|
-
protocolId: "sky",
|
|
2765
|
-
chainCategory: "evm",
|
|
2766
|
-
description: "Build USDS \u2192 sUSDS ERC-4626 deposit batch.",
|
|
2767
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2768
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2769
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkySusdsDepositFromUsdsBatch" },
|
|
2770
|
-
inputZod: mcpSkySusdsDepositInputSchema
|
|
2771
|
-
}),
|
|
2772
|
-
defineProtocolMcpTool({
|
|
2773
|
-
name: "ctm_sky_build_susds_redeem_multisign",
|
|
2774
|
-
actionId: "sky.susds-redeem",
|
|
2775
|
-
protocolId: "sky",
|
|
2776
|
-
chainCategory: "evm",
|
|
2777
|
-
description: "Build sUSDS redeem to USDS batch.",
|
|
2778
|
-
prerequisites: ["keyGen", "executorAddress", "RPC URL"],
|
|
2779
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2780
|
-
handler: { importPath: "protocols/evm/sky", exportName: "buildSkySusdsRedeemToUsdsBatch" },
|
|
2781
|
-
inputZod: mcpSkySusdsRedeemInputSchema
|
|
2782
|
-
}),
|
|
2783
|
-
defineProtocolMcpTool({
|
|
2784
|
-
name: "ctm_aave_v4_build_deposit_multisign",
|
|
2785
|
-
actionId: "aave-v4.deposit",
|
|
2786
|
-
protocolId: "aave-v4",
|
|
2787
|
-
chainCategory: "evm",
|
|
2788
|
-
description: "Build Aave v4 Spoke supply/deposit batch.",
|
|
2789
|
-
prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
|
|
2790
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2791
|
-
handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4DepositBatch" },
|
|
2792
|
-
inputZod: mcpAaveV4DepositInputSchema
|
|
2793
|
-
}),
|
|
2794
|
-
defineProtocolMcpTool({
|
|
2795
|
-
name: "ctm_aave_v4_build_withdraw_multisign",
|
|
2796
|
-
actionId: "aave-v4.withdraw",
|
|
2797
|
-
protocolId: "aave-v4",
|
|
2798
|
-
chainCategory: "evm",
|
|
2799
|
-
description: "Build Aave v4 Spoke withdraw batch.",
|
|
2800
|
-
prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
|
|
2801
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2802
|
-
handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeWithdraw" },
|
|
2803
|
-
inputZod: mcpAaveV4WithdrawInputSchema
|
|
2804
|
-
}),
|
|
2805
|
-
defineProtocolMcpTool({
|
|
2806
|
-
name: "ctm_aave_v4_build_borrow_multisign",
|
|
2807
|
-
actionId: "aave-v4.borrow",
|
|
2808
|
-
protocolId: "aave-v4",
|
|
2809
|
-
chainCategory: "evm",
|
|
2810
|
-
description: "Build Aave v4 Spoke borrow batch.",
|
|
2811
|
-
prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
|
|
2812
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2813
|
-
handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeBorrow" },
|
|
2814
|
-
inputZod: mcpAaveV4BorrowInputSchema
|
|
2815
|
-
}),
|
|
2816
|
-
defineProtocolMcpTool({
|
|
2817
|
-
name: "ctm_aave_v4_build_repay_multisign",
|
|
2818
|
-
actionId: "aave-v4.repay",
|
|
2819
|
-
protocolId: "aave-v4",
|
|
2820
|
-
chainCategory: "evm",
|
|
2821
|
-
description: "Build Aave v4 Spoke repay batch.",
|
|
2822
|
-
prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
|
|
2823
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2824
|
-
handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeRepay" },
|
|
2825
|
-
inputZod: mcpAaveV4RepayInputSchema
|
|
2826
|
-
}),
|
|
2827
|
-
defineProtocolMcpTool({
|
|
2828
|
-
name: "ctm_euler_v2_build_isolated_lend_multisign",
|
|
2829
|
-
actionId: "euler-v2.isolated-lend",
|
|
2830
|
-
protocolId: "euler-v2",
|
|
2831
|
-
chainCategory: "evm",
|
|
2832
|
-
description: "Build Euler v2 vault deposit/lend batch.",
|
|
2833
|
-
prerequisites: ["keyGen", "executorAddress", "vault address"],
|
|
2834
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2835
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch" },
|
|
2836
|
-
inputZod: mcpEulerV2IsolatedLendInputSchema
|
|
2837
|
-
}),
|
|
2838
|
-
defineProtocolMcpTool({
|
|
2839
|
-
name: "ctm_euler_v2_build_isolated_borrow_multisign",
|
|
2840
|
-
actionId: "euler-v2.isolated-borrow",
|
|
2841
|
-
protocolId: "euler-v2",
|
|
2842
|
-
chainCategory: "evm",
|
|
2843
|
-
description: "Build Euler v2 isolated borrow loop batch.",
|
|
2844
|
-
prerequisites: ["keyGen", "executorAddress", "vault + collateral"],
|
|
2845
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2846
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2IsolatedBorrowBatch" },
|
|
2847
|
-
inputZod: mcpEulerV2IsolatedBorrowInputSchema
|
|
2848
|
-
}),
|
|
2849
|
-
defineProtocolMcpTool({
|
|
2850
|
-
name: "ctm_euler_v2_build_vault_withdraw_multisign",
|
|
2851
|
-
actionId: "euler-v2.vault-withdraw",
|
|
2852
|
-
protocolId: "euler-v2",
|
|
2853
|
-
chainCategory: "evm",
|
|
2854
|
-
description: "Build Euler v2 vault withdraw/redeem batch.",
|
|
2855
|
-
prerequisites: ["keyGen", "executorAddress", "vault address"],
|
|
2856
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2857
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2VaultWithdrawBatch" },
|
|
2858
|
-
inputZod: mcpEulerV2VaultWithdrawInputSchema
|
|
2859
|
-
}),
|
|
2860
|
-
defineProtocolMcpTool({
|
|
2861
|
-
name: "ctm_euler_v2_build_borrow_repay_multisign",
|
|
2862
|
-
actionId: "euler-v2.borrow-repay",
|
|
2863
|
-
protocolId: "euler-v2",
|
|
2864
|
-
chainCategory: "evm",
|
|
2865
|
-
description: "Build Euler v2 borrow repay batch.",
|
|
2866
|
-
prerequisites: ["keyGen", "executorAddress", "vault address"],
|
|
2867
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2868
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowRepayBatch" },
|
|
2869
|
-
inputZod: mcpEulerV2BorrowRepayInputSchema
|
|
2870
|
-
}),
|
|
2871
|
-
defineProtocolMcpTool({
|
|
2872
|
-
name: "ctm_euler_v2_build_collateral_deposit_multisign",
|
|
2873
|
-
actionId: "euler-v2.collateral-deposit",
|
|
2874
|
-
protocolId: "euler-v2",
|
|
2875
|
-
chainCategory: "evm",
|
|
2876
|
-
description: "Build Euler v2 borrow collateral deposit batch.",
|
|
2877
|
-
prerequisites: ["keyGen", "executorAddress", "vault + collateral asset"],
|
|
2878
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2879
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowCollateralDepositBatch" },
|
|
2880
|
-
inputZod: mcpEulerV2CollateralDepositInputSchema
|
|
2881
|
-
}),
|
|
2882
|
-
defineProtocolMcpTool({
|
|
2883
|
-
name: "ctm_euler_v2_build_collateral_withdraw_multisign",
|
|
2884
|
-
actionId: "euler-v2.collateral-withdraw",
|
|
2885
|
-
protocolId: "euler-v2",
|
|
2886
|
-
chainCategory: "evm",
|
|
2887
|
-
description: "Build Euler v2 borrow collateral withdraw batch.",
|
|
2888
|
-
prerequisites: ["keyGen", "executorAddress", "vault + collateral asset"],
|
|
2889
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest"],
|
|
2890
|
-
handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch" },
|
|
2891
|
-
inputZod: mcpEulerV2CollateralWithdrawInputSchema
|
|
2892
|
-
})
|
|
2893
|
-
];
|
|
2894
|
-
|
|
2895
|
-
// src/agent/mcpTools.ts
|
|
2896
|
-
function defineMcpTool(def) {
|
|
2897
|
-
return {
|
|
2898
|
-
...def,
|
|
2899
|
-
inputSchema: zodSchemaToMcpJsonSchema(def.inputZod),
|
|
2900
|
-
outputSchema: zodSchemaToMcpJsonSchema(def.outputZod),
|
|
2901
|
-
parseInput: (data) => def.inputZod.parse(data),
|
|
2902
|
-
parseOutput: (data) => def.outputZod.parse(data)
|
|
2903
|
-
};
|
|
2904
|
-
}
|
|
2905
|
-
var CORE_MCP_TOOL_DEFINITIONS = [
|
|
2906
|
-
defineMcpTool({
|
|
2907
|
-
name: "ctm_uniswap_v4_quote",
|
|
2908
|
-
actionId: "uniswap-v4.quote",
|
|
2909
|
-
protocolId: "uniswap-v4",
|
|
2910
|
-
chainCategory: "evm",
|
|
2911
|
-
description: "Fetch a Uniswap V4 Trade API quote (POST /v1/quote). Returns classic quote JSON including quote.input/output amounts and routing. Does NOT create a sign request \u2014 use ctm_uniswap_v4_create_swap and ctm_uniswap_v4_build_swap_multisign after quoting. Requires uniswapApiKey and swapper (MPC executor address) or keyGen + managementNodeUrl to resolve swapper.",
|
|
2912
|
-
prerequisites: ["Chain must be supported by Uniswap V4 (Universal Router map)."],
|
|
2913
|
-
followUp: ["ctm_uniswap_v4_create_swap", "ctm_uniswap_v4_build_swap_multisign"],
|
|
2914
|
-
handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapTradeQuote" },
|
|
2915
|
-
inputZod: mcpUniswapV4QuoteInputSchema,
|
|
2916
|
-
outputZod: mcpUniswapV4QuoteOutputSchema
|
|
2917
|
-
}),
|
|
2918
|
-
defineMcpTool({
|
|
2919
|
-
name: "ctm_uniswap_v4_create_swap",
|
|
2920
|
-
actionId: "uniswap-v4.create-swap",
|
|
2921
|
-
protocolId: "uniswap-v4",
|
|
2922
|
-
chainCategory: "evm",
|
|
2923
|
-
description: "Call Uniswap Trade API POST /v1/swap to build Universal Router calldata from a prior quote. Returns { swap: { to, data, value, gasLimit? }, requestId? }. Does NOT produce a multiSignRequest \u2014 call ctm_uniswap_v4_build_swap_multisign next.",
|
|
2924
|
-
prerequisites: ["ctm_uniswap_v4_quote output (fullQuoteFromPermit)"],
|
|
2925
|
-
followUp: ["ctm_uniswap_v4_build_swap_multisign"],
|
|
2926
|
-
handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapCreateSwap" },
|
|
2927
|
-
inputZod: mcpUniswapV4CreateSwapInputSchema,
|
|
2928
|
-
outputZod: mcpUniswapV4CreateSwapOutputSchema
|
|
2929
|
-
}),
|
|
2930
|
-
defineMcpTool({
|
|
2931
|
-
name: "ctm_uniswap_v4_build_swap_multisign",
|
|
2932
|
-
actionId: "uniswap-v4.swap-exact-input",
|
|
2933
|
-
protocolId: "uniswap-v4",
|
|
2934
|
-
chainCategory: "evm",
|
|
2935
|
-
description: "Build mpc-auth multiSignRequest body for a Uniswap V4 swap. May batch 1\u20133 EVM txs: ERC-20 approve(s) to Permit2/router path + Universal Router swap (or 1 tx for native-in). Estimates gas, serializes unsigned txs, sets proposalTxParams. Output must be signed and POSTed to /multiSignRequest by the caller.",
|
|
2936
|
-
prerequisites: [
|
|
2937
|
-
"ctm_uniswap_v4_create_swap output",
|
|
2938
|
-
"keyGen with pubkeyhex",
|
|
2939
|
-
"executorAddress matching MPC wallet",
|
|
2940
|
-
"RPC URL and chainDetail from node chain config"
|
|
2941
|
-
],
|
|
2942
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest with clientSig and signedMessage"],
|
|
2943
|
-
handler: { importPath: "protocols/evm/uniswap-v4", exportName: "buildEvmMultisignBodyUniswapV4SkipPermit2Batch" },
|
|
2944
|
-
inputZod: mcpUniswapV4BuildSwapMultisignInputSchema,
|
|
2945
|
-
outputZod: multisignOutputSchema
|
|
2946
|
-
}),
|
|
2947
|
-
defineMcpTool({
|
|
2948
|
-
name: "ctm_curve_dao_build_swap_multisign",
|
|
2949
|
-
actionId: "curve-dao.swap",
|
|
2950
|
-
protocolId: "curve-dao",
|
|
2951
|
-
chainCategory: "evm",
|
|
2952
|
-
description: "Build mpc-auth multiSignRequest for a Curve Router NG swap via @curvefi/api populateSwap. Optionally batches ERC-20 approve txs when allowance is insufficient, then exchange. Requires JSON-RPC and Curve-supported chain.",
|
|
2953
|
-
prerequisites: ["keyGen", "executorAddress", "tokenIn/tokenOut/amountHuman/slippage", "RPC URL"],
|
|
2954
|
-
followUp: ["Sign messageToSign", "POST /multiSignRequest with clientSig and signedMessage"],
|
|
2955
|
-
handler: { importPath: "protocols/evm/curve-dao", exportName: "buildEvmMultisignBodyCurveDaoBatch" },
|
|
2956
|
-
inputZod: mcpCurveDaoBuildSwapMultisignInputSchema,
|
|
2957
|
-
outputZod: multisignOutputSchema
|
|
2958
|
-
})
|
|
2959
|
-
];
|
|
2960
|
-
var MCP_TOOL_DEFINITIONS = [
|
|
2961
|
-
...CORE_MCP_TOOL_DEFINITIONS,
|
|
2962
|
-
...MCP_PROTOCOL_TOOL_DEFINITIONS
|
|
2963
|
-
];
|
|
2964
|
-
function buildToolSchemaMap(kind) {
|
|
2965
|
-
const out = {};
|
|
2966
|
-
for (const tool of MCP_TOOL_DEFINITIONS) {
|
|
2967
|
-
out[tool.name] = kind === "input" ? tool.inputZod : tool.outputZod;
|
|
2968
|
-
}
|
|
2969
|
-
return out;
|
|
2970
|
-
}
|
|
2971
|
-
var MCP_TOOL_INPUT_SCHEMAS = buildToolSchemaMap("input");
|
|
2972
|
-
var MCP_TOOL_OUTPUT_SCHEMAS = buildToolSchemaMap("output");
|
|
2973
|
-
function getAgentCatalogForMcp() {
|
|
2974
|
-
return {
|
|
2975
|
-
tools: MCP_TOOL_DEFINITIONS,
|
|
2976
|
-
protocols: getProtocolModules(),
|
|
2977
|
-
commonParams: EVM_COMMON_PARAM_DOCS,
|
|
2978
|
-
multisignOutput: MULTISIGN_OUTPUT_DOC,
|
|
2979
|
-
managementSig: MANAGEMENT_SIG_DOC,
|
|
2980
|
-
/** Zod schemas for MCP tool I/O — source of truth for continuum-mcp-server validation. */
|
|
2981
|
-
inputSchemas: MCP_TOOL_INPUT_SCHEMAS,
|
|
2982
|
-
outputSchemas: MCP_TOOL_OUTPUT_SCHEMAS,
|
|
2983
|
-
workflow: {
|
|
2984
|
-
evmSwapTypical: [
|
|
2985
|
-
"1. Quote (protocol-specific API if needed)",
|
|
2986
|
-
"2. Build protocol calldata (e.g. create_swap)",
|
|
2987
|
-
"3. build_*_multisign \u2192 { bodyForSign, messageToSign }",
|
|
2988
|
-
"4. Sign messageToSign (MetaMask or Ed25519)",
|
|
2989
|
-
"5. POST /multiSignRequest with clientSig and signedMessage"
|
|
2990
|
-
],
|
|
2991
|
-
managementPostTypical: [
|
|
2992
|
-
"1. GET /getNodeKey \u2192 nodeKey (128 hex)",
|
|
2993
|
-
"2. GET /getPublicMgtKeyNonce or /getNodeMgtKeyNonce \u2192 nonce",
|
|
2994
|
-
"3. buildManagementPostBody(nonce, nodeKey, { \u2026endpoint fields })",
|
|
2995
|
-
"4. messageToSignManagementBody(body) \u2192 sign \u2192 withManagementClientSig(body, sig)",
|
|
2996
|
-
"5. POST management route with signed body"
|
|
2997
|
-
]
|
|
2998
|
-
}
|
|
2999
|
-
};
|
|
3000
|
-
}
|
|
3001
|
-
viem.getAddress(
|
|
3002
|
-
"0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84"
|
|
3003
|
-
);
|
|
3004
|
-
viem.getAddress(
|
|
3005
|
-
"0x7f39C581F595B853cBbF37C12FfeeA971C5a5bEa"
|
|
3006
|
-
);
|
|
3007
|
-
viem.getAddress("0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1");
|
|
3008
|
-
var LIDO_ETHEREUM_MAINNET_CHAIN_ID = 1;
|
|
3009
|
-
|
|
3010
|
-
// src/protocols/evm/lido/index.ts
|
|
3011
|
-
var LIDO_PROTOCOL_ID = "lido";
|
|
3012
|
-
var lidoProtocolModule = {
|
|
3013
|
-
id: LIDO_PROTOCOL_ID,
|
|
3014
|
-
chainCategory: "evm",
|
|
3015
|
-
isChainSupported(ctx) {
|
|
3016
|
-
if (ctx.chainCategory !== "evm") return false;
|
|
3017
|
-
return Number(ctx.chainId) === LIDO_ETHEREUM_MAINNET_CHAIN_ID;
|
|
3018
|
-
},
|
|
3019
|
-
isTokenSupported(token) {
|
|
3020
|
-
return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
|
|
3021
|
-
},
|
|
3022
|
-
actions: [
|
|
3023
|
-
{ id: "lido.submit", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Stake ETH via Lido submit()", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: { valueWei: { type: "string", required: true, description: "ETH to stake (wei string)" } } },
|
|
3024
|
-
{ id: "lido.request-withdrawals", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Queue stETH withdrawal", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3025
|
-
{ id: "lido.claim-withdrawal", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Claim finalized withdrawal", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3026
|
-
{ id: "lido.wrap-steth", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Wrap stETH to wstETH", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3027
|
-
{ id: "lido.unwrap-wsteth", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Unwrap wstETH to stETH", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3028
|
-
]
|
|
3029
|
-
};
|
|
3030
|
-
registerProtocolModule(lidoProtocolModule);
|
|
3031
|
-
var USDE_ETHEREUM_MAINNET = "0x4c9edd5852cd905f086c759e8383e09bff1e68b3";
|
|
3032
|
-
var USDE_MOST_L2S = "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34";
|
|
3033
|
-
var USDE_ZKSYNC_ERA = "0x39Fe7a0DACcE31Bd90418e3e659fb0b5f0B3Db0d";
|
|
3034
|
-
var L2_SAME_ADDRESS_CHAIN_IDS = /* @__PURE__ */ new Set([
|
|
3035
|
-
42161,
|
|
3036
|
-
// Arbitrum One
|
|
3037
|
-
10,
|
|
3038
|
-
// Optimism
|
|
3039
|
-
8453,
|
|
3040
|
-
// Base
|
|
3041
|
-
56,
|
|
3042
|
-
// BNB Chain
|
|
3043
|
-
59144,
|
|
3044
|
-
// Linea
|
|
3045
|
-
5e3,
|
|
3046
|
-
// Mantle
|
|
3047
|
-
81457,
|
|
3048
|
-
// Blast
|
|
3049
|
-
169,
|
|
3050
|
-
// Manta Pacific
|
|
3051
|
-
534352,
|
|
3052
|
-
// Scroll
|
|
3053
|
-
252,
|
|
3054
|
-
// Fraxtal
|
|
3055
|
-
34443,
|
|
3056
|
-
// Mode
|
|
3057
|
-
196,
|
|
3058
|
-
// X Layer
|
|
3059
|
-
1088,
|
|
3060
|
-
// Metis
|
|
3061
|
-
80084,
|
|
3062
|
-
// Berachain
|
|
3063
|
-
2222,
|
|
3064
|
-
// Kava
|
|
3065
|
-
2818,
|
|
3066
|
-
// Morph
|
|
3067
|
-
1923,
|
|
3068
|
-
// Swell
|
|
3069
|
-
48900
|
|
3070
|
-
// Zircuit
|
|
3071
|
-
]);
|
|
3072
|
-
function usdeTokenAddressOnEvmChain(chainId) {
|
|
3073
|
-
if (chainId === 1) return USDE_ETHEREUM_MAINNET;
|
|
3074
|
-
if (chainId === 324) return USDE_ZKSYNC_ERA;
|
|
3075
|
-
if (L2_SAME_ADDRESS_CHAIN_IDS.has(chainId)) return USDE_MOST_L2S;
|
|
3076
|
-
return null;
|
|
3077
|
-
}
|
|
3078
|
-
function isEvmChainInEthenaUsdeList(chainId) {
|
|
3079
|
-
return usdeTokenAddressOnEvmChain(chainId) != null;
|
|
3080
|
-
}
|
|
3081
|
-
|
|
3082
|
-
// src/protocols/evm/ethena/index.ts
|
|
3083
|
-
var ETHENA_PROTOCOL_ID = "ethena";
|
|
3084
|
-
var ethenaProtocolModule = {
|
|
3085
|
-
id: ETHENA_PROTOCOL_ID,
|
|
3086
|
-
chainCategory: "evm",
|
|
3087
|
-
isChainSupported(ctx) {
|
|
3088
|
-
if (ctx.chainCategory !== "evm") return false;
|
|
3089
|
-
const n = typeof ctx.chainId === "number" ? ctx.chainId : Number.parseInt(String(ctx.chainId), 10);
|
|
3090
|
-
return isEvmChainInEthenaUsdeList(n);
|
|
3091
|
-
},
|
|
3092
|
-
isTokenSupported(token) {
|
|
3093
|
-
return token.category === "evm" && token.kind === "erc20";
|
|
3094
|
-
},
|
|
3095
|
-
actions: [
|
|
3096
|
-
{ id: "ethena.stake-usde", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Stake USDe \u2192 sUSDe", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: { amountHuman: { type: "string", required: true, description: "USDe amount" } } },
|
|
3097
|
-
{ id: "ethena.redeem-susde", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Redeem sUSDe \u2192 USDe (no cooldown)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3098
|
-
{ id: "ethena.cooldown-shares", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Start sUSDe cooldown", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3099
|
-
{ id: "ethena.claim-unstake", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Claim after cooldown", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3100
|
-
]
|
|
3101
|
-
};
|
|
3102
|
-
registerProtocolModule(ethenaProtocolModule);
|
|
3103
|
-
|
|
3104
|
-
// src/protocols/evm/maple/constants.ts
|
|
3105
|
-
function isMapleSyrupSupportedChain(chainId) {
|
|
3106
|
-
return chainId === 1 || chainId === 11155111;
|
|
3107
|
-
}
|
|
3108
|
-
|
|
3109
|
-
// src/protocols/evm/maple/index.ts
|
|
3110
|
-
var MAPLE_PROTOCOL_ID = "maple-syrup";
|
|
3111
|
-
var mapleProtocolModule = {
|
|
3112
|
-
id: MAPLE_PROTOCOL_ID,
|
|
3113
|
-
chainCategory: "evm",
|
|
3114
|
-
isChainSupported(ctx) {
|
|
3115
|
-
if (ctx.chainCategory !== "evm") return false;
|
|
3116
|
-
const n = typeof ctx.chainId === "number" ? ctx.chainId : Number.parseInt(String(ctx.chainId), 10);
|
|
3117
|
-
return isMapleSyrupSupportedChain(n);
|
|
3118
|
-
},
|
|
3119
|
-
isTokenSupported(token) {
|
|
3120
|
-
return token.category === "evm" && token.kind === "erc20";
|
|
3121
|
-
},
|
|
3122
|
-
actions: [
|
|
3123
|
-
{ id: "maple-syrup.deposit", protocolId: MAPLE_PROTOCOL_ID, chainCategory: "evm", description: "Deposit into Maple Syrup pool", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3124
|
-
{ id: "maple-syrup.request-redeem", protocolId: MAPLE_PROTOCOL_ID, chainCategory: "evm", description: "Request redeem from pool", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3125
|
-
]
|
|
3126
|
-
};
|
|
3127
|
-
registerProtocolModule(mapleProtocolModule);
|
|
3128
|
-
|
|
3129
|
-
// src/protocols/evm/sky/mainnet.ts
|
|
3130
|
-
var SKY_ETHEREUM_MAINNET_CHAIN_ID = 1;
|
|
3131
|
-
|
|
3132
|
-
// src/protocols/evm/sky/index.ts
|
|
3133
|
-
var SKY_PROTOCOL_ID = "sky";
|
|
3134
|
-
var skyProtocolModule = {
|
|
3135
|
-
id: SKY_PROTOCOL_ID,
|
|
3136
|
-
chainCategory: "evm",
|
|
3137
|
-
isChainSupported(ctx) {
|
|
3138
|
-
if (ctx.chainCategory !== "evm") return false;
|
|
3139
|
-
return Number(ctx.chainId) === SKY_ETHEREUM_MAINNET_CHAIN_ID;
|
|
3140
|
-
},
|
|
3141
|
-
isTokenSupported(token) {
|
|
3142
|
-
return token.category === "evm" && token.kind === "erc20";
|
|
3143
|
-
},
|
|
3144
|
-
actions: [
|
|
3145
|
-
{ id: "sky.lockstake-stake", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Open Lockstake position", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3146
|
-
{ id: "sky.lockstake-draw", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Borrow USDS from Lockstake", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3147
|
-
{ id: "sky.lockstake-wipe", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Repay Lockstake debt", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3148
|
-
{ id: "sky.lockstake-close", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Close Lockstake position", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3149
|
-
{ id: "sky.susds-deposit", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Deposit USDS into sUSDS vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3150
|
-
{ id: "sky.susds-redeem", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Redeem sUSDS to USDS", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3151
|
-
]
|
|
3152
|
-
};
|
|
3153
|
-
registerProtocolModule(skyProtocolModule);
|
|
3154
|
-
|
|
3155
|
-
// src/protocols/evm/aave-v4/index.ts
|
|
3156
|
-
var AAVE_V4_PROTOCOL_ID = "aave-v4";
|
|
3157
|
-
var aaveV4ProtocolModule = {
|
|
3158
|
-
id: AAVE_V4_PROTOCOL_ID,
|
|
3159
|
-
chainCategory: "evm",
|
|
3160
|
-
isChainSupported(ctx) {
|
|
3161
|
-
return ctx.chainCategory === "evm";
|
|
3162
|
-
},
|
|
3163
|
-
isTokenSupported(token) {
|
|
3164
|
-
return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
|
|
3165
|
-
},
|
|
3166
|
-
actions: [
|
|
3167
|
-
{ id: "aave-v4.deposit", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Supply to Aave v4 Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3168
|
-
{ id: "aave-v4.withdraw", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3169
|
-
{ id: "aave-v4.borrow", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Borrow from Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3170
|
-
{ id: "aave-v4.repay", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Repay Spoke debt", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3171
|
-
]
|
|
3172
|
-
};
|
|
3173
|
-
registerProtocolModule(aaveV4ProtocolModule);
|
|
3174
|
-
|
|
3175
|
-
// src/protocols/evm/euler-v2/index.ts
|
|
3176
|
-
var EULER_V2_PROTOCOL_ID = "euler-v2";
|
|
3177
|
-
var eulerV2ProtocolModule = {
|
|
3178
|
-
id: EULER_V2_PROTOCOL_ID,
|
|
3179
|
-
chainCategory: "evm",
|
|
3180
|
-
isChainSupported(ctx) {
|
|
3181
|
-
return ctx.chainCategory === "evm";
|
|
3182
|
-
},
|
|
3183
|
-
isTokenSupported(token) {
|
|
3184
|
-
return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
|
|
3185
|
-
},
|
|
3186
|
-
actions: [
|
|
3187
|
-
{ id: "euler-v2.isolated-lend", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Deposit into Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3188
|
-
{ id: "euler-v2.isolated-borrow", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Borrow from Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3189
|
-
{ id: "euler-v2.vault-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3190
|
-
{ id: "euler-v2.borrow-repay", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Repay Euler borrow", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3191
|
-
{ id: "euler-v2.collateral-deposit", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Deposit borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
|
|
3192
|
-
{ id: "euler-v2.collateral-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
|
|
3193
|
-
]
|
|
3194
|
-
};
|
|
3195
|
-
registerProtocolModule(eulerV2ProtocolModule);
|
|
3196
|
-
|
|
3197
|
-
// src/agent/catalog.ts
|
|
3198
|
-
registerProtocolModule(uniswapV4ProtocolModule);
|
|
3199
|
-
registerProtocolModule(curveDaoProtocolModule);
|
|
3200
|
-
registerProtocolModule(lidoProtocolModule);
|
|
3201
|
-
registerProtocolModule(ethenaProtocolModule);
|
|
3202
|
-
registerProtocolModule(mapleProtocolModule);
|
|
3203
|
-
registerProtocolModule(skyProtocolModule);
|
|
3204
|
-
registerProtocolModule(aaveV4ProtocolModule);
|
|
3205
|
-
registerProtocolModule(eulerV2ProtocolModule);
|
|
3206
|
-
function getAgentCatalog() {
|
|
3207
|
-
return {
|
|
3208
|
-
protocols: getProtocolModules(),
|
|
3209
|
-
byCategory: {
|
|
3210
|
-
evm: getActionsByChainCategory("evm"),
|
|
3211
|
-
solana: getActionsByChainCategory("solana"),
|
|
3212
|
-
near: getActionsByChainCategory("near")
|
|
3213
|
-
},
|
|
3214
|
-
uniswapV4: uniswapV4ProtocolModule,
|
|
3215
|
-
curveDao: curveDaoProtocolModule,
|
|
3216
|
-
lido: lidoProtocolModule,
|
|
3217
|
-
ethena: ethenaProtocolModule,
|
|
3218
|
-
maple: mapleProtocolModule,
|
|
3219
|
-
sky: skyProtocolModule,
|
|
3220
|
-
aaveV4: aaveV4ProtocolModule,
|
|
3221
|
-
eulerV2: eulerV2ProtocolModule,
|
|
3222
|
-
/** Prefer getAgentCatalogForMcp() or getMcpToolDefinitions() for MCP servers. */
|
|
3223
|
-
mcp: getAgentCatalogForMcp()
|
|
3224
|
-
};
|
|
3225
|
-
}
|
|
3226
|
-
|
|
3227
1732
|
// src/index.ts
|
|
3228
1733
|
registerProtocolModule(uniswapV4ProtocolModule);
|
|
3229
1734
|
registerProtocolModule(curveDaoProtocolModule);
|
|
3230
1735
|
|
|
1736
|
+
Object.defineProperty(exports, "firstClientIdFromKeyGen", {
|
|
1737
|
+
enumerable: true,
|
|
1738
|
+
get: function () { return continuumNodeSdk.getClientIdFromKeyGenResult; }
|
|
1739
|
+
});
|
|
1740
|
+
exports.COINGECKO_PLATFORM_BY_CHAIN_ID = COINGECKO_PLATFORM_BY_CHAIN_ID;
|
|
3231
1741
|
exports.NEAR_CHAIN_CATEGORY = NEAR_CHAIN_CATEGORY;
|
|
3232
1742
|
exports.SOLANA_CHAIN_CATEGORY = SOLANA_CHAIN_CATEGORY;
|
|
3233
|
-
exports.alignEip1559FeesWithLatestBase = alignEip1559FeesWithLatestBase;
|
|
3234
1743
|
exports.buildEvmMultisignBatch = buildEvmMultisignBatch;
|
|
3235
|
-
exports.
|
|
3236
|
-
exports.chainSnapshotForCustomGasExtraJSON = chainSnapshotForCustomGasExtraJSON;
|
|
3237
|
-
exports.composeFeePayloadToTxParams = composeFeePayloadToTxParams;
|
|
1744
|
+
exports.coingeckoPlatformForChainId = coingeckoPlatformForChainId;
|
|
3238
1745
|
exports.coreChainCategoryModule = coreChainCategoryModule;
|
|
3239
1746
|
exports.curveDao = curveDao;
|
|
3240
1747
|
exports.curveDaoProtocolModule = curveDaoProtocolModule;
|
|
3241
1748
|
exports.evmChainCategoryModule = evmChainCategoryModule;
|
|
3242
|
-
exports.fetchChainFeeParams = fetchChainFeeParams;
|
|
3243
|
-
exports.fetchManagementNonce = fetchManagementNonce;
|
|
3244
|
-
exports.fetchNodeKey = fetchNodeKey;
|
|
3245
1749
|
exports.finalizeMultisign = finalizeMultisign;
|
|
3246
|
-
exports.
|
|
3247
|
-
exports.gasLimitFromEstimateAndChainConfig = gasLimitFromEstimateAndChainConfig;
|
|
1750
|
+
exports.getAaveGraphqlProxyUrl = getAaveGraphqlProxyUrl;
|
|
3248
1751
|
exports.getActionsByChainCategory = getActionsByChainCategory;
|
|
3249
|
-
exports.
|
|
1752
|
+
exports.getCoingeckoProxyUrl = getCoingeckoProxyUrl;
|
|
1753
|
+
exports.getEulerGraphqlProxyUrl = getEulerGraphqlProxyUrl;
|
|
1754
|
+
exports.getMapleGraphqlProxyUrl = getMapleGraphqlProxyUrl;
|
|
3250
1755
|
exports.getProtocolModule = getProtocolModule;
|
|
3251
1756
|
exports.getProtocolModules = getProtocolModules;
|
|
3252
|
-
exports.gweiToDecimalString = gweiToDecimalString;
|
|
3253
1757
|
exports.isEvmNativeToken = isEvmNativeToken;
|
|
3254
|
-
exports.isValidRpcUrl = isValidRpcUrl;
|
|
3255
|
-
exports.keyListFromKeyGen = keyListFromKeyGen;
|
|
3256
|
-
exports.managementSigFields = managementSigFields;
|
|
3257
1758
|
exports.matchEvmTokenKind = matchEvmTokenKind;
|
|
3258
1759
|
exports.mergePurposeText = mergePurposeText;
|
|
3259
|
-
exports.messageToSignManagementBody = messageToSignManagementBody;
|
|
3260
1760
|
exports.nearChainCategoryModule = nearChainCategoryModule;
|
|
3261
|
-
exports.
|
|
3262
|
-
exports.
|
|
1761
|
+
exports.normalizeCurveRouterAmountString = normalizeCurveRouterAmountString;
|
|
1762
|
+
exports.normalizeHumanDecimalAmount = normalizeHumanDecimalAmount;
|
|
3263
1763
|
exports.parseEvmChainIdToNumber = parseEvmChainIdToNumber;
|
|
3264
|
-
exports.
|
|
1764
|
+
exports.postJsonViaOptionalProxy = postJsonViaOptionalProxy;
|
|
3265
1765
|
exports.registerProtocolModule = registerProtocolModule;
|
|
3266
|
-
exports.requirePubKeyHex = requirePubKeyHex;
|
|
3267
1766
|
exports.routerSwapGasLimitFromEstimate = routerSwapGasLimitFromEstimate;
|
|
1767
|
+
exports.setAaveGraphqlProxyUrl = setAaveGraphqlProxyUrl;
|
|
1768
|
+
exports.setCoingeckoProxyUrl = setCoingeckoProxyUrl;
|
|
1769
|
+
exports.setEulerGraphqlProxyUrl = setEulerGraphqlProxyUrl;
|
|
1770
|
+
exports.setMapleGraphqlProxyUrl = setMapleGraphqlProxyUrl;
|
|
3268
1771
|
exports.solanaChainCategoryModule = solanaChainCategoryModule;
|
|
3269
|
-
exports.triggerTxParamsFromComposeBody = triggerTxParamsFromComposeBody;
|
|
3270
1772
|
exports.uniswapV4 = uniswapV4;
|
|
3271
1773
|
exports.uniswapV4ProtocolModule = uniswapV4ProtocolModule;
|
|
3272
|
-
exports.withManagementClientSig = withManagementClientSig;
|
|
3273
1774
|
//# sourceMappingURL=index.cjs.map
|
|
3274
1775
|
//# sourceMappingURL=index.cjs.map
|