dexe-mcp 0.5.7 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +641 -497
- package/README.md +193 -104
- package/SECURITY.md +96 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -1
- package/dist/governor/adapter.d.ts +90 -0
- package/dist/governor/adapter.d.ts.map +1 -0
- package/dist/governor/adapter.js +169 -0
- package/dist/governor/adapter.js.map +1 -0
- package/dist/governor/configs/compound.json +32 -0
- package/dist/governor/configs/optimism.json +28 -0
- package/dist/governor/configs/uniswap.json +32 -0
- package/dist/governor/encoder.d.ts +59 -0
- package/dist/governor/encoder.d.ts.map +1 -0
- package/dist/governor/encoder.js +290 -0
- package/dist/governor/encoder.js.map +1 -0
- package/dist/governor/index.d.ts +11 -0
- package/dist/governor/index.d.ts.map +1 -0
- package/dist/governor/index.js +20 -0
- package/dist/governor/index.js.map +1 -0
- package/dist/governor/loader.d.ts +42 -0
- package/dist/governor/loader.d.ts.map +1 -0
- package/dist/governor/loader.js +103 -0
- package/dist/governor/loader.js.map +1 -0
- package/dist/governor/tally.d.ts +48 -0
- package/dist/governor/tally.d.ts.map +1 -0
- package/dist/governor/tally.js +103 -0
- package/dist/governor/tally.js.map +1 -0
- package/dist/governor/tools/build.d.ts +3 -0
- package/dist/governor/tools/build.d.ts.map +1 -0
- package/dist/governor/tools/build.js +137 -0
- package/dist/governor/tools/build.js.map +1 -0
- package/dist/governor/tools/extras.d.ts +4 -0
- package/dist/governor/tools/extras.d.ts.map +1 -0
- package/dist/governor/tools/extras.js +197 -0
- package/dist/governor/tools/extras.js.map +1 -0
- package/dist/governor/tools/read.d.ts +4 -0
- package/dist/governor/tools/read.d.ts.map +1 -0
- package/dist/governor/tools/read.js +174 -0
- package/dist/governor/tools/read.js.map +1 -0
- package/dist/governor/tools/simulate.d.ts +6 -0
- package/dist/governor/tools/simulate.d.ts.map +1 -0
- package/dist/governor/tools/simulate.js +191 -0
- package/dist/governor/tools/simulate.js.map +1 -0
- package/dist/lib/broadcastGuards.d.ts +41 -0
- package/dist/lib/broadcastGuards.d.ts.map +1 -0
- package/dist/lib/broadcastGuards.js +85 -0
- package/dist/lib/broadcastGuards.js.map +1 -0
- package/dist/lib/ethersProvider.d.ts +96 -0
- package/dist/lib/ethersProvider.d.ts.map +1 -0
- package/dist/lib/ethersProvider.js +170 -0
- package/dist/lib/ethersProvider.js.map +1 -0
- package/dist/lib/ipfs.d.ts +7 -0
- package/dist/lib/ipfs.d.ts.map +1 -1
- package/dist/lib/ipfs.js +32 -1
- package/dist/lib/ipfs.js.map +1 -1
- package/dist/lib/signer.d.ts +2 -0
- package/dist/lib/signer.d.ts.map +1 -1
- package/dist/lib/signer.js +4 -0
- package/dist/lib/signer.js.map +1 -1
- package/dist/tools/flow.d.ts.map +1 -1
- package/dist/tools/flow.js +13 -0
- package/dist/tools/flow.js.map +1 -1
- package/dist/tools/getConfig.d.ts.map +1 -1
- package/dist/tools/getConfig.js +17 -0
- package/dist/tools/getConfig.js.map +1 -1
- package/dist/tools/inbox.js +8 -8
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ipfs.d.ts.map +1 -1
- package/dist/tools/ipfs.js +437 -16
- package/dist/tools/ipfs.js.map +1 -1
- package/dist/tools/predict.js +17 -17
- package/dist/tools/safe.d.ts +5 -0
- package/dist/tools/safe.d.ts.map +1 -0
- package/dist/tools/safe.js +264 -0
- package/dist/tools/safe.js.map +1 -0
- package/dist/tools/simulate.d.ts +7 -0
- package/dist/tools/simulate.d.ts.map +1 -1
- package/dist/tools/simulate.js +8 -0
- package/dist/tools/simulate.js.map +1 -1
- package/dist/tools/subgraph.js +162 -162
- package/dist/tools/txSend.d.ts.map +1 -1
- package/dist/tools/txSend.js +25 -0
- package/dist/tools/txSend.js.map +1 -1
- package/package.json +95 -84
package/README.md
CHANGED
|
@@ -1,56 +1,99 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.npmjs.com/package/dexe-mcp">
|
|
3
|
+
<img src="./assets/hero.svg" alt="dexe-mcp — the runtime for autonomous DAOs" width="100%"/>
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/dexe-mcp"><img alt="npm" src="https://img.shields.io/npm/v/dexe-mcp.svg?style=flat-square&labelColor=0b0f1e&color=9BB4FF"></a>
|
|
9
|
+
<a href="https://nodejs.org"><img alt="node" src="https://img.shields.io/node/v/dexe-mcp.svg?style=flat-square&labelColor=0b0f1e&color=E07AFF"></a>
|
|
10
|
+
<a href="https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/LICENSE"><img alt="license" src="https://img.shields.io/npm/l/dexe-mcp.svg?style=flat-square&labelColor=0b0f1e&color=FFC878"></a>
|
|
11
|
+
<a href="https://modelcontextprotocol.io"><img alt="MCP-compatible" src="https://img.shields.io/badge/MCP-compatible-9BB4FF?style=flat-square&labelColor=0b0f1e"></a>
|
|
12
|
+
<a href="https://github.com/edward-arinin-web-dev/dexe-mcp"><img alt="tools" src="https://img.shields.io/badge/tools-149-7CF2D1?style=flat-square&labelColor=0b0f1e"></a>
|
|
13
|
+
<a href="https://github.com/edward-arinin-web-dev/dexe-mcp"><img alt="proposal types" src="https://img.shields.io/badge/proposal--types-33-E07AFF?style=flat-square&labelColor=0b0f1e"></a>
|
|
14
|
+
</p>
|
|
4
15
|
|
|
5
|
-
|
|
16
|
+
<h2 align="center">Governance, as a function call.</h2>
|
|
6
17
|
|
|
7
|
-
|
|
18
|
+
<p align="center">
|
|
19
|
+
<code>dexe-mcp</code> turns the entire DeXe Protocol — every DAO, every proposal type, every read, every write — into <b>one Model Context Protocol server</b>.<br/>
|
|
20
|
+
Plug it into Claude, Cursor, ChatGPT, or any tool-using LLM and watch your agent <b>deploy DAOs, draft proposals, vote, delegate, execute, claim</b> — straight from natural language.<br/>
|
|
21
|
+
<sub>Calldata-first by default: keys stay in your wallet. Broadcast mode? One env var.</sub>
|
|
22
|
+
</p>
|
|
8
23
|
|
|
9
|
-
|
|
24
|
+
<p align="center">
|
|
25
|
+
<a href="#quickstart"><b>Quickstart</b></a> ·
|
|
26
|
+
<a href="#what-you-can-build">What you can build</a> ·
|
|
27
|
+
<a href="#built-for-whats-next">Built for what's next</a> ·
|
|
28
|
+
<a href="#tool-catalog">Tool catalog</a> ·
|
|
29
|
+
<a href="#swarm-test-harness">Swarm tests</a> ·
|
|
30
|
+
<a href="https://github.com/edward-arinin-web-dev/dexe-mcp/tree/main/docs">Docs</a>
|
|
31
|
+
</p>
|
|
10
32
|
|
|
11
|
-
|
|
33
|
+
---
|
|
12
34
|
|
|
13
|
-
##
|
|
35
|
+
## The shift
|
|
14
36
|
|
|
15
|
-
|
|
16
|
-
- **Git** — only needed the first time a build tool runs, to clone DeXe-Protocol. Skippable if you point `DEXE_PROTOCOL_PATH` at an existing checkout.
|
|
37
|
+
For a decade, DAOs lived behind dashboards. Every action was a click. Every read was a tab. Every coordination loop needed a human at the keyboard.
|
|
17
38
|
|
|
18
|
-
|
|
39
|
+
That era is ending.
|
|
19
40
|
|
|
20
|
-
|
|
21
|
-
npm install -g dexe-mcp
|
|
22
|
-
```
|
|
41
|
+
LLMs can now reason about voting power, weigh proposals against a mandate, draft calldata, simulate execution, and ask your wallet to sign — **continuously, across every DAO you care about, all at once.** What was a UI is becoming a conversation. What was a treasurer's spreadsheet is becoming an always-on agent.
|
|
23
42
|
|
|
24
|
-
|
|
43
|
+
**`dexe-mcp` is the substrate that makes it real for the DeXe stack — and now for external OpenZeppelin Governor DAOs as well.** One MCP server. 149 typed tools across 18 groups. Every flow the DeXe frontend exposes — plus a generic `dexe_gov_*` surface targeting Uniswap, Compound, and Optimism.
|
|
25
44
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
```
|
|
45
|
+
| | What you get |
|
|
46
|
+
|-----|------|
|
|
47
|
+
| **Total protocol coverage** | All **33 proposal types**. Validator chamber. Expert delegation. OTC multi-tier sales with merkle whitelists. Internal config. Off-chain backend. Nothing hand-rolled. Nothing missing. |
|
|
48
|
+
| **Key-safe by default** | Every write returns `TxPayload = { to, data, value, chainId }`. Your wallet — MetaMask, Safe, Ledger, anything — signs. **No keys touch the MCP unless you explicitly set `DEXE_PRIVATE_KEY`.** |
|
|
49
|
+
| **Battle-tested on-chain** | **57 swarm-test scenarios** running on BSC testnet against real fixture DAOs. Every builder validated end-to-end — draft → IPFS → propose → vote → execute. Latest pass: 2026-05-12. |
|
|
50
|
+
| **AI-native, model-agnostic** | Tool names, argument schemas, and return shapes are tuned for LLM chaining. Works with Claude, GPT, Gemini, Mistral, Llama — anything that can call MCP tools. |
|
|
51
|
+
| **Open source, no middleman** | MIT. Your RPC. Your wallet. Your keys. Your rules. No telemetry. No SaaS gatekeeper. No rate limits. Run it on your laptop or behind your agent fleet. |
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
---
|
|
37
54
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
## What you can build
|
|
56
|
+
|
|
57
|
+
> **One MCP server. Dozens of products that didn't exist a year ago.**
|
|
58
|
+
|
|
59
|
+
- **Governance copilots in chat** — *"Show every proposal I haven't voted on across all my DAOs, ranked by deadline."* The agent fans out `dexe_user_inbox`, ranks results, drafts your votes. You hit sign.
|
|
60
|
+
- **Intent-driven proposal drafting** — *"Stream 50,000 USDT from treasury to the dev fund, vesting linearly over six months."* The agent picks the right builder (`_token_distribution`), assembles nested calldata, pins metadata to IPFS, returns one signable payload. What used to be a 14-field form is now a sentence.
|
|
61
|
+
- **AI delegates that reason** — agents that read every proposal, weigh it against a written mandate, vote, and publish their reasoning on-chain. Real accountability for delegated power.
|
|
62
|
+
- **24/7 autonomous treasury bots** — policy expressed as code, executed as proposals. Market triggers, runway thresholds, vesting schedules — all enforced without a human in the loop, every action a signed on-chain decision.
|
|
63
|
+
- **Multi-DAO coalition orchestration** — one agent coordinating votes across allied protocols, tracking quorums, building coalitions, executing in lockstep.
|
|
64
|
+
- **Conversational DAO frontends** — apps where there *is* no UI. The MCP server is the backend. The chat is the dashboard. The wallet is the only button.
|
|
65
|
+
- **Adversarial governance simulators** — spin up swarms of AI proposers, voters, and validators to red-team a parameter change *before* it hits mainnet. The swarm harness ships with this already (see [Swarm tests](#swarm-test-harness)).
|
|
66
|
+
- **OTC sale autopilots** — open multi-tier sales with merkle whitelists, manage buyer flows, fulfill vested payouts — all without a sale-management UI.
|
|
67
|
+
- **Forensics and compliance** — `dexe_decode_proposal` + `_decode_calldata` make any historic on-chain proposal human-readable. Agents narrate every governance decision for audits, postmortems, and research.
|
|
68
|
+
|
|
69
|
+
If you can describe a DeXe governance operation in a sentence, `dexe-mcp` has the tool.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Built for what's next
|
|
74
|
+
|
|
75
|
+
The next generation of DAOs will be **operated by language, not by clicks.**
|
|
76
|
+
|
|
77
|
+
- **AI delegates will outvote human ones.** They read every proposal. They show their reasoning. They never miss a deadline.
|
|
78
|
+
- **Treasuries will defend themselves.** Policy bots react to market moves, rebalance, claim, redelegate — all through governance, never around it.
|
|
79
|
+
- **Cross-DAO coordination will be ambient.** Coalitions form in seconds via agent-to-agent negotiation, ratified by on-chain votes.
|
|
80
|
+
- **Governance frontends will collapse into chat.** The dashboard moves into the conversation. The UI is the prompt.
|
|
81
|
+
- **Every proposal will be simulated first.** Adversarial AI swarms stress-test changes before they reach mainnet.
|
|
82
|
+
- **Audit will run continuously.** Compliance agents decode and narrate every historical decision in real time.
|
|
48
83
|
|
|
49
|
-
|
|
84
|
+
`dexe-mcp` is the connective tissue. Bring your model. Bring your wallet. Bring your DAO.
|
|
85
|
+
|
|
86
|
+
---
|
|
50
87
|
|
|
51
88
|
## Quickstart
|
|
52
89
|
|
|
53
|
-
|
|
90
|
+
**1.** Install:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm install -g dexe-mcp
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**2.** Register with your MCP client (`.mcp.json`, `claude_desktop_config.json`, Cursor settings, etc.):
|
|
54
97
|
|
|
55
98
|
```json
|
|
56
99
|
{
|
|
@@ -66,35 +109,50 @@ Minimum config to get **read-only** access to a BSC mainnet DAO:
|
|
|
66
109
|
}
|
|
67
110
|
```
|
|
68
111
|
|
|
69
|
-
|
|
112
|
+
> **Windows note:** if your MCP client can't resolve the `dexe-mcp` shim on PATH, point it at the installed script directly:
|
|
113
|
+
> ```json
|
|
114
|
+
> { "command": "node", "args": ["<npm root -g>/dexe-mcp/dist/index.js"] }
|
|
115
|
+
> ```
|
|
116
|
+
> (Run `npm root -g` to get the absolute path.)
|
|
70
117
|
|
|
71
|
-
|
|
118
|
+
**3.** Ask your agent something governance-shaped:
|
|
72
119
|
|
|
73
120
|
```jsonc
|
|
74
|
-
//
|
|
121
|
+
// Discover every proposal type your DAO can run
|
|
75
122
|
dexe_proposal_catalog({ category: "all", implementedOnly: true })
|
|
76
123
|
|
|
77
|
-
//
|
|
124
|
+
// Snapshot a DAO — treasury, voters, settings, validators, everything
|
|
78
125
|
dexe_dao_info({ govPool: "0x..." })
|
|
79
126
|
|
|
80
|
-
//
|
|
127
|
+
// Draft a token-transfer proposal (returns ready-to-sign calldata)
|
|
81
128
|
dexe_proposal_build_token_transfer({
|
|
82
|
-
govPool:
|
|
83
|
-
token:
|
|
129
|
+
govPool: "0x...",
|
|
130
|
+
token: "0x...",
|
|
84
131
|
recipient: "0x...",
|
|
85
|
-
amount:
|
|
132
|
+
amount: "1000000000000000000"
|
|
86
133
|
})
|
|
87
134
|
```
|
|
88
135
|
|
|
136
|
+
The agent gets back a `TxPayload`. Pass it to your wallet. Sign. Submit. Done.
|
|
137
|
+
|
|
138
|
+
**Want the MCP to broadcast too?** Set `DEXE_PRIVATE_KEY` and unlock the composite signing flow (`dexe_proposal_create`, `dexe_proposal_vote_and_execute`, `dexe_tx_send`, `dexe_tx_status`). Strictly opt-in — default stays calldata-only.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Prerequisites
|
|
143
|
+
|
|
144
|
+
- **Node.js ≥ 20** with a working `npm` (`node --version` and `npm --version` must both succeed).
|
|
145
|
+
- **Git** — needed the first time a build tool (`dexe_compile` / `dexe_test` / `dexe_lint`) runs, to shallow-clone DeXe-Protocol. Skippable if you set `DEXE_PROTOCOL_PATH` to an existing checkout.
|
|
146
|
+
|
|
89
147
|
## First run
|
|
90
148
|
|
|
91
|
-
The MCP server starts instantly. On the first build-tool call
|
|
149
|
+
The MCP server starts instantly. On the first build-tool call, dexe-mcp shallow-clones DeXe-Protocol into a platform cache directory and runs `npm install` there once. Most tools never need that checkout — reads, proposal builders, vote tools, and deploy only need an RPC URL.
|
|
92
150
|
|
|
93
|
-
|
|
151
|
+
---
|
|
94
152
|
|
|
95
153
|
## Environment variables
|
|
96
154
|
|
|
97
|
-
All optional. Tools that need a missing variable fail with a clear message pointing at exactly what to set. Full matrix
|
|
155
|
+
All optional. Tools that need a missing variable fail with a clear, actionable message pointing at exactly what to set. Full matrix → [`docs/ENVIRONMENT.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/ENVIRONMENT.md).
|
|
98
156
|
|
|
99
157
|
| Variable | Required for | Purpose |
|
|
100
158
|
|----------|--------------|---------|
|
|
@@ -103,86 +161,92 @@ All optional. Tools that need a missing variable fail with a clear message point
|
|
|
103
161
|
| `DEXE_CHAIN_ID` | reads | Defaults to `56` (BSC mainnet). Override for other chains |
|
|
104
162
|
| `DEXE_CONTRACTS_REGISTRY` | reads (optional) | Override the ContractsRegistry root; defaults to the known per-chain address |
|
|
105
163
|
| `DEXE_PINATA_JWT` | IPFS uploads | Pinata JWT for pinning proposal/DAO metadata |
|
|
106
|
-
| `DEXE_IPFS_GATEWAY` | IPFS fetch | **Dedicated** gateway URL (Pinata
|
|
164
|
+
| `DEXE_IPFS_GATEWAY` | IPFS fetch | **Dedicated** gateway URL (Pinata, Filebase, Quicknode, self-hosted). Public gateways are unreliable and NOT defaulted |
|
|
107
165
|
| `DEXE_IPFS_GATEWAYS_FALLBACK` | IPFS fetch (optional) | Comma-separated public gateways tried sequentially after the primary |
|
|
108
|
-
| `DEXE_SUBGRAPH_POOLS_URL` | `dexe_read_dao_list`, `
|
|
166
|
+
| `DEXE_SUBGRAPH_POOLS_URL` | `dexe_read_dao_list`, `_dao_members`, `_delegation_map`, `_dao_experts`, `_user_inbox`, `_proposal_voters`, `_dao_predict_addresses` | The Graph endpoint for the DeXe pools subgraph |
|
|
109
167
|
| `DEXE_SUBGRAPH_VALIDATORS_URL` | `dexe_read_validator_list` | The Graph endpoint for the DeXe validators subgraph |
|
|
110
168
|
| `DEXE_SUBGRAPH_INTERACTIONS_URL` | `dexe_read_user_activity` | The Graph endpoint for the DeXe interactions subgraph |
|
|
111
|
-
| `DEXE_GRAPH_API_KEY` | subgraph reads (optional) | Bearer token for `gateway.thegraph.com`. Required only when
|
|
169
|
+
| `DEXE_GRAPH_API_KEY` | subgraph reads (optional) | Bearer token for `gateway.thegraph.com`. Required only when the URL doesn't embed the key. Auto-extracted from `/api/<key>/...` URLs |
|
|
112
170
|
| `DEXE_BACKEND_API_URL` | off-chain proposals | DeXe backend (e.g. `https://api.dexe.io`) |
|
|
171
|
+
| `DEXE_PRIVATE_KEY` | broadcast mode (opt-in) | Enables `_tx_send`, `_tx_status`, and the broadcast branch of composite flows. Default stays calldata-only |
|
|
172
|
+
|
|
173
|
+
---
|
|
113
174
|
|
|
114
175
|
## Documentation
|
|
115
176
|
|
|
116
177
|
Full docs in [`docs/`](https://github.com/edward-arinin-web-dev/dexe-mcp/tree/main/docs):
|
|
117
178
|
|
|
118
|
-
- [
|
|
119
|
-
- [
|
|
120
|
-
- [
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
|
133
|
-
|
|
134
|
-
|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
|
142
|
-
|
|
143
|
-
|
|
179
|
+
- [**`docs/TOOLS.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/TOOLS.md) — complete catalog of all 149 tools, grouped, with one-line descriptions and required envs.
|
|
180
|
+
- [**`docs/GOVERNOR.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/GOVERNOR.md) — external OpenZeppelin / Bravo Governor surface (Uniswap, Compound, Optimism). Family branching, fixture map, paste-able JSON examples, Tally parity harness.
|
|
181
|
+
- [**`docs/USAGE.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/USAGE.md) — 10 worked examples (deploy DAO, create/vote/execute proposals, delegate, validator chamber, decode calldata, off-chain proposals, multicall batching). Copy-pasteable JSON.
|
|
182
|
+
- [**`docs/ENVIRONMENT.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/ENVIRONMENT.md) — env-var reference: minimum block to get started, per-category requirements, calldata vs signer mode, chain config, IPFS gateway rationale, subgraph migration, swarm-harness envs, common pitfalls.
|
|
183
|
+
- [**`docs/OTC.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/OTC.md) — multi-tier OTC sale flows (project-owner and buyer paths).
|
|
184
|
+
- [**`docs/SIMULATOR.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/SIMULATOR.md) — `eth_call`-based preflight with revert-reason decoding.
|
|
185
|
+
- [**`docs/INBOX.md`**](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/INBOX.md) — cross-DAO inbox and proposal forecast.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Tool catalog
|
|
190
|
+
|
|
191
|
+
**149 tools, 18 groups.** Run `dexe_proposal_catalog` at runtime for the live proposal-type map. Full per-tool reference → [`docs/TOOLS.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/TOOLS.md).
|
|
192
|
+
|
|
193
|
+
| Group | # | What it gives you |
|
|
194
|
+
|-------|---|------|
|
|
195
|
+
| **Dev tooling** | 4 | One-command Hardhat lifecycle for the DeXe-Protocol monorepo — `dexe_compile`, `_test`, `_coverage`, `_lint`. Auto-clones the repo on first call. |
|
|
196
|
+
| **Contract introspection** | 10 | Ask the protocol about itself — list contracts, fetch ABIs, look up selectors, read NatSpec, view source, decode arbitrary calldata or full proposal payloads. The agent's reverse-engineer toolkit. |
|
|
197
|
+
| **DAO reads** | 19 | Everything you'd see on a DAO dashboard, returned as JSON — `dao_info`, predicted helper addresses, proposal state/list/voters, voting power, treasury, settings, validators, staking, distributions, privacy policy. |
|
|
198
|
+
| **IPFS** | 9 | Pinata uploads for files / avatars / DAO + proposal metadata, smart metadata updates, deterministic identicon generation, gateway-fallback fetch, CID computation without uploading. |
|
|
199
|
+
| **DAO deploy** | 1 | `dexe_dao_build_deploy` — encodes the full nested `PoolFactory.deployGovPool` struct with predicted helper addresses pre-wired. From idea to a live DAO in one signed tx. |
|
|
200
|
+
| **Proposal catalog + primitives** | 5 | `dexe_proposal_catalog` enumerates **all 33** proposal types with metadata + gating. Primitives `_build_external`, `_build_internal`, `_build_custom_abi`, `_build_offchain` cover anything not in a named wrapper. |
|
|
201
|
+
| **External proposal wrappers** | 20 | Named builders for every common action: token transfer / distribution / sale (single + multi-tier), treasury withdraw, validators, experts, staking tier, math model, blacklist, reward multiplier, apply to DAO, modify profile, change voting settings, new proposal type, whitelist, and more. |
|
|
202
|
+
| **Internal validator wrappers** | 4 | Validator-chamber proposals: `_change_validator_balances`, `_change_validator_settings`, `_monthly_withdraw`, `_offchain_internal_proposal`. |
|
|
203
|
+
| **Off-chain backend** | 8 | Full DeXe-backend integration — nonce + SIWE login, off-chain proposal creation (single-option / multi-option / for-against / settings), off-chain vote + cancel. |
|
|
204
|
+
| **Vote / stake / delegate / execute / claim** | 26 | Every direct EOA write on `GovPool` and `Validators` — deposit, vote, delegate, undelegate, execute, claim rewards, micropool rewards, staking flows, token-sale buy/claim/vesting, distribution claim, NFT multiplier lock/unlock, privacy policy signing, multicall. |
|
|
205
|
+
| **Composite signing flows** | 5 | High-level flows for power users: `_proposal_create`, `_proposal_vote_and_execute`, `_tx_send`, `_tx_status`, `_get_config`. Signing tools opt-in via `DEXE_PRIVATE_KEY`. |
|
|
206
|
+
| **Subgraph reads** | 7 | The Graph queries: DAO list, members, experts, validator list, user activity, delegation map, OTC sale tiers. Decentralized-network endpoints + RPC fallback. |
|
|
207
|
+
| **Merkle utility** | 2 | `dexe_merkle_build`, `dexe_merkle_proof` — OZ `StandardMerkleTree`-compatible. For whitelisted sales and airdrops. |
|
|
208
|
+
| **OTC composites** | 4 | Full project-owner + buyer flows over `TokenSaleProposal`: open multi-tier sale, check buyer status, buy native or with merkle proof, claim vested payouts. See [`docs/OTC.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/OTC.md). |
|
|
209
|
+
| **Safe multisig** | 2 | Queue a tx in the Safe Transaction Service for owners to co-sign instead of broadcasting — `dexe_safe_info` (on-chain nonce/threshold/owners + endpoint), `dexe_safe_propose_tx` (compute `safeTxHash`, sign as owner, POST to the queue; dry-run by default). See [`docs/SAFE.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/SAFE.md). |
|
|
210
|
+
| **Simulator** | 3 | `eth_call`-based preflight with decoded revert reasons — `_sim_calldata`, `_sim_proposal`, `_sim_buy`. Catch reverts before you pay gas. See [`docs/SIMULATOR.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/SIMULATOR.md). |
|
|
211
|
+
| **Multi-DAO inbox + forecast** | 2 | `dexe_user_inbox` aggregates pending items (unvoted proposals, claimable rewards, locked deposits) across N DAOs. `_proposal_forecast` predicts pass rate with quorum projection + risk flags. See [`docs/INBOX.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/INBOX.md). |
|
|
212
|
+
| **External Governor DAOs** | 18 | `dexe_gov_*` — read, build, simulate, and decode against OpenZeppelin Governor + Compound Bravo DAOs. Tier-1: Uniswap, Compound, Optimism. Config-only addition for new DAOs. Family-aware (OZ vs Bravo) propose / castVote / queue / execute / cancel / delegate. Eth-call dry-run + vote-impact projection. hasVoted + state + hashProposal + decode + descriptionHash utilities. Tally state-enum parity harness. See [`docs/GOVERNOR.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/docs/GOVERNOR.md). |
|
|
213
|
+
|
|
214
|
+
---
|
|
144
215
|
|
|
145
216
|
## Swarm test harness
|
|
146
217
|
|
|
147
|
-
`tests/swarm/` is a multi-agent DAO testing harness that
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
balances/settings, monthly withdraw, add/remove expert (local + global),
|
|
163
|
-
delegate/revoke from expert, reward multiplier (4 modes), change voting
|
|
164
|
-
settings, new proposal type, change math model, custom ABI, manual calldata,
|
|
165
|
-
create staking tier, off-chain validator + for/against + settings) (S16–S40)
|
|
166
|
-
- OTC multi-tier sale flows: open sale, buyer buy native + merkle (S41–S46)
|
|
167
|
-
- Simulator + inbox + per-DAO reads (S47, S48, S50, S51)
|
|
168
|
-
- **Broadcast lifecycle for the v0.5.6 builder rewrites: `withdraw_treasury`,
|
|
169
|
-
`apply_to_dao`, `reward_multiplier mint` (S52–S54)**
|
|
170
|
-
- **Broadcast lifecycle for the most-used proposal types: `token_transfer`,
|
|
171
|
-
`blacklist`, `add_expert` (S55–S57)**
|
|
218
|
+
[`tests/swarm/`](https://github.com/edward-arinin-web-dev/dexe-mcp/tree/main/tests/swarm) is a multi-agent DAO testing harness that runs every `dexe-mcp` tool against real BSC-testnet DAOs. Scenarios are JSON specs; the orchestrator resolves agent wallets and runs each step through either an inline ethers dispatcher or the dexe-mcp stdio bridge.
|
|
219
|
+
|
|
220
|
+
It's also a reference implementation of one of the futures we described above — **adversarial AI agents stress-testing a DAO before it ships.**
|
|
221
|
+
|
|
222
|
+
**57 scenarios shipped.** Coverage:
|
|
223
|
+
|
|
224
|
+
- **Reset + delegation chains** — S00, S01, S06, S14
|
|
225
|
+
- **Validator chamber** — pass / veto / full lifecycle (S02, S03, S07)
|
|
226
|
+
- **Read-only snapshots** — expert state, participation, validators, cross-DAO, catalog, multi-proposal state, user activity (S04, S05, S09–S15)
|
|
227
|
+
- **Cancel-vote + decode-and-introspect** — S08, S12
|
|
228
|
+
- **Build-only sanity for every proposal type** in `dexe_proposal_catalog` — token transfer, blacklist, withdraw treasury, apply to DAO, token distribution, token sale + recover, manage validators, change validator balances/settings, monthly withdraw, add/remove expert (local + global), delegate/revoke from expert, reward multiplier (4 modes), change voting settings, new proposal type, change math model, custom ABI, manual calldata, create staking tier, off-chain validator + for/against + settings (S16–S40)
|
|
229
|
+
- **OTC multi-tier sale flows** — open sale, buyer buy native + merkle (S41–S46)
|
|
230
|
+
- **Simulator + inbox + per-DAO reads** — S47, S48, S50, S51
|
|
231
|
+
- **Broadcast lifecycle (v0.5.6 builder rewrites)** — `withdraw_treasury`, `apply_to_dao`, `reward_multiplier mint` (S52–S54)
|
|
232
|
+
- **Broadcast lifecycle (most-used proposal types)** — `token_transfer`, `blacklist`, `add_expert` (S55–S57)
|
|
172
233
|
|
|
173
234
|
```bash
|
|
174
235
|
# 1) generate 9 wallets (8 agents + funder), fund the funder from your wallet
|
|
175
236
|
# 2) deploy fixture DAOs via dexe_dao_build_deploy (one 50% quorum + one with validators)
|
|
176
237
|
# 3) configure SWARM_DAOS_TESTNET / SWARM_TOKENS_TESTNET / SWARM_RPC_URL_TESTNET
|
|
238
|
+
|
|
177
239
|
npm run swarm:preflight # red/green table per wallet
|
|
178
240
|
npm run swarm:fund -- --confirm # broadcast top-ups from funder
|
|
179
241
|
npm run swarm:run # full sweep, all scenarios
|
|
180
242
|
npm run swarm:run -- --scenarios=S00-reset,S01-delegation-chain-3hop --dry-run
|
|
181
243
|
```
|
|
182
244
|
|
|
183
|
-
Setup runbook
|
|
184
|
-
Scenario schema
|
|
185
|
-
Per-role agent prompts
|
|
245
|
+
- Setup runbook → [`tests/swarm/README.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/tests/swarm/README.md)
|
|
246
|
+
- Scenario schema → [`tests/swarm/scenarios/_schema.md`](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/tests/swarm/scenarios/_schema.md)
|
|
247
|
+
- Per-role agent prompts → [`tests/swarm/prompts/`](https://github.com/edward-arinin-web-dev/dexe-mcp/tree/main/tests/swarm/prompts)
|
|
248
|
+
|
|
249
|
+
---
|
|
186
250
|
|
|
187
251
|
## Contributing
|
|
188
252
|
|
|
@@ -195,6 +259,31 @@ npm run typecheck
|
|
|
195
259
|
npm run dev # watch mode
|
|
196
260
|
```
|
|
197
261
|
|
|
262
|
+
Issues, PRs, and proposal-type requests welcome → [GitHub issues](https://github.com/edward-arinin-web-dev/dexe-mcp/issues).
|
|
263
|
+
|
|
264
|
+
## Security
|
|
265
|
+
|
|
266
|
+
Supply-chain hardening is enforced in CI. See [SECURITY.md](SECURITY.md) for the full policy, threat model, and how to report a vulnerability. Highlights:
|
|
267
|
+
|
|
268
|
+
- **Signed release tags.** Every release tag is GPG-signed and `release.yml` runs `git verify-tag` before publishing — an unsigned or untrusted tag aborts the release. Verify any tag yourself after cloning:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
gpg --recv-keys <MAINTAINER_KEY_ID> # import maintainer key once
|
|
272
|
+
git verify-tag v0.5.9 # or the shorthand: git tag -v v0.5.9
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
A `Good signature` line is the only acceptable result; `no signature found` or `No public key` means do not trust the tag.
|
|
276
|
+
- **npm provenance.** Releases publish with `npm publish --provenance`; verify with `npm audit signatures` against an installed copy.
|
|
277
|
+
- **Reproducible installs.** A `verify-lockfile` CI job installs strictly from the committed `package-lock.json` and fails on any drift.
|
|
278
|
+
- **Continuous scanning.** CodeQL (SAST) runs on every PR and weekly; OSSF Scorecard runs weekly and on push to `main`; Dependency Review runs on every PR.
|
|
279
|
+
|
|
198
280
|
## License
|
|
199
281
|
|
|
200
282
|
MIT. See [LICENSE](https://github.com/edward-arinin-web-dev/dexe-mcp/blob/main/LICENSE).
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
<p align="center">
|
|
287
|
+
<b>The runtime for autonomous DAOs.</b><br/>
|
|
288
|
+
<sub>Built for the DeXe Protocol governance stack on BNB Chain. Not affiliated with DeXe Network — independent open-source integration.</sub>
|
|
289
|
+
</p>
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Only the latest published version on npm receives security updates. Pin to the latest minor (`^0.5`) in your MCP client config.
|
|
6
|
+
|
|
7
|
+
## Automated security checks
|
|
8
|
+
|
|
9
|
+
The repo runs four GitHub Actions security workflows continuously:
|
|
10
|
+
|
|
11
|
+
- **CI** (`ci.yml`) — typecheck and build on every push to `main` and every pull request, against Node 20 and 22, plus a `verify-lockfile` integrity job. The test step (`vitest`) runs whenever test files are present on the branch; it is currently a no-op via `--passWithNoTests` (the suite lives on `governor-adapter`) and becomes an enforcing gate once those tests merge. Read-only `GITHUB_TOKEN` scope.
|
|
12
|
+
- **Dependency Review** (`dependency-review.yml`) — every PR is checked against the GitHub Advisory Database. Fails the PR check if any added/updated dependency carries a `high` or `critical` CVE, or if it introduces a forbidden license (GPL/AGPL).
|
|
13
|
+
- **OSSF Scorecard** (`scorecard.yml`) — weekly + on push to `main`. Audits branch protection, signed releases, pinned dependencies, token permissions, and a dozen other supply-chain checks. Results uploaded to GitHub code-scanning (SARIF) and published as a public score at `https://api.securityscorecards.dev/projects/github.com/edward-arinin-web-dev/dexe-mcp/badge`.
|
|
14
|
+
- **CodeQL** (`codeql.yml`) — GitHub-native SAST with the `security-extended` query suite. Runs on every PR/main push and weekly. Scans for prototype pollution, command injection, ReDoS, unsafe deserialization, path traversal, and other CWE patterns. Findings land in the repo's Security tab.
|
|
15
|
+
|
|
16
|
+
## Release provenance
|
|
17
|
+
|
|
18
|
+
Every npm release from `v0.5.9` onwards is published via `.github/workflows/release.yml` with `npm publish --provenance`. The signed attestation links the tarball to the exact git commit and GitHub Actions run that produced it. Verify in three ways:
|
|
19
|
+
|
|
20
|
+
- The npmjs.com page for the package shows a "Provenance" badge with the source repo and workflow run.
|
|
21
|
+
- `npm view dexe-mcp dist.signatures` returns Sigstore signatures.
|
|
22
|
+
- `npm audit signatures` against an installed copy fails if the registry tarball was tampered with.
|
|
23
|
+
|
|
24
|
+
If you ever install a `dexe-mcp` version that lacks a provenance attestation (and is not a pre-`v0.5.9` historical release), treat it as suspect and report.
|
|
25
|
+
|
|
26
|
+
## Signed release tags
|
|
27
|
+
|
|
28
|
+
Every release tag is GPG-signed by the maintainer, and `release.yml` runs `git verify-tag "$GITHUB_REF_NAME"` **before** the publish step — an unsigned tag, an invalid signature, or a tag signed by an unknown key aborts the release, so a pushed tag can never publish to npm without a valid maintainer signature.
|
|
29
|
+
|
|
30
|
+
To verify a tag yourself after cloning the repo:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Import the maintainer's public key once (key id published alongside releases).
|
|
34
|
+
gpg --recv-keys <MAINTAINER_KEY_ID>
|
|
35
|
+
|
|
36
|
+
# Verify a specific tag — exits non-zero if unsigned or signed by an unknown key.
|
|
37
|
+
git verify-tag v0.5.9
|
|
38
|
+
# Equivalent shorthand:
|
|
39
|
+
git tag -v v0.5.9
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A clean `gpg: Good signature from "<maintainer>"` line is the only acceptable result. `error: ... no signature found` (unsigned) or `Can't check signature: No public key` (unknown signer) means do not trust the tag.
|
|
43
|
+
|
|
44
|
+
## Reporting a Vulnerability
|
|
45
|
+
|
|
46
|
+
If you find a vulnerability in `dexe-mcp` — whether in the calldata builders, the optional signer (`DEXE_PRIVATE_KEY`), IPFS upload paths, or the Hardhat bridge — please **do not** open a public GitHub issue.
|
|
47
|
+
|
|
48
|
+
Email: **edward.arinin@gmail.com**
|
|
49
|
+
|
|
50
|
+
Include:
|
|
51
|
+
|
|
52
|
+
- A description of the issue and its impact (what an attacker can do, under what conditions).
|
|
53
|
+
- A minimal reproduction: the tool call, env vars (redacted), and the resulting behavior.
|
|
54
|
+
- Affected version (`dexe-mcp --version` or check `package.json`).
|
|
55
|
+
- Suggested mitigation, if you have one.
|
|
56
|
+
|
|
57
|
+
You should expect an acknowledgement within 72 hours. A coordinated-disclosure timeline will be agreed before any public advisory is filed.
|
|
58
|
+
|
|
59
|
+
## Scope
|
|
60
|
+
|
|
61
|
+
In scope:
|
|
62
|
+
|
|
63
|
+
- Calldata-builder tools (`dexe_proposal_build_*`, `dexe_vote_build_*`, `dexe_dao_build_deploy`) that produce calldata that does not match the intended action.
|
|
64
|
+
- Signer mode (`dexe_tx_send`, auto-broadcast in `dexe_proposal_create` / `dexe_proposal_vote_and_execute`) leaking or misusing the configured private key.
|
|
65
|
+
- IPFS upload paths that exfiltrate non-public data or accept unsafe input.
|
|
66
|
+
- Hardhat bridge (`dexe_compile`, `dexe_test`, etc.) executing unintended shell commands.
|
|
67
|
+
- Dependency vulnerabilities reachable through `dexe-mcp`'s exposed tool surface.
|
|
68
|
+
|
|
69
|
+
Out of scope:
|
|
70
|
+
|
|
71
|
+
- Vulnerabilities in the on-chain DeXe Protocol contracts (report at <https://github.com/dexe-network>).
|
|
72
|
+
- Issues that require the operator to set obviously unsafe env values (e.g. `DEXE_PRIVATE_KEY=<a key the attacker already controls>`).
|
|
73
|
+
- General npm-registry / npm-cli / Node.js issues unrelated to this package.
|
|
74
|
+
|
|
75
|
+
## Threat Model
|
|
76
|
+
|
|
77
|
+
`dexe-mcp` runs **locally** alongside an MCP client (Claude Desktop, Claude Code, etc.). It does not bind a network port and does not expose itself to the public internet. The interesting attack surfaces are:
|
|
78
|
+
|
|
79
|
+
1. The operator's private key in signer mode — never logged, never sent off-host, only used by `ethers.Wallet` to sign payloads the operator has already approved at the agent level.
|
|
80
|
+
2. Calldata correctness — every `_build_*` tool emits a `TxPayload` the operator can decode (`dexe_decode_calldata`, `dexe_decode_proposal`) and sign-verify before broadcasting.
|
|
81
|
+
3. IPFS pinning credentials — keep `PINATA_JWT` scoped to a project-specific key.
|
|
82
|
+
|
|
83
|
+
If you believe any of the above is broken, please report per the process above.
|
|
84
|
+
|
|
85
|
+
## Signer broadcast guards
|
|
86
|
+
|
|
87
|
+
When signer mode is enabled (`DEXE_PRIVATE_KEY`), `dexe_tx_send` runs four opt-in guards before broadcasting (`src/lib/broadcastGuards.ts`). They narrow the blast radius of a compromised or runaway MCP host — the host can still *call* the tool, but cannot send to arbitrary destinations, drain arbitrary value, pay gas for reverting txs, or loop unbounded. Each is a no-op unless its env var is set; a failed guard returns `{ status: "rejected", guard, reason }` with **no gas spent**.
|
|
88
|
+
|
|
89
|
+
| Guard | Env var | What it blocks |
|
|
90
|
+
|-------|---------|----------------|
|
|
91
|
+
| **B6** destination allowlist | `DEXE_SIGNER_ALLOWLIST` | Broadcasts to any `to` not on the comma-separated list. |
|
|
92
|
+
| **B7** value cap | `DEXE_SIGNER_MAX_VALUE_WEI` | Broadcasts whose `value` (wei) exceeds the cap. |
|
|
93
|
+
| **B9** auto-simulation | _(always on in signer mode)_ | Doomed txs — `eth_call` preflight aborts with the decoded revert reason before gas is spent. |
|
|
94
|
+
| **B10** rate limit | `DEXE_SIGNER_MAX_BROADCASTS_PER_MIN` | More than N broadcasts in a rolling 60s window. |
|
|
95
|
+
|
|
96
|
+
These are defense-in-depth, **not** a substitute for keeping the key off-host. For prod governance/treasury actions, prefer calldata mode + Safe Multisig / Ledger. See `docs/ENVIRONMENT.md` §4 for the recommended config block.
|
package/dist/config.d.ts
CHANGED
|
@@ -34,6 +34,15 @@ export interface DexeConfig {
|
|
|
34
34
|
forkBlock?: number;
|
|
35
35
|
/** Private key for tx signing. When set, `dexe_tx_send` can broadcast. */
|
|
36
36
|
privateKey?: string;
|
|
37
|
+
/**
|
|
38
|
+
* B6 — destination allowlist for `dexe_tx_send`. Lowercased, checksummed-then-
|
|
39
|
+
* lowercased addresses. Undefined/empty = no restriction.
|
|
40
|
+
*/
|
|
41
|
+
signerAllowlist?: string[];
|
|
42
|
+
/** B7 — max wei value per broadcast. Undefined = no cap. */
|
|
43
|
+
signerMaxValueWei?: bigint;
|
|
44
|
+
/** B10 — max broadcasts per rolling minute. Undefined = no limit. */
|
|
45
|
+
signerMaxBroadcastsPerMin?: number;
|
|
37
46
|
}
|
|
38
47
|
/**
|
|
39
48
|
* Reads environment and returns a frozen config. **Fast and side-effect-free**
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IAErB,uEAAuE;IACvE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IAErB,uEAAuE;IACvE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACzC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAwMtD;AAcD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAW9E"}
|
package/dist/config.js
CHANGED
|
@@ -34,6 +34,20 @@ export async function loadConfig() {
|
|
|
34
34
|
if (rpcMainnet) {
|
|
35
35
|
chains.set(56, { chainId: 56, rpcUrl: rpcMainnet });
|
|
36
36
|
}
|
|
37
|
+
// Generic per-chain RPC: DEXE_RPC_URL_<chainId> (e.g. DEXE_RPC_URL_1,
|
|
38
|
+
// DEXE_RPC_URL_10). Enables chains beyond BSC — notably the external
|
|
39
|
+
// Governor DAOs, which live on Ethereum (1) and Optimism (10). The numeric
|
|
40
|
+
// suffix never collides with the named *_TESTNET / *_MAINNET vars above.
|
|
41
|
+
for (const [key, val] of Object.entries(process.env)) {
|
|
42
|
+
const m = /^DEXE_RPC_URL_(\d+)$/.exec(key);
|
|
43
|
+
if (!m)
|
|
44
|
+
continue;
|
|
45
|
+
const url = val?.trim();
|
|
46
|
+
if (!url)
|
|
47
|
+
continue;
|
|
48
|
+
const cid = Number(m[1]);
|
|
49
|
+
chains.set(cid, { chainId: cid, rpcUrl: url });
|
|
50
|
+
}
|
|
37
51
|
// Legacy single-chain env (still supported)
|
|
38
52
|
const legacyRpc = process.env.DEXE_RPC_URL?.trim() || undefined;
|
|
39
53
|
let legacyChainId;
|
|
@@ -106,6 +120,49 @@ export async function loadConfig() {
|
|
|
106
120
|
const addr = new Wallet(privateKey).address;
|
|
107
121
|
process.stderr.write(`[dexe-mcp] signing enabled for ${addr}\n`);
|
|
108
122
|
}
|
|
123
|
+
// ---- signer broadcast guard B6 (destination allowlist) -----------------
|
|
124
|
+
// Opt-in; only meaningful in signer mode. Parses to undefined when unset,
|
|
125
|
+
// leaving the default posture unchanged.
|
|
126
|
+
let signerAllowlist;
|
|
127
|
+
const allowlistRaw = process.env.DEXE_SIGNER_ALLOWLIST?.trim();
|
|
128
|
+
if (allowlistRaw) {
|
|
129
|
+
const { isAddress, getAddress } = await import("ethers");
|
|
130
|
+
const normalized = [];
|
|
131
|
+
for (const entry of allowlistRaw.split(",").map(s => s.trim()).filter(Boolean)) {
|
|
132
|
+
if (!isAddress(entry)) {
|
|
133
|
+
fatal(`DEXE_SIGNER_ALLOWLIST contains an invalid address: ${entry}`);
|
|
134
|
+
}
|
|
135
|
+
normalized.push(getAddress(entry).toLowerCase());
|
|
136
|
+
}
|
|
137
|
+
if (normalized.length > 0)
|
|
138
|
+
signerAllowlist = normalized;
|
|
139
|
+
}
|
|
140
|
+
// ---- signer broadcast guard B7 (value cap) -----------------------------
|
|
141
|
+
let signerMaxValueWei;
|
|
142
|
+
const maxValueRaw = process.env.DEXE_SIGNER_MAX_VALUE_WEI?.trim();
|
|
143
|
+
if (maxValueRaw) {
|
|
144
|
+
let parsed;
|
|
145
|
+
try {
|
|
146
|
+
parsed = BigInt(maxValueRaw);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
fatal(`DEXE_SIGNER_MAX_VALUE_WEI must be a non-negative integer (wei), got: ${maxValueRaw}`);
|
|
150
|
+
}
|
|
151
|
+
if (parsed < 0n) {
|
|
152
|
+
fatal(`DEXE_SIGNER_MAX_VALUE_WEI must be a non-negative integer (wei), got: ${maxValueRaw}`);
|
|
153
|
+
}
|
|
154
|
+
signerMaxValueWei = parsed;
|
|
155
|
+
}
|
|
156
|
+
// ---- signer broadcast guard B10 (rate limit) ---------------------------
|
|
157
|
+
let signerMaxBroadcastsPerMin;
|
|
158
|
+
const maxBroadcastsRaw = process.env.DEXE_SIGNER_MAX_BROADCASTS_PER_MIN?.trim();
|
|
159
|
+
if (maxBroadcastsRaw) {
|
|
160
|
+
const n = Number(maxBroadcastsRaw);
|
|
161
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
162
|
+
fatal(`DEXE_SIGNER_MAX_BROADCASTS_PER_MIN must be a positive integer, got: ${maxBroadcastsRaw}`);
|
|
163
|
+
}
|
|
164
|
+
signerMaxBroadcastsPerMin = n;
|
|
165
|
+
}
|
|
109
166
|
let forkBlock;
|
|
110
167
|
if (process.env.DEXE_FORK_BLOCK) {
|
|
111
168
|
const n = Number(process.env.DEXE_FORK_BLOCK);
|
|
@@ -128,6 +185,9 @@ export async function loadConfig() {
|
|
|
128
185
|
subgraphInteractionsUrl,
|
|
129
186
|
forkBlock,
|
|
130
187
|
privateKey,
|
|
188
|
+
signerAllowlist,
|
|
189
|
+
signerMaxValueWei,
|
|
190
|
+
signerMaxBroadcastsPerMin,
|
|
131
191
|
});
|
|
132
192
|
}
|
|
133
193
|
/**
|