dexe-mcp 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +262 -136
  2. package/dist/lib/merkleTree.d.ts +38 -0
  3. package/dist/lib/merkleTree.d.ts.map +1 -0
  4. package/dist/lib/merkleTree.js +83 -0
  5. package/dist/lib/merkleTree.js.map +1 -0
  6. package/dist/tools/flow.d.ts +57 -0
  7. package/dist/tools/flow.d.ts.map +1 -1
  8. package/dist/tools/flow.js +204 -176
  9. package/dist/tools/flow.js.map +1 -1
  10. package/dist/tools/inbox.d.ts +4 -0
  11. package/dist/tools/inbox.d.ts.map +1 -0
  12. package/dist/tools/inbox.js +251 -0
  13. package/dist/tools/inbox.js.map +1 -0
  14. package/dist/tools/index.d.ts.map +1 -1
  15. package/dist/tools/index.js +10 -0
  16. package/dist/tools/index.js.map +1 -1
  17. package/dist/tools/merkle.d.ts +4 -0
  18. package/dist/tools/merkle.d.ts.map +1 -0
  19. package/dist/tools/merkle.js +174 -0
  20. package/dist/tools/merkle.js.map +1 -0
  21. package/dist/tools/otc.d.ts +5 -0
  22. package/dist/tools/otc.d.ts.map +1 -0
  23. package/dist/tools/otc.js +504 -0
  24. package/dist/tools/otc.js.map +1 -0
  25. package/dist/tools/predict.d.ts +4 -0
  26. package/dist/tools/predict.d.ts.map +1 -0
  27. package/dist/tools/predict.js +209 -0
  28. package/dist/tools/predict.js.map +1 -0
  29. package/dist/tools/proposalBuildComplex.d.ts +222 -0
  30. package/dist/tools/proposalBuildComplex.d.ts.map +1 -1
  31. package/dist/tools/proposalBuildComplex.js +373 -66
  32. package/dist/tools/proposalBuildComplex.js.map +1 -1
  33. package/dist/tools/read.js +2 -2
  34. package/dist/tools/read.js.map +1 -1
  35. package/dist/tools/simulate.d.ts +27 -0
  36. package/dist/tools/simulate.d.ts.map +1 -0
  37. package/dist/tools/simulate.js +278 -0
  38. package/dist/tools/simulate.js.map +1 -0
  39. package/dist/tools/subgraph.d.ts.map +1 -1
  40. package/dist/tools/subgraph.js +303 -163
  41. package/dist/tools/subgraph.js.map +1 -1
  42. package/package.json +84 -83
@@ -0,0 +1,251 @@
1
+ import { z } from "zod";
2
+ import { Interface, isAddress, getAddress } from "ethers";
3
+ import { RpcProvider } from "../rpc.js";
4
+ import { multicall } from "../lib/multicall.js";
5
+ import { gqlRequest } from "../lib/subgraph.js";
6
+ import { proposalStateLabel } from "../lib/govEnums.js";
7
+ /**
8
+ * dexe_user_inbox — multi-DAO attention aggregator.
9
+ *
10
+ * Per DAO, surfaces three kinds of pending items for `user`:
11
+ * 1. unvotedProposal — proposal in Voting state where user has zero personal vote
12
+ * 2. claimableRewards — proposals user voted on with a positive pendingRewards balance
13
+ * 3. lockedDeposit — UserKeeper.tokenBalance(user, PersonalVote).balance > 0
14
+ * (i.e. tokens still parked in the DAO and reclaimable)
15
+ *
16
+ * When `daos` is omitted on mainnet, the pools subgraph is queried for DAOs
17
+ * the user has a `voterInPool` row in (limit 50). On testnet (no subgraph),
18
+ * `daos[]` is required.
19
+ */
20
+ // ---------- ABI ----------
21
+ const GOV_POOL_ABI = new Interface([
22
+ "function getHelperContracts() view returns (address settings, address userKeeper, address validators, address poolRegistry, address votePower)",
23
+ "function getProposals(uint256 offset, uint256 limit) view returns (tuple(tuple(tuple(bool earlyCompletion, bool delegatedVotingAllowed, bool validatorsVote, uint64 duration, uint64 durationValidators, uint64 executionDelay, uint128 quorum, uint128 quorumValidators, uint256 minVotesForVoting, uint256 minVotesForCreating, tuple(address rewardToken, uint256 creationReward, uint256 executionReward, uint256 voteRewardsCoefficient) rewardsInfo, string executorDescription) settings, uint64 voteEnd, uint64 executeAfter, bool executed, uint256 votesFor, uint256 votesAgainst, uint256 rawVotesFor, uint256 rawVotesAgainst, uint256 givenRewards) core, string descriptionURL, tuple(address executor, uint256 value, bytes data)[] actionsOnFor, tuple(address executor, uint256 value, bytes data)[] actionsOnAgainst)[] proposals, tuple(uint256 proposalId, uint256 executeAfter, uint256 quorum, uint256 rawVotesFor, uint256 rawVotesAgainst, bool executed, tuple(bool earlyCompletion, bool delegatedVotingAllowed, bool validatorsVote, uint64 duration, uint64 durationValidators, uint64 executionDelay, uint128 quorum, uint128 quorumValidators, uint256 minVotesForVoting, uint256 minVotesForCreating, tuple(address rewardToken, uint256 creationReward, uint256 executionReward, uint256 voteRewardsCoefficient) rewardsInfo, string executorDescription) settings)[] validatorProposals, uint8[] proposalStates, uint256[] requiredQuorums, uint256[] requiredValidatorsQuorums)",
24
+ "function getTotalVotes(uint256 proposalId, address voter, uint8 voteType) view returns (uint256 totalVoted, uint256 totalRawVoted, uint256 votesForNow, bool isVoteFor)",
25
+ "function getPendingRewards(address user, uint256[] proposalIds) view returns (tuple(address[] tokens, uint256[] amounts, uint256[] proposalIds))",
26
+ ]);
27
+ const USER_KEEPER_ABI = new Interface([
28
+ "function tokenAddress() view returns (address)",
29
+ "function tokenBalance(address voter, uint8 voteType) view returns (uint256 balance, uint256 ownedBalance)",
30
+ ]);
31
+ // Tries to read pendingRewards using the canonical ABI; if the contract
32
+ // version doesn't expose it, we silently skip and only surface unvoted +
33
+ // lockedDeposit. The subgraph would be the next-best signal.
34
+ const PENDING_REWARDS_ABI = new Interface([
35
+ "function getPendingRewards(address user, uint256[] proposalIds) view returns (tuple(address[] tokens, uint256[] amounts, uint256[] proposalIds) rewards)",
36
+ ]);
37
+ // ---------- subgraph ----------
38
+ const USER_DAOS_QUERY = /* GraphQL */ `
39
+ query UserDaos($user: String!, $first: Int!) {
40
+ voterInPools(where: { voter_: { id: $user } }, first: $first) {
41
+ pool {
42
+ id
43
+ }
44
+ }
45
+ }
46
+ `;
47
+ // ---------- helpers ----------
48
+ function err(message) {
49
+ return { content: [{ type: "text", text: message }], isError: true };
50
+ }
51
+ function ok(data) {
52
+ return {
53
+ content: [
54
+ {
55
+ type: "text",
56
+ text: JSON.stringify(data, (_k, v) => (typeof v === "bigint" ? v.toString() : v), 2),
57
+ },
58
+ ],
59
+ };
60
+ }
61
+ // ---------- register ----------
62
+ export function registerInboxTools(server, ctx) {
63
+ const rpc = new RpcProvider(ctx.config);
64
+ server.registerTool("dexe_user_inbox", {
65
+ title: "Multi-DAO attention aggregator",
66
+ description: "Aggregates pending items across N DAOs for a user: unvoted proposals in Voting state, claimable rewards, and locked deposits. " +
67
+ "Mainnet: omits `daos` to auto-discover via the pools subgraph (limit 50). Testnet: `daos[]` required (no subgraph). " +
68
+ "Read-only.",
69
+ inputSchema: {
70
+ user: z.string().describe("User wallet address"),
71
+ daos: z
72
+ .array(z.string())
73
+ .optional()
74
+ .describe("Optional explicit DAO list. Required on testnet (chain 97)."),
75
+ proposalScanLimit: z
76
+ .number()
77
+ .int()
78
+ .min(1)
79
+ .max(100)
80
+ .default(20)
81
+ .describe("Per-DAO recent-proposal scan window for unvoted/rewards detection"),
82
+ },
83
+ }, async ({ user, daos, proposalScanLimit = 20 }) => {
84
+ if (!isAddress(user))
85
+ return err(`Invalid user: ${user}`);
86
+ const provider = rpc.requireProvider();
87
+ const userAddr = getAddress(user);
88
+ // ----- DAO list resolution -----
89
+ let resolvedDaos = [];
90
+ if (daos && daos.length > 0) {
91
+ for (const d of daos) {
92
+ if (!isAddress(d))
93
+ return err(`Invalid dao: ${d}`);
94
+ resolvedDaos.push(getAddress(d));
95
+ }
96
+ }
97
+ else {
98
+ const url = ctx.config.subgraphPoolsUrl;
99
+ if (!url) {
100
+ return err("No `daos` supplied and DEXE_SUBGRAPH_POOLS_URL is not set (testnet has no subgraph). Pass `daos: [...]` explicitly.");
101
+ }
102
+ try {
103
+ const data = await gqlRequest(url, USER_DAOS_QUERY, {
104
+ user: userAddr.toLowerCase(),
105
+ first: 50,
106
+ });
107
+ resolvedDaos = data.voterInPools.map((v) => getAddress(v.pool.id));
108
+ }
109
+ catch (e) {
110
+ return err(`Subgraph DAO discovery failed: ${e instanceof Error ? e.message : String(e)}`);
111
+ }
112
+ }
113
+ const pendingItems = [];
114
+ let daosWithItems = 0;
115
+ // ----- per-DAO scan -----
116
+ for (const dao of resolvedDaos) {
117
+ const items = [];
118
+ try {
119
+ // Step 1: fetch helpers + recent proposals in one multicall.
120
+ const [helpersR, proposalsR] = await multicall(provider, [
121
+ { target: dao, iface: GOV_POOL_ABI, method: "getHelperContracts", args: [], allowFailure: true },
122
+ {
123
+ target: dao,
124
+ iface: GOV_POOL_ABI,
125
+ method: "getProposals",
126
+ args: [0n, BigInt(proposalScanLimit)],
127
+ allowFailure: true,
128
+ },
129
+ ]);
130
+ if (!helpersR?.success)
131
+ continue;
132
+ const helpers = helpersR.value;
133
+ const userKeeper = helpers.userKeeper;
134
+ // Step 2: read deposit balance + token address.
135
+ const [tokenAddrR, balanceR] = await multicall(provider, [
136
+ { target: userKeeper, iface: USER_KEEPER_ABI, method: "tokenAddress", args: [], allowFailure: true },
137
+ {
138
+ target: userKeeper,
139
+ iface: USER_KEEPER_ABI,
140
+ method: "tokenBalance",
141
+ args: [userAddr, 0],
142
+ allowFailure: true,
143
+ },
144
+ ]);
145
+ const govToken = tokenAddrR?.success ? tokenAddrR.value : undefined;
146
+ if (balanceR?.success) {
147
+ const bal = balanceR.value;
148
+ if (bal.balance > 0n) {
149
+ items.push({
150
+ dao,
151
+ type: "lockedDeposit",
152
+ amount: bal.balance.toString(),
153
+ govToken,
154
+ });
155
+ }
156
+ }
157
+ // Step 3: walk recent proposals for unvoted in Voting state, and for
158
+ // claimable rewards on already-voted proposals.
159
+ if (proposalsR?.success) {
160
+ const raw = proposalsR.value;
161
+ const proposalIds = [];
162
+ const votingIds = [];
163
+ for (let i = 0; i < raw.proposals.length; i++) {
164
+ const id = String(i + 1);
165
+ proposalIds.push(id);
166
+ const stateIdx = Number(raw.proposalStates[i] ?? 9);
167
+ const stateName = proposalStateLabel(stateIdx);
168
+ if (stateName === "Voting" || stateName === "ValidatorVoting") {
169
+ votingIds.push({ id, deadline: raw.proposals[i].core.voteEnd.toString() });
170
+ }
171
+ }
172
+ // For each voting proposal, ask getTotalVotes → if voter has zero,
173
+ // surface as unvoted.
174
+ if (votingIds.length > 0) {
175
+ const calls = votingIds.map((p) => ({
176
+ target: dao,
177
+ iface: GOV_POOL_ABI,
178
+ method: "getTotalVotes",
179
+ args: [BigInt(p.id), userAddr, 0],
180
+ allowFailure: true,
181
+ }));
182
+ const res = await multicall(provider, calls);
183
+ for (let i = 0; i < votingIds.length; i++) {
184
+ const r = res[i];
185
+ if (!r?.success)
186
+ continue;
187
+ const v = r.value;
188
+ if (v.totalVoted === 0n) {
189
+ items.push({
190
+ dao,
191
+ type: "unvotedProposal",
192
+ proposalId: votingIds[i].id,
193
+ deadline: votingIds[i].deadline,
194
+ });
195
+ }
196
+ }
197
+ }
198
+ // Pending rewards across all scanned proposals (best-effort —
199
+ // contracts that don't expose `getPendingRewards` will silently
200
+ // produce an empty list).
201
+ if (proposalIds.length > 0) {
202
+ const [rewardsR] = await multicall(provider, [
203
+ {
204
+ target: dao,
205
+ iface: PENDING_REWARDS_ABI,
206
+ method: "getPendingRewards",
207
+ args: [userAddr, proposalIds.map((s) => BigInt(s))],
208
+ allowFailure: true,
209
+ },
210
+ ]);
211
+ if (rewardsR?.success) {
212
+ const rw = rewardsR.value;
213
+ const r = rw.rewards;
214
+ if (r.amounts && r.amounts.length > 0) {
215
+ let total = 0n;
216
+ for (const a of r.amounts)
217
+ total += a;
218
+ if (total > 0n) {
219
+ items.push({
220
+ dao,
221
+ type: "claimableRewards",
222
+ proposalIds: r.proposalIds.map((p) => p.toString()),
223
+ totalAmount: total.toString(),
224
+ });
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ }
231
+ catch {
232
+ // Best-effort per DAO — skip on failure, don't poison the inbox.
233
+ continue;
234
+ }
235
+ if (items.length > 0)
236
+ daosWithItems++;
237
+ pendingItems.push(...items);
238
+ }
239
+ const criticalCount = pendingItems.filter((i) => i.type === "unvotedProposal").length;
240
+ return ok({
241
+ user: userAddr,
242
+ pendingItems,
243
+ summary: {
244
+ totalDaos: resolvedDaos.length,
245
+ daosWithItems,
246
+ criticalCount,
247
+ },
248
+ });
249
+ });
250
+ }
251
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/tools/inbox.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAyB/C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA0BvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA8B/C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+BvE"}
@@ -19,6 +19,11 @@ import { registerDaoDeployTools } from "./daoDeploy.js";
19
19
  import { registerSubgraphTools } from "./subgraph.js";
20
20
  import { registerTxTools } from "./txSend.js";
21
21
  import { registerFlowTools } from "./flow.js";
22
+ import { registerMerkleTools } from "./merkle.js";
23
+ import { registerOtcTools } from "./otc.js";
24
+ import { registerSimulateTools } from "./simulate.js";
25
+ import { registerInboxTools } from "./inbox.js";
26
+ import { registerPredictTools } from "./predict.js";
22
27
  import { SignerManager } from "../lib/signer.js";
23
28
  /**
24
29
  * Wire every dexe-mcp tool onto the given server instance. Builds the shared
@@ -46,8 +51,13 @@ export function registerAll(server, config) {
46
51
  registerVoteBuildTools(server, ctx);
47
52
  registerDaoDeployTools(server, ctx);
48
53
  registerSubgraphTools(server, ctx);
54
+ registerMerkleTools(server, ctx);
55
+ registerInboxTools(server, ctx);
56
+ registerPredictTools(server, ctx);
49
57
  const signer = new SignerManager(config);
50
58
  registerTxTools(server, config, signer);
51
59
  registerFlowTools(server, ctx, signer);
60
+ registerOtcTools(server, ctx, signer);
61
+ registerSimulateTools(server, ctx, signer);
52
62
  }
53
63
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolContext } from "./context.js";
3
+ export declare function registerMerkleTools(server: McpServer, _ctx: ToolContext): void;
4
+ //# sourceMappingURL=merkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../../src/tools/merkle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AA0ChD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CA+J9E"}
@@ -0,0 +1,174 @@
1
+ import { z } from "zod";
2
+ import { isAddress, getAddress } from "ethers";
3
+ import { buildAddressMerkleTree, buildMerkleTree, computeLeafHash, verifyProof, } from "../lib/merkleTree.js";
4
+ /**
5
+ * Merkle utility tools — produce roots and proofs compatible with
6
+ * OpenZeppelin's `StandardMerkleTree` and the on-chain verifier in
7
+ * `TokenSaleProposalBuy.sol::_checkMerkleProofs`.
8
+ *
9
+ * Default leaf encoding is `["address"]` (the only shape used by the
10
+ * frontend's OTC token-sale flow). Set `leafEncoding` + `entries` for
11
+ * advanced trees (e.g. `["address","uint256"]`).
12
+ */
13
+ function errorResult(message) {
14
+ return { content: [{ type: "text", text: message }], isError: true };
15
+ }
16
+ function jsonResult(value) {
17
+ return {
18
+ content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
19
+ structuredContent: value,
20
+ };
21
+ }
22
+ function normaliseAddresses(addresses) {
23
+ const seen = new Set();
24
+ const result = [];
25
+ for (const raw of addresses) {
26
+ if (!isAddress(raw))
27
+ throw new Error(`Invalid address: ${raw}`);
28
+ const checksummed = getAddress(raw);
29
+ if (seen.has(checksummed.toLowerCase()))
30
+ continue;
31
+ seen.add(checksummed.toLowerCase());
32
+ result.push(checksummed);
33
+ }
34
+ return result;
35
+ }
36
+ export function registerMerkleTools(server, _ctx) {
37
+ server.registerTool("dexe_merkle_build", {
38
+ title: "Build a merkle tree (OZ StandardMerkleTree compatible)",
39
+ description: "Builds a merkle tree compatible with OpenZeppelin StandardMerkleTree (used by DeXe's TokenSaleProposal merkle whitelists). Default leaf shape is a single address; pass `leafEncoding` + `entries` for richer leaves (e.g. address + amount). Returns root, leaf hashes, and per-input-index proofs.",
40
+ inputSchema: {
41
+ addresses: z
42
+ .array(z.string())
43
+ .min(1)
44
+ .optional()
45
+ .describe("Convenience: addresses for an `address`-only merkle whitelist. Mutually exclusive with `entries`."),
46
+ entries: z
47
+ .array(z.array(z.union([z.string(), z.number()])))
48
+ .min(1)
49
+ .optional()
50
+ .describe("Advanced: per-leaf raw values matching `leafEncoding` order. Mutually exclusive with `addresses`."),
51
+ leafEncoding: z
52
+ .array(z.string())
53
+ .min(1)
54
+ .default(["address"])
55
+ .describe("ABI types for each leaf column. Default `['address']` matches the OTC frontend."),
56
+ },
57
+ outputSchema: {
58
+ root: z.string(),
59
+ leafHashes: z.array(z.string()),
60
+ proofs: z.array(z.array(z.string())),
61
+ addresses: z.array(z.string()).optional(),
62
+ },
63
+ }, async ({ addresses, entries, leafEncoding = ["address"] }) => {
64
+ try {
65
+ if (!addresses && !entries) {
66
+ return errorResult("Must provide either `addresses` or `entries`.");
67
+ }
68
+ if (addresses && entries) {
69
+ return errorResult("Provide either `addresses` or `entries`, not both.");
70
+ }
71
+ if (addresses) {
72
+ const normalised = normaliseAddresses(addresses);
73
+ const result = buildAddressMerkleTree(normalised);
74
+ return jsonResult({
75
+ root: result.root,
76
+ leafHashes: result.leafHashes,
77
+ proofs: result.proofs,
78
+ addresses: normalised,
79
+ });
80
+ }
81
+ const result = buildMerkleTree(entries, leafEncoding);
82
+ return jsonResult({
83
+ root: result.root,
84
+ leafHashes: result.leafHashes,
85
+ proofs: result.proofs,
86
+ });
87
+ }
88
+ catch (err) {
89
+ return errorResult(err instanceof Error ? err.message : String(err));
90
+ }
91
+ });
92
+ server.registerTool("dexe_merkle_proof", {
93
+ title: "Compute a merkle proof for one address (or leaf)",
94
+ description: "Builds the same tree as `dexe_merkle_build` and returns the proof for a single target. Useful for buyer-side flows where the full whitelist is known but only one proof is needed. Default shape: address-only.",
95
+ inputSchema: {
96
+ addresses: z
97
+ .array(z.string())
98
+ .min(1)
99
+ .optional()
100
+ .describe("Address-only whitelist (mutually exclusive with `entries`)."),
101
+ entries: z
102
+ .array(z.array(z.union([z.string(), z.number()])))
103
+ .min(1)
104
+ .optional(),
105
+ leafEncoding: z.array(z.string()).min(1).default(["address"]),
106
+ target: z.string().describe("Address (when using `addresses`)."),
107
+ targetEntry: z
108
+ .array(z.union([z.string(), z.number()]))
109
+ .optional()
110
+ .describe("Raw leaf values when using `entries`."),
111
+ },
112
+ outputSchema: {
113
+ root: z.string(),
114
+ leaf: z.string(),
115
+ proof: z.array(z.string()),
116
+ verified: z.boolean(),
117
+ },
118
+ }, async ({ addresses, entries, leafEncoding = ["address"], target, targetEntry }) => {
119
+ try {
120
+ if (!addresses && !entries) {
121
+ return errorResult("Must provide either `addresses` or `entries`.");
122
+ }
123
+ if (addresses) {
124
+ if (!isAddress(target))
125
+ return errorResult(`Invalid target address: ${target}`);
126
+ const normalised = normaliseAddresses(addresses);
127
+ const checksummed = getAddress(target);
128
+ const idx = normalised.findIndex((a) => a.toLowerCase() === checksummed.toLowerCase());
129
+ if (idx === -1) {
130
+ return errorResult(`Target ${checksummed} not present in whitelist.`);
131
+ }
132
+ const tree = buildAddressMerkleTree(normalised);
133
+ const leaf = computeLeafHash([checksummed], ["address"]);
134
+ const proof = tree.proofs[idx] ?? [];
135
+ return jsonResult({
136
+ root: tree.root,
137
+ leaf,
138
+ proof,
139
+ verified: verifyProof(proof, tree.root, leaf),
140
+ });
141
+ }
142
+ if (!entries) {
143
+ return errorResult("Must provide `entries` when not using `addresses`.");
144
+ }
145
+ if (!targetEntry) {
146
+ return errorResult("Provide `targetEntry` when using `entries`.");
147
+ }
148
+ const tree = buildMerkleTree(entries, leafEncoding);
149
+ const leaf = computeLeafHash(targetEntry, leafEncoding);
150
+ const idx = tree.leafHashes.findIndex((h) => h.toLowerCase() === leaf.toLowerCase());
151
+ if (idx === -1) {
152
+ return errorResult("Target entry leaf not in tree.");
153
+ }
154
+ let proof = [];
155
+ for (let i = 0; i < entries.length; i++) {
156
+ const candidateLeaf = computeLeafHash(entries[i], leafEncoding);
157
+ if (candidateLeaf.toLowerCase() === leaf.toLowerCase()) {
158
+ proof = tree.proofs[i] ?? [];
159
+ break;
160
+ }
161
+ }
162
+ return jsonResult({
163
+ root: tree.root,
164
+ leaf,
165
+ proof,
166
+ verified: verifyProof(proof, tree.root, leaf),
167
+ });
168
+ }
169
+ catch (err) {
170
+ return errorResult(err instanceof Error ? err.message : String(err));
171
+ }
172
+ });
173
+ }
174
+ //# sourceMappingURL=merkle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.js","sourceRoot":"","sources":["../../src/tools/merkle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B;;;;;;;;GAQG;AAEH,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,UAAU,CAAoC,KAAQ;IAC7D,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1E,iBAAiB,EAAE,KAAK;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,SAA4B;IACtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAAE,SAAS;QAClD,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,IAAiB;IACtE,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,wDAAwD;QAC/D,WAAW,EACT,sSAAsS;QACxS,WAAW,EAAE;YACX,SAAS,EAAE,CAAC;iBACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CACP,mGAAmG,CACpG;YACH,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;iBACjD,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CACP,mGAAmG,CACpG;YACH,YAAY,EAAE,CAAC;iBACZ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC;iBACpB,QAAQ,CACP,iFAAiF,CAClF;SACJ;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACpC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SAC1C;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE;QAC3D,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,WAAW,CAAC,+CAA+C,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;gBACzB,OAAO,WAAW,CAAC,oDAAoD,CAAC,CAAC;YAC3E,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;gBAClD,OAAO,UAAU,CAAC;oBAChB,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,SAAS,EAAE,UAAU;iBACtB,CAAC,CAAC;YACL,CAAC;YAED,MAAM,MAAM,GAAG,eAAe,CAAC,OAA0C,EAAE,YAAY,CAAC,CAAC;YACzF,OAAO,UAAU,CAAC;gBAChB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;QACE,KAAK,EAAE,kDAAkD;QACzD,WAAW,EACT,iNAAiN;QACnN,WAAW,EAAE;YACX,SAAS,EAAE,CAAC;iBACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACjB,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CAAC,6DAA6D,CAAC;YAC1E,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;iBACjD,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;YACb,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC;YAC7D,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAChE,WAAW,EAAE,CAAC;iBACX,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;iBACxC,QAAQ,EAAE;iBACV,QAAQ,CAAC,uCAAuC,CAAC;SACrD;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YAC1B,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;SACtB;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QAChF,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC3B,OAAO,WAAW,CAAC,+CAA+C,CAAC,CAAC;YACtE,CAAC;YACD,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;oBAAE,OAAO,WAAW,CAAC,2BAA2B,MAAM,EAAE,CAAC,CAAC;gBAChF,MAAM,UAAU,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;gBACjD,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;gBACvC,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC;gBACvF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACf,OAAO,WAAW,CAAC,UAAU,WAAW,4BAA4B,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,IAAI,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBACrC,OAAO,UAAU,CAAC;oBAChB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,IAAI;oBACJ,KAAK;oBACL,QAAQ,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;iBAC9C,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,WAAW,CAAC,oDAAoD,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,WAAW,CAAC,6CAA6C,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,IAAI,GAAG,eAAe,CAC1B,OAA0C,EAC1C,YAAY,CACb,CAAC;YACF,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YACxD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;YACrF,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,OAAO,WAAW,CAAC,gCAAgC,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,KAAK,GAAa,EAAE,CAAC;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,aAAa,GAAG,eAAe,CACnC,OAAO,CAAC,CAAC,CAAuB,EAChC,YAAY,CACb,CAAC;gBACF,IAAI,aAAa,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;oBACvD,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC7B,MAAM;gBACR,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAC;gBAChB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI;gBACJ,KAAK;gBACL,QAAQ,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;aAC9C,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolContext } from "./context.js";
3
+ import { SignerManager } from "../lib/signer.js";
4
+ export declare function registerOtcTools(server: McpServer, ctx: ToolContext, signer: SignerManager): void;
5
+ //# sourceMappingURL=otc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otc.d.ts","sourceRoot":"","sources":["../../src/tools/otc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAgEjD,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,GACpB,IAAI,CA+iBN"}