@continuumdao/ctm-mpc-defi 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +18 -0
  2. package/README.md +111 -0
  3. package/dist/agent/catalog.cjs +484 -0
  4. package/dist/agent/catalog.cjs.map +1 -0
  5. package/dist/agent/catalog.d.cts +117 -0
  6. package/dist/agent/catalog.d.ts +117 -0
  7. package/dist/agent/catalog.js +474 -0
  8. package/dist/agent/catalog.js.map +1 -0
  9. package/dist/chains/evm/index.cjs +474 -0
  10. package/dist/chains/evm/index.cjs.map +1 -0
  11. package/dist/chains/evm/index.d.cts +62 -0
  12. package/dist/chains/evm/index.d.ts +62 -0
  13. package/dist/chains/evm/index.js +459 -0
  14. package/dist/chains/evm/index.js.map +1 -0
  15. package/dist/chains/near/index.cjs +25 -0
  16. package/dist/chains/near/index.cjs.map +1 -0
  17. package/dist/chains/near/index.d.cts +37 -0
  18. package/dist/chains/near/index.d.ts +37 -0
  19. package/dist/chains/near/index.js +20 -0
  20. package/dist/chains/near/index.js.map +1 -0
  21. package/dist/chains/solana/index.cjs +25 -0
  22. package/dist/chains/solana/index.cjs.map +1 -0
  23. package/dist/chains/solana/index.d.cts +40 -0
  24. package/dist/chains/solana/index.d.ts +40 -0
  25. package/dist/chains/solana/index.js +20 -0
  26. package/dist/chains/solana/index.js.map +1 -0
  27. package/dist/core/index.cjs +128 -0
  28. package/dist/core/index.cjs.map +1 -0
  29. package/dist/core/index.d.cts +10 -0
  30. package/dist/core/index.d.ts +10 -0
  31. package/dist/core/index.js +116 -0
  32. package/dist/core/index.js.map +1 -0
  33. package/dist/envelope-CcE5Cz_q.d.ts +35 -0
  34. package/dist/envelope-DYDPnrHZ.d.cts +35 -0
  35. package/dist/index.cjs +2481 -0
  36. package/dist/index.cjs.map +1 -0
  37. package/dist/index.d.cts +15 -0
  38. package/dist/index.d.ts +15 -0
  39. package/dist/index.js +2446 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/keygen-CfNp8yKJ.d.cts +9 -0
  42. package/dist/keygen-DsINazx8.d.ts +9 -0
  43. package/dist/nodeRead-BnmSaMGO.d.cts +8 -0
  44. package/dist/nodeRead-BnmSaMGO.d.ts +8 -0
  45. package/dist/protocols/evm/curve-dao/index.cjs +869 -0
  46. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -0
  47. package/dist/protocols/evm/curve-dao/index.d.cts +147 -0
  48. package/dist/protocols/evm/curve-dao/index.d.ts +147 -0
  49. package/dist/protocols/evm/curve-dao/index.js +846 -0
  50. package/dist/protocols/evm/curve-dao/index.js.map +1 -0
  51. package/dist/protocols/evm/uniswap-v4/index.cjs +1700 -0
  52. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -0
  53. package/dist/protocols/evm/uniswap-v4/index.d.cts +323 -0
  54. package/dist/protocols/evm/uniswap-v4/index.d.ts +323 -0
  55. package/dist/protocols/evm/uniswap-v4/index.js +1659 -0
  56. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -0
  57. package/dist/registry-BwZoE668.d.cts +8 -0
  58. package/dist/registry-oMKlO_5z.d.ts +8 -0
  59. package/dist/txParams-BC7ogvdR.d.cts +19 -0
  60. package/dist/txParams-BC7ogvdR.d.ts +19 -0
  61. package/dist/types-5u863Fd9.d.ts +34 -0
  62. package/dist/types-B8idm_gu.d.cts +34 -0
  63. package/dist/types-Ce2qNHai.d.cts +57 -0
  64. package/dist/types-Ce2qNHai.d.ts +57 -0
  65. package/package.json +94 -0
package/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Business Source License 1.1 (For this repository)
2
+
3
+ Copyright (c) 2025 ContinuumDAO
4
+
5
+ Licensor: ContinuumDAO
6
+
7
+ Licensed under the Business Source License v1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://mariadb.com/bsl11/.
8
+
9
+ Software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
10
+
11
+ IMPORTANT NOTE: This license will automatically transition to the GNU General Public License v3.0 or later on January 1, 2030. After this date, this software will be licensed under GPL-3.0-or-later.
12
+
13
+ For the full text of the GNU General Public License v3.0, see:
14
+ https://www.gnu.org/licenses/gpl-3.0.txt
15
+
16
+ CHANGE DATE: 2030-01-01
17
+
18
+ CHANGE LICENSE: GPL-3.0-or-later
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # @continuumdao/ctm-mpc-defi
2
+
3
+ Continuum MPC DeFi protocol library — builds **multiSignRequest** payloads for EVM (and future chain categories). Usable from the Next.js app and from AI agents / Node scripts.
4
+
5
+ **License:** [Business Source License 1.1](LICENSE) (ContinuumDAO). Converts to GPL-3.0-or-later on 2030-01-01.
6
+
7
+ ## Architecture
8
+
9
+ | Layer | Path | Role |
10
+ |-------|------|------|
11
+ | Core | `src/core/` | KeyGen, purpose, mpc-auth envelope, registry |
12
+ | Chain categories | `src/chains/<category>/` | EVM batch builder, fees; Solana/NEAR stubs |
13
+ | Protocols | `src/protocols/<category>/<name>/` | DeFi actions (Uniswap V4, Curve DAO, …) |
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @continuumdao/ctm-mpc-defi viem
19
+ ```
20
+
21
+ Local link with the app:
22
+
23
+ ```json
24
+ "@continuumdao/ctm-mpc-defi": "file:../ctm-mpc-defi"
25
+ ```
26
+
27
+ Run `npm run build` in this repo after changes so `dist/` is up to date.
28
+
29
+ ## Package exports
30
+
31
+ - `@continuumdao/ctm-mpc-defi` — core + registry
32
+ - `@continuumdao/ctm-mpc-defi/core`
33
+ - `@continuumdao/ctm-mpc-defi/chains/evm`
34
+ - `@continuumdao/ctm-mpc-defi/protocols/evm/uniswap-v4`
35
+ - `@continuumdao/ctm-mpc-defi/protocols/evm/curve-dao`
36
+ - `@continuumdao/ctm-mpc-defi/agent` — action catalog for agents
37
+
38
+ ## Agent example (Uniswap V4)
39
+
40
+ ```typescript
41
+ import { uniswapV4 } from '@continuumdao/ctm-mpc-defi/protocols/evm/uniswap-v4'
42
+
43
+ const quote = await uniswapV4.quote({
44
+ type: 'EXACT_INPUT',
45
+ amount: '1000000',
46
+ tokenIn: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
47
+ tokenOut: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
48
+ chainId: 1,
49
+ uniswapApiKey: process.env.UNISWAP_API_KEY!,
50
+ swapper: '0xYourMpcExecutor',
51
+ })
52
+
53
+ const { bodyForSign, messageToSign } = await uniswapV4.buildSwapMultisignBody({ /* … */ })
54
+ // Sign messageToSign, POST { ...bodyForSign, clientSig, signedMessage }
55
+ ```
56
+
57
+ ## Agent catalog
58
+
59
+ Short registry (protocol actions):
60
+
61
+ ```typescript
62
+ import { getAgentCatalog } from '@continuumdao/ctm-mpc-defi/agent'
63
+ console.log(getAgentCatalog().byCategory.evm)
64
+ ```
65
+
66
+ **MCP servers** should use the richer tool definitions (descriptions, input/output schema, handler mapping, prerequisites):
67
+
68
+ ```typescript
69
+ import { getMcpToolDefinitions, getAgentCatalogForMcp } from '@continuumdao/ctm-mpc-defi/agent'
70
+
71
+ for (const tool of getMcpToolDefinitions()) {
72
+ // Register each tool with your MCP server using tool.name, tool.description,
73
+ // tool.inputSchema, tool.outputSchema; invoke via tool.handler.importPath + exportName
74
+ }
75
+ ```
76
+
77
+ Each MCP tool includes:
78
+ - Long `description` (what it does and does not do)
79
+ - `inputSchema` / `outputSchema` (including `MultisignBuildResult` for sign builders)
80
+ - `prerequisites` / `followUp` (typical quote → swap → multisign → sign → POST flow)
81
+ - `handler`: `{ importPath, exportName }` pointing at the library export to call
82
+
83
+ ## Development
84
+
85
+ ```bash
86
+ npm install
87
+ npm run build
88
+ npm test
89
+ npm run typecheck
90
+ ```
91
+
92
+ ## Publish (npm)
93
+
94
+ Scoped package for the [ContinuumDAO npm org](https://www.npmjs.com/org/continuumdao):
95
+
96
+ ```bash
97
+ npm login
98
+ npm publish
99
+ ```
100
+
101
+ Install in consumers:
102
+
103
+ ```bash
104
+ npm install @continuumdao/ctm-mpc-defi
105
+ ```
106
+
107
+ For local development against the sibling repo:
108
+
109
+ ```json
110
+ "@continuumdao/ctm-mpc-defi": "file:../ctm-mpc-defi"
111
+ ```
@@ -0,0 +1,484 @@
1
+ 'use strict';
2
+
3
+ require('viem');
4
+
5
+ // src/core/registry.ts
6
+ var modules = [];
7
+ function registerProtocolModule(mod) {
8
+ const existing = modules.findIndex((m) => m.id === mod.id);
9
+ if (existing >= 0) {
10
+ modules[existing] = mod;
11
+ } else {
12
+ modules.push(mod);
13
+ }
14
+ }
15
+ function getProtocolModules() {
16
+ return modules;
17
+ }
18
+ function getActionsByChainCategory(category) {
19
+ return modules.filter((m) => m.chainCategory === category).flatMap((m) => m.actions);
20
+ }
21
+
22
+ // src/chains/evm/chainIdParse.ts
23
+ function parseEvmChainIdToNumber(chainId) {
24
+ if (chainId == null) return Number.NaN;
25
+ if (typeof chainId === "bigint") {
26
+ const n = Number(chainId);
27
+ return Number.isSafeInteger(n) && n >= 0 ? n : Number.NaN;
28
+ }
29
+ if (typeof chainId === "number") {
30
+ return Number.isInteger(chainId) && chainId >= 0 ? chainId : Number.NaN;
31
+ }
32
+ const t = String(chainId).trim();
33
+ if (!t) return Number.NaN;
34
+ const low = t.toLowerCase();
35
+ if (low.startsWith("eip155:")) {
36
+ const rest = t.slice("eip155:".length).trim();
37
+ const n = Number.parseInt(rest, 10);
38
+ return Number.isNaN(n) || n < 0 ? Number.NaN : n;
39
+ }
40
+ if (low.startsWith("0x")) {
41
+ return Number.parseInt(t, 16);
42
+ }
43
+ return Number.parseInt(t, 10);
44
+ }
45
+
46
+ // src/protocols/evm/uniswap-v4/constants.ts
47
+ var UNIVERSAL_ROUTER_SPENDER = {
48
+ 1: "0x66a9893cc07d91d95644aedd05d03f95e1dba8af",
49
+ 5: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
50
+ 11155111: "0x3a9d48ab9751398bbfa63ad67599bb04e4bdf98b",
51
+ 137: "0x1095692a6237d83c6a72f3f5efedb9a670c49223",
52
+ 80001: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
53
+ 10: "0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",
54
+ 420: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
55
+ 42161: "0xa51afafe0263b40edaef0df8781ea9aa03e381a3",
56
+ 421613: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
57
+ 42220: "0xcb695bc5D3Aa22cAD1E6DF07801b061a05A0233A",
58
+ 44787: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
59
+ 56: "0x1906c1d672b88cd1b9ac7593301ca990f94eae07",
60
+ 43114: "0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",
61
+ 84531: "0xd0872d928672ae2ff74bdb2f5130ac12229cafaf",
62
+ 8453: "0x6fF5693b99212da76ad316178a184ab56d299b43",
63
+ 81457: "0xeabbcb3e8e415306207ef514f660a3f820025be3",
64
+ 7777777: "0x3315ef7ca28db74abadc6c44570efdf06b04b020",
65
+ 324: "0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06",
66
+ 480: "0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743",
67
+ 1301: "0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d",
68
+ 130: "0xef740bf23acae26f6492b10de645d6b98dc8eaf3",
69
+ 10143: "0x3ae6d8a282d67893e17aa70ebffb33ee5aa65893",
70
+ 84532: "0x492e6456d9528771018deb9e87ef7750ef184104",
71
+ 1868: "0x0e2850543f69f678257266e0907ff9a58b3f13de",
72
+ 143: "0x0d97dc33264bfc1c226207428a79b26757fb9dc3",
73
+ 59144: "0x661e93cca42afacb172121ef892830ca3b70f08d",
74
+ 4217: "0x1febb76be10aaf3a1402f04e8e835f2c382f7914",
75
+ 196: "0x5507749f2c558bb3e162c6e90c314c092e7372ff"
76
+ };
77
+ function isUniswapV4ChainSupported(chainId) {
78
+ if (chainId == null) return false;
79
+ const n = parseEvmChainIdToNumber(chainId);
80
+ if (Number.isNaN(n) || n < 0) return false;
81
+ const a = UNIVERSAL_ROUTER_SPENDER[n];
82
+ return typeof a === "string" && a.startsWith("0x");
83
+ }
84
+
85
+ // src/protocols/evm/uniswap-v4/index.ts
86
+ var UNISWAP_V4_PROTOCOL_ID = "uniswap-v4";
87
+ var uniswapV4ProtocolModule = {
88
+ id: UNISWAP_V4_PROTOCOL_ID,
89
+ chainCategory: "evm",
90
+ isChainSupported(ctx) {
91
+ if (ctx.chainCategory !== "evm") return false;
92
+ return isUniswapV4ChainSupported(ctx.chainId);
93
+ },
94
+ isTokenSupported(token) {
95
+ if (token.category !== "evm") return false;
96
+ return token.kind === "native" || token.kind === "erc20";
97
+ },
98
+ actions: [
99
+ {
100
+ id: "uniswap-v4.swap-exact-input",
101
+ protocolId: UNISWAP_V4_PROTOCOL_ID,
102
+ chainCategory: "evm",
103
+ description: "Swap ERC-20 or native token via Uniswap V4 Universal Router (classic allowance path)",
104
+ commonParams: ["keyGen", "purposeText", "useCustomGas"],
105
+ params: {
106
+ tokenIn: { type: "address", required: true, description: "Input token (0x0 for native)" },
107
+ tokenOut: { type: "address", required: true, description: "Output token address" },
108
+ amount: { type: "string", required: true, description: "Human or wei amount per trade type" },
109
+ slippagePercent: { type: "number", required: true, description: "Slippage tolerance percent" },
110
+ swapTransactionDeadlineUnix: {
111
+ type: "number",
112
+ required: false,
113
+ description: "On-chain swap deadline (unix seconds)"
114
+ },
115
+ uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API key" }
116
+ }
117
+ },
118
+ {
119
+ id: "uniswap-v4.quote",
120
+ protocolId: UNISWAP_V4_PROTOCOL_ID,
121
+ chainCategory: "evm",
122
+ description: "Fetch Uniswap Trade API quote",
123
+ commonParams: ["keyGen"],
124
+ params: {
125
+ tokenIn: { type: "address", required: true, description: "Input token" },
126
+ tokenOut: { type: "address", required: true, description: "Output token" },
127
+ amount: { type: "string", required: true, description: "Amount for quote" },
128
+ type: { type: "EXACT_INPUT | EXACT_OUTPUT", required: true, description: "Trade type" }
129
+ }
130
+ }
131
+ ]
132
+ };
133
+ registerProtocolModule(uniswapV4ProtocolModule);
134
+
135
+ // src/protocols/evm/curve-dao/support.ts
136
+ var CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS = /* @__PURE__ */ new Set([
137
+ 1,
138
+ 10,
139
+ 56,
140
+ 100,
141
+ 137,
142
+ 146,
143
+ 196,
144
+ 250,
145
+ 252,
146
+ 324,
147
+ 999,
148
+ 1284,
149
+ 2222,
150
+ 5e3,
151
+ 8453,
152
+ 42161,
153
+ 42220,
154
+ 43114,
155
+ 1313161554
156
+ ]);
157
+ function isCurveApiChainSupported(chainId) {
158
+ const n = parseEvmChainIdToNumber(chainId);
159
+ if (Number.isNaN(n) || n < 0) return false;
160
+ return CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS.has(n);
161
+ }
162
+
163
+ // src/protocols/evm/curve-dao/index.ts
164
+ var CURVE_DAO_PROTOCOL_ID = "curve-dao";
165
+ var curveDaoProtocolModule = {
166
+ id: CURVE_DAO_PROTOCOL_ID,
167
+ chainCategory: "evm",
168
+ isChainSupported(ctx) {
169
+ if (ctx.chainCategory !== "evm") return false;
170
+ return isCurveApiChainSupported(ctx.chainId);
171
+ },
172
+ isTokenSupported(token) {
173
+ if (token.category !== "evm") return false;
174
+ return token.kind === "native" || token.kind === "erc20";
175
+ },
176
+ actions: [
177
+ {
178
+ id: "curve-dao.swap",
179
+ protocolId: CURVE_DAO_PROTOCOL_ID,
180
+ chainCategory: "evm",
181
+ description: "Swap via Curve Router NG (optional ERC-20 approve batch)",
182
+ commonParams: ["keyGen", "purposeText", "useCustomGas"],
183
+ params: {
184
+ tokenIn: { type: "address", required: true, description: "ERC-20 token in (native uses WETH path in UI)" },
185
+ tokenOut: { type: "address", required: true, description: "Output token or 0xeeee\u2026 native placeholder" },
186
+ amountHuman: { type: "string", required: true, description: "Human-readable input amount" },
187
+ slippagePercent: { type: "number", required: true, description: "Slippage percent (0\u2013100 exclusive)" }
188
+ }
189
+ }
190
+ ]
191
+ };
192
+ registerProtocolModule(curveDaoProtocolModule);
193
+
194
+ // src/agent/commonParamDocs.ts
195
+ var EVM_COMMON_PARAM_DOCS = {
196
+ keyGen: {
197
+ type: "object",
198
+ required: true,
199
+ description: "MPC key slice: { pubkeyhex: string (required), keylist: string[], ClientKeys?: Record<string,string> }. Used for pubKey/keyList on POST /multiSignRequest."
200
+ },
201
+ purposeText: {
202
+ type: "string",
203
+ required: true,
204
+ description: "Human-readable purpose for the sign request. Stored in bodyForSign.purpose (may be appended with an automatic batch suffix)."
205
+ },
206
+ useCustomGas: {
207
+ type: "boolean",
208
+ required: true,
209
+ description: "When true, apply chain gas settings from chainDetail / customGasChainDetails instead of raw RPC estimates only."
210
+ },
211
+ chainId: {
212
+ type: "number",
213
+ required: true,
214
+ description: "EVM chain id (decimal). Becomes destinationChainID on the sign request."
215
+ },
216
+ rpcUrl: {
217
+ type: "string",
218
+ required: true,
219
+ description: "HTTPS JSON-RPC URL for gas estimation, nonce, and allowance reads."
220
+ },
221
+ executorAddress: {
222
+ type: "address",
223
+ required: true,
224
+ description: "MPC wallet address (from keyGen ethereumaddress) \u2014 tx sender for estimates and approvals."
225
+ },
226
+ chainDetail: {
227
+ type: "object",
228
+ required: true,
229
+ description: "Optional gas config: { legacy?, gasLimit?, gasMultiplier?, gasPrice?, baseFee?, priorityFee?, baseFeeMultiplier? }."
230
+ },
231
+ customGasChainDetails: {
232
+ type: "object",
233
+ required: false,
234
+ description: "Snapshot written to extraJSON.customGasChainDetails when useCustomGas is true."
235
+ }
236
+ };
237
+ var MULTISIGN_OUTPUT_DOC = {
238
+ description: "Unsigned mpc-auth multiSignRequest payload. The caller must sign messageToSign (MetaMask personal_sign or Ed25519) and POST { ...bodyForSign, clientSig, signedMessage: messageToSign } to /multiSignRequest.",
239
+ fields: {
240
+ bodyForSign: {
241
+ type: "object",
242
+ description: "POST body fields without clientSig: keyList, pubKey, msgHash, msgRaw, destinationChainID, purpose, extraJSON, proposalTxParams (batch), messageHashes/messageRawBatch when N>1 txs."
243
+ },
244
+ messageToSign: {
245
+ type: "string",
246
+ description: "JSON.stringify(bodyForSign) \u2014 exact string to sign before adding clientSig."
247
+ }
248
+ }
249
+ };
250
+
251
+ // src/agent/mcpTools.ts
252
+ function paramProperties(params, includeCommon = []) {
253
+ const out = {};
254
+ for (const k of includeCommon) {
255
+ const d = EVM_COMMON_PARAM_DOCS[k];
256
+ if (d) out[k] = { type: d.type, description: d.description };
257
+ }
258
+ for (const [k, d] of Object.entries(params)) {
259
+ out[k] = { type: d.type, description: d.description };
260
+ }
261
+ return out;
262
+ }
263
+ function requiredKeys(params, includeCommon = []) {
264
+ const req = [];
265
+ for (const k of includeCommon) {
266
+ if (EVM_COMMON_PARAM_DOCS[k]?.required) req.push(k);
267
+ }
268
+ for (const [k, d] of Object.entries(params)) {
269
+ if (d.required) req.push(k);
270
+ }
271
+ return req;
272
+ }
273
+ var multisignOutputSchema = {
274
+ type: "object",
275
+ description: MULTISIGN_OUTPUT_DOC.description,
276
+ properties: {
277
+ bodyForSign: {
278
+ type: "object",
279
+ description: MULTISIGN_OUTPUT_DOC.fields.bodyForSign.description
280
+ },
281
+ messageToSign: {
282
+ type: "string",
283
+ description: MULTISIGN_OUTPUT_DOC.fields.messageToSign.description
284
+ }
285
+ },
286
+ required: ["bodyForSign", "messageToSign"]
287
+ };
288
+ var MCP_TOOL_DEFINITIONS = [
289
+ {
290
+ name: "ctm_uniswap_v4_quote",
291
+ actionId: "uniswap-v4.quote",
292
+ protocolId: "uniswap-v4",
293
+ chainCategory: "evm",
294
+ 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.",
295
+ prerequisites: ["Chain must be supported by Uniswap V4 (Universal Router map)."],
296
+ followUp: ["ctm_uniswap_v4_create_swap", "ctm_uniswap_v4_build_swap_multisign"],
297
+ handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapTradeQuote" },
298
+ inputSchema: {
299
+ type: "object",
300
+ properties: paramProperties({
301
+ type: { type: "string", required: true, description: "EXACT_INPUT or EXACT_OUTPUT" },
302
+ amount: { type: "string", required: true, description: "Amount in token-in base units (wei string for ERC-20)" },
303
+ tokenIn: { type: "address", required: true, description: "Input token; 0x0 for native ETH" },
304
+ tokenOut: { type: "address", required: true, description: "Output token address" },
305
+ chainId: { type: "number", required: true, description: "tokenInChainId / same-chain default" },
306
+ uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API x-api-key" },
307
+ swapper: { type: "address", required: false, description: "MPC executor; omit if keyGen + managementNodeUrl provided" },
308
+ slippage: { type: "number", required: false, description: "Slippage percent; omit for API auto slippage" }
309
+ }),
310
+ required: requiredKeys({
311
+ type: { type: "string", required: true, description: "" },
312
+ amount: { type: "string", required: true, description: "" },
313
+ tokenIn: { type: "address", required: true, description: "" },
314
+ tokenOut: { type: "address", required: true, description: "" },
315
+ chainId: { type: "number", required: true, description: "" },
316
+ uniswapApiKey: { type: "string", required: true, description: "" }
317
+ })
318
+ },
319
+ outputSchema: {
320
+ type: "object",
321
+ description: "Full Uniswap POST /quote JSON (includes nested quote object with input/output amounts)."
322
+ }
323
+ },
324
+ {
325
+ name: "ctm_uniswap_v4_create_swap",
326
+ actionId: "uniswap-v4.create-swap",
327
+ protocolId: "uniswap-v4",
328
+ chainCategory: "evm",
329
+ 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.",
330
+ prerequisites: ["ctm_uniswap_v4_quote output (fullQuoteFromPermit)"],
331
+ followUp: ["ctm_uniswap_v4_build_swap_multisign"],
332
+ handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapCreateSwap" },
333
+ inputSchema: {
334
+ type: "object",
335
+ properties: paramProperties({
336
+ uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API key" },
337
+ fullQuoteFromPermit: { type: "object", required: true, description: "Full quote JSON from ctm_uniswap_v4_quote" },
338
+ swapTransactionDeadlineUnix: {
339
+ type: "number",
340
+ required: false,
341
+ description: "On-chain deadline unix seconds; default ~30 min from now"
342
+ },
343
+ useServerProxy: {
344
+ type: "boolean",
345
+ required: false,
346
+ description: "Set false in Node/agents; true only in browser via Next API route"
347
+ }
348
+ }),
349
+ required: requiredKeys({
350
+ uniswapApiKey: { type: "string", required: true, description: "" },
351
+ fullQuoteFromPermit: { type: "object", required: true, description: "" }
352
+ })
353
+ },
354
+ outputSchema: {
355
+ type: "object",
356
+ description: "{ swap: TransactionRequest, requestId?, gasFee? }"
357
+ }
358
+ },
359
+ {
360
+ name: "ctm_uniswap_v4_build_swap_multisign",
361
+ actionId: "uniswap-v4.swap-exact-input",
362
+ protocolId: "uniswap-v4",
363
+ chainCategory: "evm",
364
+ 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.",
365
+ prerequisites: [
366
+ "ctm_uniswap_v4_create_swap output",
367
+ "keyGen with pubkeyhex",
368
+ "executorAddress matching MPC wallet",
369
+ "RPC URL and chainDetail from node chain config"
370
+ ],
371
+ followUp: ["Sign messageToSign", "POST /multiSignRequest with clientSig"],
372
+ handler: { importPath: "protocols/evm/uniswap-v4", exportName: "buildEvmMultisignBodyUniswapV4SkipPermit2Batch" },
373
+ inputSchema: {
374
+ type: "object",
375
+ properties: paramProperties(
376
+ {
377
+ tokenIn: { type: "address", required: true, description: "Token in; 0x0 for native ETH" },
378
+ swap: { type: "object", required: true, description: "swap field from create_swap response" },
379
+ createSwapResponse: { type: "object", required: true, description: "Full create_swap response" },
380
+ fullQuoteSnapshot: { type: "object", required: true, description: "Quote JSON used for the swap" },
381
+ swapDeadlineUnix: { type: "number", required: true, description: "Same deadline passed to create_swap" },
382
+ slippagePercent: { type: "number", required: false, description: "Extra approve headroom for EXACT_OUTPUT" }
383
+ },
384
+ ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail", "customGasChainDetails"]
385
+ ),
386
+ required: requiredKeys(
387
+ {
388
+ tokenIn: { type: "address", required: true, description: "" },
389
+ swap: { type: "object", required: true, description: "" },
390
+ createSwapResponse: { type: "object", required: true, description: "" },
391
+ fullQuoteSnapshot: { type: "object", required: true, description: "" },
392
+ swapDeadlineUnix: { type: "number", required: true, description: "" }
393
+ },
394
+ ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail"]
395
+ )
396
+ },
397
+ outputSchema: multisignOutputSchema
398
+ },
399
+ {
400
+ name: "ctm_curve_dao_build_swap_multisign",
401
+ actionId: "curve-dao.swap",
402
+ protocolId: "curve-dao",
403
+ chainCategory: "evm",
404
+ 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.",
405
+ prerequisites: ["keyGen", "executorAddress", "tokenIn/tokenOut/amountHuman/slippage", "RPC URL"],
406
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
407
+ handler: { importPath: "protocols/evm/curve-dao", exportName: "buildEvmMultisignBodyCurveDaoBatch" },
408
+ inputSchema: {
409
+ type: "object",
410
+ properties: paramProperties(
411
+ {
412
+ tokenIn: { type: "address", required: true, description: "ERC-20 sold (native in uses WETH path in UI)" },
413
+ tokenOut: { type: "string", required: true, description: "Output token or 0xeeee\u2026 native placeholder" },
414
+ amountHuman: { type: "string", required: true, description: "Human-readable amount of tokenIn" },
415
+ slippagePercent: { type: "number", required: true, description: "Slippage 0\u2013100 exclusive" }
416
+ },
417
+ ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail", "customGasChainDetails"]
418
+ ),
419
+ required: requiredKeys(
420
+ {
421
+ tokenIn: { type: "address", required: true, description: "" },
422
+ tokenOut: { type: "string", required: true, description: "" },
423
+ amountHuman: { type: "string", required: true, description: "" },
424
+ slippagePercent: { type: "number", required: true, description: "" }
425
+ },
426
+ ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail"]
427
+ )
428
+ },
429
+ outputSchema: multisignOutputSchema
430
+ }
431
+ ];
432
+ function getMcpToolDefinitions() {
433
+ return MCP_TOOL_DEFINITIONS;
434
+ }
435
+ function getMcpToolByName(name) {
436
+ return MCP_TOOL_DEFINITIONS.find((t) => t.name === name);
437
+ }
438
+ function getAgentCatalogForMcp() {
439
+ return {
440
+ tools: MCP_TOOL_DEFINITIONS,
441
+ protocols: getProtocolModules(),
442
+ commonParams: EVM_COMMON_PARAM_DOCS,
443
+ multisignOutput: MULTISIGN_OUTPUT_DOC,
444
+ workflow: {
445
+ evmSwapTypical: [
446
+ "1. Quote (protocol-specific API if needed)",
447
+ "2. Build protocol calldata (e.g. create_swap)",
448
+ "3. build_*_multisign \u2192 { bodyForSign, messageToSign }",
449
+ "4. Sign messageToSign (MetaMask or Ed25519)",
450
+ "5. POST /multiSignRequest with clientSig and signedMessage"
451
+ ]
452
+ }
453
+ };
454
+ }
455
+
456
+ // src/agent/catalog.ts
457
+ registerProtocolModule(uniswapV4ProtocolModule);
458
+ registerProtocolModule(curveDaoProtocolModule);
459
+ function getAgentCatalog() {
460
+ return {
461
+ protocols: getProtocolModules(),
462
+ byCategory: {
463
+ evm: getActionsByChainCategory("evm"),
464
+ solana: getActionsByChainCategory("solana"),
465
+ near: getActionsByChainCategory("near")
466
+ },
467
+ uniswapV4: uniswapV4ProtocolModule,
468
+ curveDao: curveDaoProtocolModule,
469
+ /** Prefer getAgentCatalogForMcp() or getMcpToolDefinitions() for MCP servers. */
470
+ mcp: getAgentCatalogForMcp()
471
+ };
472
+ }
473
+
474
+ exports.EVM_COMMON_PARAM_DOCS = EVM_COMMON_PARAM_DOCS;
475
+ exports.MCP_TOOL_DEFINITIONS = MCP_TOOL_DEFINITIONS;
476
+ exports.MULTISIGN_OUTPUT_DOC = MULTISIGN_OUTPUT_DOC;
477
+ exports.getActionsByChainCategory = getActionsByChainCategory;
478
+ exports.getAgentCatalog = getAgentCatalog;
479
+ exports.getAgentCatalogForMcp = getAgentCatalogForMcp;
480
+ exports.getMcpToolByName = getMcpToolByName;
481
+ exports.getMcpToolDefinitions = getMcpToolDefinitions;
482
+ exports.getProtocolModules = getProtocolModules;
483
+ //# sourceMappingURL=catalog.cjs.map
484
+ //# sourceMappingURL=catalog.cjs.map