dexe-mcp 0.2.0 → 0.4.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 (80) hide show
  1. package/CHANGELOG.md +192 -85
  2. package/README.md +103 -80
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +10 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/index.js +16 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/addresses.js +1 -1
  10. package/dist/lib/ipfs.d.ts.map +1 -1
  11. package/dist/lib/ipfs.js +2 -1
  12. package/dist/lib/ipfs.js.map +1 -1
  13. package/dist/lib/markdownToSlate.d.ts +39 -0
  14. package/dist/lib/markdownToSlate.d.ts.map +1 -0
  15. package/dist/lib/markdownToSlate.js +203 -0
  16. package/dist/lib/markdownToSlate.js.map +1 -0
  17. package/dist/lib/merkleTree.d.ts +38 -0
  18. package/dist/lib/merkleTree.d.ts.map +1 -0
  19. package/dist/lib/merkleTree.js +83 -0
  20. package/dist/lib/merkleTree.js.map +1 -0
  21. package/dist/lib/signer.d.ts +12 -0
  22. package/dist/lib/signer.d.ts.map +1 -0
  23. package/dist/lib/signer.js +31 -0
  24. package/dist/lib/signer.js.map +1 -0
  25. package/dist/lib/subgraph.d.ts +2 -2
  26. package/dist/lib/subgraph.d.ts.map +1 -1
  27. package/dist/lib/subgraph.js +14 -9
  28. package/dist/lib/subgraph.js.map +1 -1
  29. package/dist/tools/daoDeploy.d.ts.map +1 -1
  30. package/dist/tools/daoDeploy.js +313 -63
  31. package/dist/tools/daoDeploy.js.map +1 -1
  32. package/dist/tools/flow.d.ts +62 -0
  33. package/dist/tools/flow.d.ts.map +1 -0
  34. package/dist/tools/flow.js +479 -0
  35. package/dist/tools/flow.js.map +1 -0
  36. package/dist/tools/index.d.ts.map +1 -1
  37. package/dist/tools/index.js +12 -0
  38. package/dist/tools/index.js.map +1 -1
  39. package/dist/tools/ipfs.d.ts.map +1 -1
  40. package/dist/tools/ipfs.js +94 -28
  41. package/dist/tools/ipfs.js.map +1 -1
  42. package/dist/tools/merkle.d.ts +4 -0
  43. package/dist/tools/merkle.d.ts.map +1 -0
  44. package/dist/tools/merkle.js +174 -0
  45. package/dist/tools/merkle.js.map +1 -0
  46. package/dist/tools/otc.d.ts +5 -0
  47. package/dist/tools/otc.d.ts.map +1 -0
  48. package/dist/tools/otc.js +481 -0
  49. package/dist/tools/otc.js.map +1 -0
  50. package/dist/tools/proposal.js +28 -10
  51. package/dist/tools/proposal.js.map +1 -1
  52. package/dist/tools/proposalBuild.d.ts.map +1 -1
  53. package/dist/tools/proposalBuild.js +28 -13
  54. package/dist/tools/proposalBuild.js.map +1 -1
  55. package/dist/tools/proposalBuildComplex.d.ts +222 -0
  56. package/dist/tools/proposalBuildComplex.d.ts.map +1 -1
  57. package/dist/tools/proposalBuildComplex.js +511 -138
  58. package/dist/tools/proposalBuildComplex.js.map +1 -1
  59. package/dist/tools/proposalBuildInternal.js +24 -11
  60. package/dist/tools/proposalBuildInternal.js.map +1 -1
  61. package/dist/tools/proposalBuildMore.js +42 -21
  62. package/dist/tools/proposalBuildMore.js.map +1 -1
  63. package/dist/tools/proposalBuildOffchain.d.ts.map +1 -1
  64. package/dist/tools/proposalBuildOffchain.js +8 -5
  65. package/dist/tools/proposalBuildOffchain.js.map +1 -1
  66. package/dist/tools/read.d.ts.map +1 -1
  67. package/dist/tools/read.js +227 -0
  68. package/dist/tools/read.js.map +1 -1
  69. package/dist/tools/subgraph.d.ts +4 -0
  70. package/dist/tools/subgraph.d.ts.map +1 -0
  71. package/dist/tools/subgraph.js +404 -0
  72. package/dist/tools/subgraph.js.map +1 -0
  73. package/dist/tools/txSend.d.ts +5 -0
  74. package/dist/tools/txSend.d.ts.map +1 -0
  75. package/dist/tools/txSend.js +87 -0
  76. package/dist/tools/txSend.js.map +1 -0
  77. package/dist/tools/voteBuild.d.ts.map +1 -1
  78. package/dist/tools/voteBuild.js +420 -0
  79. package/dist/tools/voteBuild.js.map +1 -1
  80. package/package.json +83 -75
package/CHANGELOG.md CHANGED
@@ -1,85 +1,192 @@
1
- # Changelog
2
-
3
- ## 0.2.0
4
-
5
- The big one — dexe-mcp expands from 15 dev-tooling tools to **83 tools** covering the full DeXe DAO lifecycle. AI agents can now create DAOs, build any of the 33 proposal types the DeXe frontend exposes, upload metadata to IPFS, stake/delegate/vote/execute/claim — all end-to-end.
6
-
7
- ### Added
8
-
9
- **Foundations + reads (13 tools)** — `dexe_dao_info`, `dexe_dao_predict_addresses`, `dexe_dao_registry_lookup`, `dexe_proposal_state`, `dexe_proposal_list`, `dexe_proposal_voters`, `dexe_vote_user_power`, `dexe_vote_get_votes`, `dexe_read_multicall`, `dexe_read_treasury`, `dexe_read_validators`, `dexe_read_settings`, `dexe_read_expert_status`. Backed by an `AddressBook` that resolves contracts via `ContractsRegistry`, a Multicall3 batch helper, a canonical `TxPayload` shape, enum mirrors for `ProposalState` / `VoteType`, and a minimal subgraph GraphQL client.
10
-
11
- **IPFS (6 tools)** — `dexe_ipfs_upload_proposal_metadata`, `_upload_dao_metadata`, `_upload_file`, `_fetch`, `_cid_info`, `_cid_for_json`. Backed by a Pinata client and local CID computation via `multiformats`. Public gateways (dweb.link, ipfs.io, cf-ipfs, 4everland) are unreliable and NOT defaulted. Users must set `DEXE_IPFS_GATEWAY` to a dedicated gateway (the one Pinata provides alongside the JWT is recommended). Public gateways are opt-in via `DEXE_IPFS_GATEWAYS_FALLBACK` (comma-separated, tried sequentially — no parallel races).
12
-
13
- **Proposalsall 33 types (35 tools)**
14
- - `dexe_proposal_catalog` — enumerate every proposal type the DeXe UI exposes (24 external, 4 internal, 5 off-chain), with metadata shape, gating, and linked MCP builder.
15
- - Primitives: `dexe_proposal_build_external` (+ `createProposalAndVote`), `dexe_proposal_build_internal`, `dexe_proposal_build_custom_abi`, `dexe_proposal_build_offchain`.
16
- - External wrappers (each returns `{ metadata, actions: Action[] }`): `token_transfer`, `token_distribution`, `token_sale`, `token_sale_recover`, `change_voting_settings`, `manage_validators`, `add_expert`, `remove_expert`, `withdraw_treasury`, `delegate_to_expert`, `revoke_from_expert`, `create_staking_tier`, `change_math_model`, `modify_dao_profile`, `blacklist`, `reward_multiplier`, `apply_to_dao`, `new_proposal_type` (also covers *Enable Staking*).
17
- - Internal validator wrappers (each returns `{ metadata, proposalType, data }`): `change_validator_balances` (type 0), `change_validator_settings` (type 1), `monthly_withdraw` (type 2), `offchain_internal_proposal` (type 3).
18
- - Off-chain backend proposals: `offchain_single_option`, `offchain_multi_option`, `offchain_for_against`, `offchain_settings`. Plus `dexe_auth_request_nonce` + `dexe_auth_login_request` for the 2-step Bearer flow, and `dexe_offchain_build_vote` / `dexe_offchain_build_cancel_vote`.
19
- - **Write model is calldata-only.** No signer, no private keys. Every write tool emits a signable payload the agent's wallet submits.
20
-
21
- **Vote / stake / execute / claim writes (14 tools)** `erc20_approve`, `deposit` (payable for native-staking DAOs), `withdraw`, `delegate`, `undelegate`, `vote`, `cancel_vote`, `validator_vote`, `validator_cancel_vote`, `move_to_validators`, `execute`, `claim_rewards`, `claim_micropool_rewards`, plus `multicall` to batch any of the above into one atomic tx. Arg-order gotchas captured in code comments (e.g. `GovPool.vote(pid, isFor, amount, nftIds)` vs `GovValidators.voteInternalProposal(pid, amount, isFor)`).
22
-
23
- **DAO deploy (1 tool)** `dexe_dao_build_deploy` encodes `PoolFactory.deployGovPool(GovPoolDeployParams)` with the full nested struct (settings / validators / userKeeper / token / votePower / verifier / BABT flag / descriptionURL / name). Auto-resolves PoolFactory via `ContractsRegistry` if omitted. When `deployer` + RPC are available, also returns the predicted GovPool address so agents can wire follow-up txs before the DAO exists. Encodes against the compiled `PoolFactory.json` artifact when present (strict parity); falls back to a hand-rolled tuple signature derived from `IPoolFactory.sol` otherwise.
24
-
25
- ### Changed
26
-
27
- - `src/config.ts` adds `DEXE_CHAIN_ID` (default 56), `DEXE_CONTRACTS_REGISTRY` override, `DEXE_PINATA_JWT`, three subgraph URL overrides, `DEXE_BACKEND_API_URL`.
28
- - `package.json` description rewritten to reflect full DAO-ops scope. New dep: `multiformats` (Protocol Labs, for local CID computation).
29
- - `README.md` reorganized around the eight tool groups; added the full env-var matrix.
30
-
31
- ### Notes
32
-
33
- - **No breaking changes.** All v0.1.x tools remain. The write contract is new-world: `TxPayload` for single-tx builders, `Action[]` for proposal wrappers — never a singular `action` field.
34
- - **Deferred to future work** (`FUTURE.md`): Hardhat-fork simulation (`dexe_simulate_vote`), signer-aware send mode, additional IPFS pinning providers (Storacha, Lighthouse), and alternate subgraphs.
35
-
36
- ## 0.1.5
37
-
38
- ### Fixed
39
- - **`'npx' is not recognized`** from inside `npm run compile` (and other npm scripts that internally call `npx hardhat …`) on stripped-Node Windows installs. v0.1.4 got `npm` itself spawning cleanly, but DeXe-Protocol's `compile` script is literally `npx hardhat compile --force`, and when npm spawned that child, `cmd.exe` couldn't find `npx.cmd` on PATH — the stripped `C:\Program Files\nodejs\` has `node.exe` only. Root cause: we weren't propagating the resolved Node's shim directory into the child's `PATH`.
40
- - New `deriveNodeBinDir()` + `envWithNodeBinDir()` helpers in `src/runtime.ts` derive the directory containing `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx` (Unix) from the resolved `npm-cli.js` path, and prepend it to `PATH` on every child spawn (`bootstrap` npm install, `runNpmScript`, `runHardhat`). Child shells launched by npm scripts can now resolve `npx` / `npm` / any locally-installed binary as expected.
41
- - `npmCommand()` now returns a `binDir` field alongside `command` / `prefixArgs` / `needsShell`. Bootstrap logs the prepended directory on first run so it's visible which Node install is contributing the shims.
42
-
43
- ## 0.1.4
44
-
45
- ### Fixed
46
- - **`spawn EINVAL` during first-run `npm install`** on Windows hosts where `process.execPath` points at a Node install that does not bundle npm (e.g. a bare `node.exe` dropped under `C:\Program Files\nodejs\` without the rest of the toolchain). Two root causes addressed:
47
- 1. `resolveNpmCli()` now searches a broader set of locations for a usable `npm-cli.js` including `%APPDATA%\nvm\v*\node_modules\npm\bin\npm-cli.js` (nvm-windows), `%APPDATA%\npm\node_modules\npm\bin\npm-cli.js` (per-user npm prefix), `C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js` (stock Windows installer), `~/.nvm/versions/node/v*/lib/node_modules/npm/bin/npm-cli.js` (nvm Unix), and Homebrew paths. Because `npm-cli.js` is plain JavaScript, *any* modern `node` can execute any of these, so the MCP process's own Node is free to "borrow" npm from a completely different Node install.
48
- 2. When no `npm-cli.js` is found anywhere and we fall back to spawning `npm.cmd` directly, `execFile` / `execa` now pass `{ shell: true }` — without it, Node refuses to spawn `.cmd` / `.bat` files (CVE-2024-27980 mitigation) and throws `spawn EINVAL`.
49
- - Progress logging on first bootstrap now prints the resolved `npm-cli.js` path (or "shell-resolved" fallback), so "which npm is about to run" is visible in stderr.
50
-
51
- ## 0.1.3
52
-
53
- ### Docs
54
- - **Windows install section rewritten** to lead with the absolute-path recipe (`node <abs path to dist/index.js>`) instead of `cmd /c dexe-mcp`. End-to-end testing against Claude Code on Windows showed the `cmd /c` wrapper, while standalone functional, did not reliably complete the MCP handshake when spawned by Claude Code — the absolute-path recipe has zero shim resolution and is known-working.
55
- - **New prereq step**: verify `npm --version` actually runs in your shell *before* attempting `npm install -g dexe-mcp`. Users with a stripped `node.exe`-only install (common on Windows) will hit a silent `npm i -g` no-op otherwise, with no visible error.
56
- - Added a "Verify the install" section showing how to smoke-test `dexe-mcp` over stdio without involving Claude Code, so users can distinguish "MCP server broken" from "client registration broken".
57
-
58
- No code changes — 0.1.3 is a docs-only patch on top of 0.1.2's behavior.
59
-
60
- ## 0.1.2
61
-
62
- ### Fixed
63
- - **Server no longer hangs / fails on first launch.** The heavy `git clone` + `npm install` bootstrap is now lazy — it runs only when a build tool (`dexe_compile`, `dexe_test`, `dexe_coverage`, `dexe_lint`) is first invoked, not inside MCP `initialize()`. Previously the MCP handshake would block for minutes or time out, and crash outright on hosts where `npm` / `git` were not on the spawned process's PATH.
64
- - **PATH-independent spawning of `npm` and `hardhat`.** The runner now invokes `node <npm-cli.js>` and `node <protocol>/node_modules/hardhat/internal/cli/cli.js` directly via `process.execPath`, so it works on Windows installs where `npm.cmd` / `npx.cmd` aren't on the MCP client's spawn PATH (common with nvm-windows and with stripped `node.exe`-only installs).
65
- - **Actionable error messages** when `git` is not installed, when `DEXE_PROTOCOL_PATH` points at a non-Hardhat directory, or when the user-managed checkout is missing `node_modules`.
66
- - Concurrent build-tool calls now coalesce into a single bootstrap instead of racing `git clone` / `npm install`.
67
-
68
- ### Changed
69
- - `loadConfig()` no longer hard-fails when the DeXe-Protocol checkout is missing or incomplete at startup it logs a soft warning to stderr and defers preparation to the first build-tool invocation.
70
- - `src/bootstrap.ts` split into `resolveProtocolPath()` (cheap, startup-safe) and `ensureBuildReady()` (lazy, idempotent).
71
- - New `src/runtime.ts` with portable `npmCommand()` / `hardhatCommand()` / `hasGit()` helpers.
72
-
73
- ### Docs
74
- - README now has an OS-specific install matrix (Mac/Linux vs. Windows) and a "dev / local checkout" recipe. Troubleshooting section updated for the new lazy-bootstrap behavior and the `process.execPath` npm resolution.
75
-
76
- ## 0.1.1
77
-
78
- ### Added
79
- - `dexe_get_methods` introspection tool — returns per-contract methods partitioned into `read` (view/pure) and `write` (nonpayable/payable). Each entry includes `name`, canonical `signature`, 4-byte `selector`, `stateMutability`, and structured `inputs`/`outputs` with `internalType` preserved (so tuple-typed args like `IGovPool.ProposalView[]` survive intact). Designed for generating TypeScript interfaces or ethers wrappers without re-parsing raw ABIs. Supports `kind` filter (`read`/`write`/`all`) and optional `includeEvents`/`includeErrors`.
80
-
81
- Tool count: 14 → 15.
82
-
83
- ## 0.1.0
84
-
85
- Initial public release (Phase A): build/test, contract introspection, read-only governance tools. 14 tools.
1
+ # Changelog
2
+
3
+ ## 0.4.0
4
+
5
+ OTC DAO support. Adds the calldata builders, merkle utilities, and four
6
+ composite tools needed to launch and operate an over-the-counter token sale
7
+ end-to-end through one MCP surface. **119 tools** total. Lifecycle proven
8
+ on BSC testnet (deploy → open_sale → vote → execute → buy → claim →
9
+ balance delta verified).
10
+
11
+ ### Added
12
+
13
+ **Phase A calldata builders (4 tools)**
14
+ - `dexe_proposal_build_token_sale_multi` — N-tier sale envelope. Sums and dedupes ERC20 approves per sale token, auto-derives merkle roots for `MerkleWhitelist` tiers when only `users[]` is supplied, auto-appends `addToWhitelist` for plain `Whitelist` tiers.
15
+ - `dexe_proposal_build_token_sale_whitelist` standalone external proposal that calls `addToWhitelist([{tierId, users[], uri}, …])` on a live tier.
16
+ - `dexe_proposal_build_token_sale` kept as back-compat shim forwarding `[tier]` to `_multi`. Gains optional `participation` field.
17
+ - `dexe_merkle_build` / `dexe_merkle_proof` OZ `StandardMerkleTree`-compatible: sorted-pair commutative keccak, double-hash leaf `keccak256(keccak256(abi.encode(...)))`. Default leaf shape `["address"]`; advanced shapes via `entries` + `leafEncoding`.
18
+
19
+ **Phase B composite tools (4 tools)**
20
+ - `dexe_otc_dao_open_sale` — orchestrates `_multi` + `runProposalCreate` (balance/threshold check, approve, deposit, IPFS metadata, `createProposalAndVote`). `buildOnly: true` short-circuits the proposal flow and just returns the envelope. `dryRun: true` returns ordered TxPayloads even when `DEXE_PRIVATE_KEY` is set.
21
+ - `dexe_otc_buyer_status` read-only aggregator. Multicalls `getTierViews` + `getUserViews(user, tierIds, proofs)`, surfaces participation requirements + pre-computed `claimable` (`canClaim && !isClaimed ? claimTotalAmount : 0`) and `vestingWithdrawable` (`amountToWithdraw`). Optional per-tier `whitelists[]` triggers merkle-tree build + proof + verify check for the user.
22
+ - `dexe_otc_buyer_buy` — preflights ERC20 balance + allowance (skipped on native sentinel `ZeroAddress`), prepends `approve(spender=TokenSaleProposal, MAX_UINT256)` when needed, builds `buy(tierId, paymentToken, amount, proof)`. Auto-derives the merkle proof when `whitelistUsers[]` is supplied without a precomputed `proof`. Native path sets `value=amount`.
23
+ - `dexe_otc_buyer_claim_all`picks tiers with `canClaim && !isClaimed` `claim`, tiers with `amountToWithdraw > 0` `vestingWithdraw`. Skips silently when nothing pending (`mode='noop'`).
24
+
25
+ **Refactors**
26
+ - `proposalBuildComplex.ts` — extracted `buildTokenSaleMultiActions(input)` pure helper; `tierSchema`, `TierSpec`, `buildTierTuple`, `buildSaleApprovals`, `TOKEN_SALE_PROPOSAL_ABI` now exported. The `dexe_proposal_build_token_sale_multi` registrar is a thin shim around the helper.
27
+ - `flow.ts` extracted `runProposalCreate(input, deps)` + `sendOrCollect` exported. `dexe_proposal_create` gains a `dryRun` flag. `sendOrCollect` distinguishes `mode='dryRun'` (caller-requested) from `mode='payloads'` (no signer); the swarm orchestrator's `mcpFallbackDispatcher` only auto-broadcasts on `'payloads'`.
28
+
29
+ **Docs + scripts**
30
+ - `docs/OTC.md` — project-owner + buyer flows with paste-ready examples. Documents every gotcha that bit during integration: PRECISION 1e25 (not 1e18) on `exchangeRates`; `canClaim` requires `block.timestamp >= saleEndTime + claimLockDuration` so buyers must wait for the sale window to close even with `claimLockDuration: 0`; `maxAllocationPerUser == 0` means unlimited (not zero); newly-passed proposals briefly land in `Locked` (idx 6) before `SucceededFor` (idx 4); treasury must be seeded with sale token (mint via `tokenParams.users[]` + predicted `govPool` address).
31
+ - `scripts/lifecycle-otc.mjs` — runnable end-to-end proof on BSC testnet (chain 97). Single command. Deploys a fresh DAO, opens a 1-tier sale, votes+executes, buys, claims, verifies balance delta.
32
+
33
+ **Swarm scenarios**
34
+ - `S41-otc-multi-merkle-build` 2 tiers Open + MerkleWhitelist, auto-derived root.
35
+ - `S42-otc-multi-whitelist-build` — 2 tiers Open + plain Whitelist, auto-appended `addToWhitelist`.
36
+ - `S43-otc-whitelist-extend-build` — standalone `_whitelist` proposal extending an existing tier.
37
+ - `S44-otc-open-sale-build` — `buildOnly` envelope sanity.
38
+ - `S45-otc-buyer-buy-native-build` — `dryRun` + native sentinel.
39
+ - `S46-otc-buyer-buy-merkle-build` `dryRun` + auto-merkle proof.
40
+
41
+ ### Fixed
42
+
43
+ - **Bug #25** — `TOKEN_SALE_PROPOSAL_ABI` had two field-order transpositions vs the contract: `TierInitParams` swapped `saleTokenAddress` <-> `claimLockDuration`, and `VestingSettings` was declared `(cliff, step, duration, percentage)` instead of canonical `(percentage, duration, cliff, step)`. Selector matched (`0x6a6effda`) but calldata was silently misdecoded — every prior single-tier sale proposal built via dexe-mcp landed with vesting + claim-lock fields scrambled.
44
+ - **Bug #26** — `getUserViews` ABI in `read.ts` (and copied into `otc.ts`) declared `UserView` as a flat 7-field struct (`canParticipate, isWhitelisted, purchasedAmount, owedAmount, lockedAmount, claimableAmount, vestingWithdrawAmount`). Actual contract returns `tuple(bool canParticipate, PurchaseView purchaseView, VestingUserView vestingUserView)` with nested structs. Both files now match the contract; affected callers (`dexe_read_token_sale_user`, `dexe_otc_buyer_status`, `dexe_otc_buyer_claim_all`) updated to read fields via the correct paths.
45
+ - **Bug #27** — `getUserViews` is a 3-arg function (`address user, uint256[] tierIds, bytes32[][] proofs`); ABI was missing the third parameter, causing every call to revert with `require(false)` at the abicoder layer. Fixed in both `read.ts` and `otc.ts`; non-merkle tiers pass `tierIds.map(() => [])`.
46
+ - **`flow.ts` `vote_and_execute` Locked state.** When `open_sale`'s `createProposalAndVote` clears quorum + earlyCompletion, the proposal lands directly in state 6 (`Locked`) before transitioning to `SucceededFor`. The skip-vote-and-execute branch only matched 4/5; now also matches 6.
47
+ - **`otc.ts` multicall double-unwrap.** Single-return-value functions are already unwrapped by `src/lib/multicall.ts`; the OTC composites were treating the result as one extra layer deep and indexing `[0]`. Fixed.
48
+
49
+ ### Lifecycle proof
50
+
51
+ Live run on BSC testnet (chain 97) on 2026-05-01:
52
+ - govPool: `0x028C447c72A6Fd1955f0937bb3C5926E8EAC297c`
53
+ - deploy tx: `0x3e17ff4e46a6840bf4945e15a9c3af620be276b7de0e1efe807e08ec8a097dbe`
54
+ - execute proposal 1: `0x17b677e3fb0b078ca670d3a16c3a776cc36dac97e4497446b19d6490633873df`
55
+ - buyer balance: `400000.0` `399999.0` (buy) `400000.0` (claim) delta verified
56
+
57
+ ---
58
+
59
+ ## 0.3.0
60
+
61
+ End-to-end testnet validation. Every proposal-builder tool is now exercised by an automated swarm scenario on BSC testnet, and the harness itself ships in-repo so external integrators can run it. **111 tools** total, **41 swarm scenarios**, full sweep green.
62
+
63
+ ### Added
64
+
65
+ **Swarm test harness (`tests/swarm/` + `scripts/swarm/`)**
66
+ - `scripts/swarm/orchestrator.ts` — scenario loader + dispatcher. Inline ethers dispatchers for the no-IPFS toolset (vote_user_power, read_delegation_map, build_undelegate, build_withdraw, build_withdraw_all, build_erc20_approve, build_deposit, build_delegate, build_vote). Generic MCP-stdio fallback (`mcpFallbackDispatcher`) routes anything else through the dexe-mcp child server, so adding a scenario for a new tool is JSON-only — no code changes.
67
+ - Loop expansion (`spec.loop.over` × `appliesToSteps`), template engine (`{{dao}}`, `{{firstAllowlistedToken}}`, `{{firstAllowlistedDao}}`, `{{secondAllowlistedDao}}`, `{{dao.<helper>}}`, `{{agent:X:address}}`, `{{capture.path}}`, `{{capture.0.field}}`), `skipIf` evaluator with limited expressions, deferred-cascade for chained captures, wallet semaphore for parallel-safe broadcasts, per-scenario `prefund` hook that tops up agents from `AGENT_FUNDER_PK` before each scenario runs.
68
+ - `scripts/swarm/preflight.ts` + `scripts/swarm/fund-pool.ts` — wallet-readiness check + token allowlist–enforced top-up. Hard-refuses to send to any non-pool address or any token not on the allowlist.
69
+ - `scripts/swarm/nightly.sh` Phase 5 cron runner. Pulls main, runs preflight + full sweep, tails the run report, posts the one-line summary to `SWARM_SUMMARY_WEBHOOK` and/or `SWARM_SUMMARY_ISSUE` (gh CLI), runs a triage stub on failure (with `SWARM_FIXER=1` opt-in for auto-fix), and rotates run-report dirs older than 30 days while keeping the latest 50.
70
+ - `scripts/swarm/orchestrator.ts` emits a single greppable summary line after `writeReport`: `SWARM <runId> <pass>/<total> <mode> <chainTag> <reportPath>` — consumed by nightly.sh and any external poster.
71
+ - `scripts/swarm/one-shot-execute.mjs` closes a proposal lifecycle once it reaches `SucceededFor`. Polls + caps `wait()` at 90 s to avoid sandbox hangs.
72
+ - 41 scenario JSONs covering: reset, delegation chain, validator pass / veto / full lifecycle, expert / participation / staking / validator / catalog / cross-DAO / multi-proposal-state read snapshots, cancel-vote, decode-and-introspect, build-only sanity for every external + internal proposal type from `dexe_proposal_catalog`.
73
+ - Role prompts: `proposer`, `voter`, `delegator`, `reporter`, `triage`, `validator`, `expert`, `fixer`, plus `_shared.md` and the dao-personas fixture. Fixer prompt encodes the CLAUDE.md auto-fix loop verbatim — branch `swarm-fix/<YYYY-MM-DD>`, never push to main, diff scope hard-bounded to `src/tools/`, `src/lib/`, `tests/swarm/`.
74
+
75
+ **Composite + signing tools**
76
+ - `dexe_proposal_create` — full prerequisite handling: balance check, ERC20 approve, deposit, IPFS metadata upload, `createProposalAndVote`. When `DEXE_PRIVATE_KEY` is set the tool signs and broadcasts; otherwise returns the ordered `TxPayload` list. Supports `proposalType: 'modify_dao_profile' | 'custom'`.
77
+ - `dexe_proposal_vote_and_execute` — vote-then-execute composite with `autoExecute` + `depositFirst` flags.
78
+ - `dexe_tx_send` + `dexe_tx_status` — opt-in signer surface that uses the configured `DEXE_PRIVATE_KEY` when present. Calls remain calldata-by-default; users opt in by setting the env var.
79
+ - `dexe_dao_build_deploy` predicted-address auto-wiring: `govToken` flowed into `userKeeperParams.tokenAddress` and `distributionProposal` + `govTokenSale` into `additionalProposalExecutors` automatically. LINEAR / POLYNOMIAL `votePower` initData auto-encoded.
80
+
81
+ **Reads + introspection**
82
+ - `dexe_read_dao_list`, `_dao_members`, `_dao_experts`, `_user_activity`, `_distribution_status`, `_token_sale_tiers`, `_token_sale_user`, `_staking_info`, `_validator_list`, `_privacy_policy_status`, `_delegation_map` — fill out the DAO read surface.
83
+ - `dexe_get_methods` returns structured per-function metadata (4-byte selectors, mutability, full structured inputs/outputs with `internalType` preserved for tuples).
84
+ - `dexe_proposal_voters` switched to the `pools` subgraph and the proposalInteractions composite ID format (poolAddr + uint32LE(proposalId), no separator).
85
+ - `dexe_decode_proposal` understands every external + internal proposal action shape.
86
+
87
+ ### Fixed
88
+
89
+ - **Proposal metadata format**: builders now emit `proposalName` / `proposalDescription` (not `name` / `description`), wrap diffs inside `changes: { proposedChanges, currentChanges }`, set `isMeta: false`, and round-trip identical to the frontend reference. 17 builders touched.
90
+ - **Approve target for deposits** is `UserKeeper`, not `GovPool`. Both flow tools (`proposal_create`, `vote_and_execute`) now approve the right address.
91
+ - **Personal voting power** = `tokenBalance.balance − ownedBalance` (deposited only). Without this, `withdraw` on freshly-funded agents reverts `GovUK: can't withdraw this`.
92
+ - **VotePower initData** uses `__LinearPower_init()` selector `0x892aea1f` (not empty `0x`) so newly-deployed DAOs initialize their LINEAR vote-power proxy correctly.
93
+ - **`STATE_NAMES` enum order** corrected (Defeated / Locked positions were swapped).
94
+ - **Custom-proposal IPFS metadata** now includes `category`, `isMeta`, `proposedChanges`, `currentChanges`.
95
+ - **Subgraph migration**: Studio URLs deprecated; switched to The Graph decentralized network with API key. Per-chain endpoints documented.
96
+ - **IPFS gateway path normalization**: dedicated gateways configured with a trailing `/ipfs` (e.g. `https://<sub>.mypinata.cloud/ipfs`) no longer produce `/ipfs/ipfs/<cid>` 404s.
97
+
98
+ ### Changed
99
+
100
+ - README updated: tool count `83 → 111`, new "Swarm test harness" section.
101
+ - `process.loadEnvFile()` is invoked from `index.ts` so the MCP server loads `.env` itself; users no longer have to plumb env-var changes through their MCP client config (which often doesn't reload).
102
+ - Repo now ships `.claude/skills/swarm-test/SKILL.md` for users running Claude Code; lets them invoke the swarm with `/swarm-test`.
103
+
104
+ ### Notes
105
+
106
+ - **Validated network**: BSC testnet (chain 97). Two fixture DAOs deployed for the harness — Glacier (50% quorum, no validators) and Sentinel (5% quorum, 2 validators with 1k SVT each).
107
+ - **Mainnet status**: a separate run pass is staged (Stage B per `tests/swarm/README.md`) but blocked on a previously-observed `PoolFactory.deployGovPool` revert. Re-validate when the protocol team confirms a fix.
108
+ - **Off-chain backend tools** require `DEXE_BACKEND_API_URL` and only run on chains where DeXe operates a backend. The corresponding swarm scenarios declare `requiresChain: [56]` so they auto-skip on testnet.
109
+
110
+ ## 0.2.0
111
+
112
+ The big one — dexe-mcp expands from 15 dev-tooling tools to **83 tools** covering the full DeXe DAO lifecycle. AI agents can now create DAOs, build any of the 33 proposal types the DeXe frontend exposes, upload metadata to IPFS, stake/delegate/vote/execute/claim — all end-to-end.
113
+
114
+ ### Added
115
+
116
+ **Foundations + reads (13 tools)** — `dexe_dao_info`, `dexe_dao_predict_addresses`, `dexe_dao_registry_lookup`, `dexe_proposal_state`, `dexe_proposal_list`, `dexe_proposal_voters`, `dexe_vote_user_power`, `dexe_vote_get_votes`, `dexe_read_multicall`, `dexe_read_treasury`, `dexe_read_validators`, `dexe_read_settings`, `dexe_read_expert_status`. Backed by an `AddressBook` that resolves contracts via `ContractsRegistry`, a Multicall3 batch helper, a canonical `TxPayload` shape, enum mirrors for `ProposalState` / `VoteType`, and a minimal subgraph GraphQL client.
117
+
118
+ **IPFS (6 tools)** — `dexe_ipfs_upload_proposal_metadata`, `_upload_dao_metadata`, `_upload_file`, `_fetch`, `_cid_info`, `_cid_for_json`. Backed by a Pinata client and local CID computation via `multiformats`. Public gateways (dweb.link, ipfs.io, cf-ipfs, 4everland) are unreliable and NOT defaulted. Users must set `DEXE_IPFS_GATEWAY` to a dedicated gateway (the one Pinata provides alongside the JWT is recommended). Public gateways are opt-in via `DEXE_IPFS_GATEWAYS_FALLBACK` (comma-separated, tried sequentially — no parallel races).
119
+
120
+ **Proposals — all 33 types (35 tools)**
121
+ - `dexe_proposal_catalog` — enumerate every proposal type the DeXe UI exposes (24 external, 4 internal, 5 off-chain), with metadata shape, gating, and linked MCP builder.
122
+ - Primitives: `dexe_proposal_build_external` (+ `createProposalAndVote`), `dexe_proposal_build_internal`, `dexe_proposal_build_custom_abi`, `dexe_proposal_build_offchain`.
123
+ - External wrappers (each returns `{ metadata, actions: Action[] }`): `token_transfer`, `token_distribution`, `token_sale`, `token_sale_recover`, `change_voting_settings`, `manage_validators`, `add_expert`, `remove_expert`, `withdraw_treasury`, `delegate_to_expert`, `revoke_from_expert`, `create_staking_tier`, `change_math_model`, `modify_dao_profile`, `blacklist`, `reward_multiplier`, `apply_to_dao`, `new_proposal_type` (also covers *Enable Staking*).
124
+ - Internal validator wrappers (each returns `{ metadata, proposalType, data }`): `change_validator_balances` (type 0), `change_validator_settings` (type 1), `monthly_withdraw` (type 2), `offchain_internal_proposal` (type 3).
125
+ - Off-chain backend proposals: `offchain_single_option`, `offchain_multi_option`, `offchain_for_against`, `offchain_settings`. Plus `dexe_auth_request_nonce` + `dexe_auth_login_request` for the 2-step Bearer flow, and `dexe_offchain_build_vote` / `dexe_offchain_build_cancel_vote`.
126
+ - **Write model is calldata-only.** No signer, no private keys. Every write tool emits a signable payload the agent's wallet submits.
127
+
128
+ **Vote / stake / execute / claim writes (14 tools)** — `erc20_approve`, `deposit` (payable for native-staking DAOs), `withdraw`, `delegate`, `undelegate`, `vote`, `cancel_vote`, `validator_vote`, `validator_cancel_vote`, `move_to_validators`, `execute`, `claim_rewards`, `claim_micropool_rewards`, plus `multicall` to batch any of the above into one atomic tx. Arg-order gotchas captured in code comments (e.g. `GovPool.vote(pid, isFor, amount, nftIds)` vs `GovValidators.voteInternalProposal(pid, amount, isFor)`).
129
+
130
+ **DAO deploy (1 tool)** — `dexe_dao_build_deploy` encodes `PoolFactory.deployGovPool(GovPoolDeployParams)` with the full nested struct (settings / validators / userKeeper / token / votePower / verifier / BABT flag / descriptionURL / name). Auto-resolves PoolFactory via `ContractsRegistry` if omitted. When `deployer` + RPC are available, also returns the predicted GovPool address so agents can wire follow-up txs before the DAO exists. Encodes against the compiled `PoolFactory.json` artifact when present (strict parity); falls back to a hand-rolled tuple signature derived from `IPoolFactory.sol` otherwise.
131
+
132
+ ### Changed
133
+
134
+ - `src/config.ts` adds `DEXE_CHAIN_ID` (default 56), `DEXE_CONTRACTS_REGISTRY` override, `DEXE_PINATA_JWT`, three subgraph URL overrides, `DEXE_BACKEND_API_URL`.
135
+ - `package.json` description rewritten to reflect full DAO-ops scope. New dep: `multiformats` (Protocol Labs, for local CID computation).
136
+ - `README.md` reorganized around the eight tool groups; added the full env-var matrix.
137
+
138
+ ### Notes
139
+
140
+ - **No breaking changes.** All v0.1.x tools remain. The write contract is new-world: `TxPayload` for single-tx builders, `Action[]` for proposal wrappers — never a singular `action` field.
141
+ - **Deferred to future work** (`FUTURE.md`): Hardhat-fork simulation (`dexe_simulate_vote`), signer-aware send mode, additional IPFS pinning providers (Storacha, Lighthouse), and alternate subgraphs.
142
+
143
+ ## 0.1.5
144
+
145
+ ### Fixed
146
+ - **`'npx' is not recognized`** from inside `npm run compile` (and other npm scripts that internally call `npx hardhat …`) on stripped-Node Windows installs. v0.1.4 got `npm` itself spawning cleanly, but DeXe-Protocol's `compile` script is literally `npx hardhat compile --force`, and when npm spawned that child, `cmd.exe` couldn't find `npx.cmd` on PATH — the stripped `C:\Program Files\nodejs\` has `node.exe` only. Root cause: we weren't propagating the resolved Node's shim directory into the child's `PATH`.
147
+ - New `deriveNodeBinDir()` + `envWithNodeBinDir()` helpers in `src/runtime.ts` derive the directory containing `npm.cmd`/`npx.cmd` (Windows) or `bin/npm`/`bin/npx` (Unix) from the resolved `npm-cli.js` path, and prepend it to `PATH` on every child spawn (`bootstrap` npm install, `runNpmScript`, `runHardhat`). Child shells launched by npm scripts can now resolve `npx` / `npm` / any locally-installed binary as expected.
148
+ - `npmCommand()` now returns a `binDir` field alongside `command` / `prefixArgs` / `needsShell`. Bootstrap logs the prepended directory on first run so it's visible which Node install is contributing the shims.
149
+
150
+ ## 0.1.4
151
+
152
+ ### Fixed
153
+ - **`spawn EINVAL` during first-run `npm install`** on Windows hosts where `process.execPath` points at a Node install that does not bundle npm (e.g. a bare `node.exe` dropped under `C:\Program Files\nodejs\` without the rest of the toolchain). Two root causes addressed:
154
+ 1. `resolveNpmCli()` now searches a broader set of locations for a usable `npm-cli.js` — including `%APPDATA%\nvm\v*\node_modules\npm\bin\npm-cli.js` (nvm-windows), `%APPDATA%\npm\node_modules\npm\bin\npm-cli.js` (per-user npm prefix), `C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js` (stock Windows installer), `~/.nvm/versions/node/v*/lib/node_modules/npm/bin/npm-cli.js` (nvm Unix), and Homebrew paths. Because `npm-cli.js` is plain JavaScript, *any* modern `node` can execute any of these, so the MCP process's own Node is free to "borrow" npm from a completely different Node install.
155
+ 2. When no `npm-cli.js` is found anywhere and we fall back to spawning `npm.cmd` directly, `execFile` / `execa` now pass `{ shell: true }` — without it, Node refuses to spawn `.cmd` / `.bat` files (CVE-2024-27980 mitigation) and throws `spawn EINVAL`.
156
+ - Progress logging on first bootstrap now prints the resolved `npm-cli.js` path (or "shell-resolved" fallback), so "which npm is about to run" is visible in stderr.
157
+
158
+ ## 0.1.3
159
+
160
+ ### Docs
161
+ - **Windows install section rewritten** to lead with the absolute-path recipe (`node <abs path to dist/index.js>`) instead of `cmd /c dexe-mcp`. End-to-end testing against Claude Code on Windows showed the `cmd /c` wrapper, while standalone functional, did not reliably complete the MCP handshake when spawned by Claude Code — the absolute-path recipe has zero shim resolution and is known-working.
162
+ - **New prereq step**: verify `npm --version` actually runs in your shell *before* attempting `npm install -g dexe-mcp`. Users with a stripped `node.exe`-only install (common on Windows) will hit a silent `npm i -g` no-op otherwise, with no visible error.
163
+ - Added a "Verify the install" section showing how to smoke-test `dexe-mcp` over stdio without involving Claude Code, so users can distinguish "MCP server broken" from "client registration broken".
164
+
165
+ No code changes — 0.1.3 is a docs-only patch on top of 0.1.2's behavior.
166
+
167
+ ## 0.1.2
168
+
169
+ ### Fixed
170
+ - **Server no longer hangs / fails on first launch.** The heavy `git clone` + `npm install` bootstrap is now lazy — it runs only when a build tool (`dexe_compile`, `dexe_test`, `dexe_coverage`, `dexe_lint`) is first invoked, not inside MCP `initialize()`. Previously the MCP handshake would block for minutes or time out, and crash outright on hosts where `npm` / `git` were not on the spawned process's PATH.
171
+ - **PATH-independent spawning of `npm` and `hardhat`.** The runner now invokes `node <npm-cli.js>` and `node <protocol>/node_modules/hardhat/internal/cli/cli.js` directly via `process.execPath`, so it works on Windows installs where `npm.cmd` / `npx.cmd` aren't on the MCP client's spawn PATH (common with nvm-windows and with stripped `node.exe`-only installs).
172
+ - **Actionable error messages** when `git` is not installed, when `DEXE_PROTOCOL_PATH` points at a non-Hardhat directory, or when the user-managed checkout is missing `node_modules`.
173
+ - Concurrent build-tool calls now coalesce into a single bootstrap instead of racing `git clone` / `npm install`.
174
+
175
+ ### Changed
176
+ - `loadConfig()` no longer hard-fails when the DeXe-Protocol checkout is missing or incomplete at startup — it logs a soft warning to stderr and defers preparation to the first build-tool invocation.
177
+ - `src/bootstrap.ts` split into `resolveProtocolPath()` (cheap, startup-safe) and `ensureBuildReady()` (lazy, idempotent).
178
+ - New `src/runtime.ts` with portable `npmCommand()` / `hardhatCommand()` / `hasGit()` helpers.
179
+
180
+ ### Docs
181
+ - README now has an OS-specific install matrix (Mac/Linux vs. Windows) and a "dev / local checkout" recipe. Troubleshooting section updated for the new lazy-bootstrap behavior and the `process.execPath` npm resolution.
182
+
183
+ ## 0.1.1
184
+
185
+ ### Added
186
+ - `dexe_get_methods` introspection tool — returns per-contract methods partitioned into `read` (view/pure) and `write` (nonpayable/payable). Each entry includes `name`, canonical `signature`, 4-byte `selector`, `stateMutability`, and structured `inputs`/`outputs` with `internalType` preserved (so tuple-typed args like `IGovPool.ProposalView[]` survive intact). Designed for generating TypeScript interfaces or ethers wrappers without re-parsing raw ABIs. Supports `kind` filter (`read`/`write`/`all`) and optional `includeEvents`/`includeErrors`.
187
+
188
+ Tool count: 14 → 15.
189
+
190
+ ## 0.1.0
191
+
192
+ Initial public release (Phase A): build/test, contract introspection, read-only governance tools. 14 tools.
package/README.md CHANGED
@@ -4,9 +4,11 @@
4
4
 
5
5
  MCP server that gives AI agents **full DeXe Protocol DAO operations coverage** — deploy DAOs, build any of the 33 proposal types the DeXe UI exposes, upload metadata to IPFS, stake/delegate/vote/execute/claim. Plus dev tooling: build/test/lint, contract introspection, ABI-aware calldata decoding.
6
6
 
7
- **Writes return calldata.** No signer ever lives in the MCP — every write tool emits a ready-to-sign `{ to, data, value, chainId, description }` payload that the agent's wallet (MetaMask, Safe, hardware, etc.) signs and submits. No `PRIVATE_KEY` env var, ever.
7
+ **Two write modes, calldata-default.** Every write tool returns a ready-to-sign `TxPayload = { to, data, value, chainId, description }` that the agent's wallet (MetaMask, Safe, hardware, etc.) signs and submits — no key in the MCP. Power users who *want* the server to sign and broadcast can opt in by setting `DEXE_PRIVATE_KEY`; that unlocks `dexe_tx_send`, `dexe_tx_status`, and the auto-broadcast branch of `dexe_proposal_create` / `dexe_proposal_vote_and_execute`. Default stays calldata-only.
8
8
 
9
- **83 tools** across 8 groups. Call `dexe_proposal_catalog` at runtime for the full proposal-type map, or browse the [catalog](#tool-catalog) below.
9
+ **111 tools** across 9 groups. Call `dexe_proposal_catalog` at runtime for the full proposal-type map, or browse the [catalog](#tool-catalog) below.
10
+
11
+ > **End-to-end coverage.** Every proposal-builder tool ships with a swarm-test scenario that exercises it on BSC testnet. Latest pass: **41/41 scenarios green**, ~200 broadcasts validated against two fixture DAOs (Glacier 50%-quorum + Sentinel 5%-quorum-with-validators). See [Swarm test harness](#swarm-test-harness) below.
10
12
 
11
13
  ## Prerequisites
12
14
 
@@ -46,6 +48,44 @@ If your client can't spawn the bare `dexe-mcp` command directly (a known issue w
46
48
 
47
49
  Run `npm root -g` to resolve the path on your machine. Restart the MCP client and the `dexe_*` tools will appear.
48
50
 
51
+ ## Quickstart
52
+
53
+ Minimum config to get **read-only** access to a BSC mainnet DAO:
54
+
55
+ ```json
56
+ {
57
+ "mcpServers": {
58
+ "dexe": {
59
+ "command": "dexe-mcp",
60
+ "env": {
61
+ "DEXE_RPC_URL": "https://bsc-dataseed.binance.org",
62
+ "DEXE_CHAIN_ID": "56"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ Add `DEXE_PINATA_JWT` for IPFS uploads, `DEXE_BACKEND_API_URL` for off-chain proposals, and per-chain subgraph URLs for `dexe_proposal_voters` and the DAO-list reads. Full matrix → [`docs/ENVIRONMENT.md`](./docs/ENVIRONMENT.md).
70
+
71
+ Three first-call examples (full set in [`docs/USAGE.md`](./docs/USAGE.md)):
72
+
73
+ ```jsonc
74
+ // 1) discover available proposal types
75
+ dexe_proposal_catalog({ category: "all", implementedOnly: true })
76
+
77
+ // 2) read a DAO
78
+ dexe_dao_info({ govPool: "0x..." })
79
+
80
+ // 3) build a token-transfer proposal (calldata only)
81
+ dexe_proposal_build_token_transfer({
82
+ govPool: "0x...",
83
+ token: "0x...",
84
+ recipient: "0x...",
85
+ amount: "1000000000000000000"
86
+ })
87
+ ```
88
+
49
89
  ## First run
50
90
 
51
91
  The MCP server starts instantly. On the first build-tool call (`dexe_compile` / `dexe_test` / `dexe_lint`), dexe-mcp will automatically shallow-clone DeXe-Protocol into a platform cache directory and run `npm install` there once. If you prefer to reuse an existing checkout, set `DEXE_PROTOCOL_PATH` in the MCP `env` block and nothing will be cloned.
@@ -54,7 +94,7 @@ Most tools don't need the protocol checkout at all — read/proposal/vote/deploy
54
94
 
55
95
  ## Environment variables
56
96
 
57
- All optional. Tools that need a missing variable fail with a clear message pointing at exactly what to set.
97
+ All optional. Tools that need a missing variable fail with a clear message pointing at exactly what to set. Full matrix + per-tool requirements → [`docs/ENVIRONMENT.md`](./docs/ENVIRONMENT.md).
58
98
 
59
99
  | Variable | Required for | Purpose |
60
100
  |----------|--------------|---------|
@@ -69,85 +109,68 @@ All optional. Tools that need a missing variable fail with a clear message point
69
109
  | `DEXE_SUBGRAPH_POOLS_URL`, `DEXE_SUBGRAPH_VALIDATORS_URL` | reserved | Additional subgraph endpoints for future tools |
70
110
  | `DEXE_BACKEND_API_URL` | off-chain proposals | DeXe backend (e.g. `https://api.dexe.io`) |
71
111
 
72
- ## Tool catalog
73
-
74
- ### Dev tooling (compile / test / introspect / decode)
75
-
76
- | Tool | Description |
77
- |------|-------------|
78
- | `dexe_compile`, `dexe_test`, `dexe_coverage`, `dexe_lint` | Hardhat wrappers |
79
- | `dexe_list_contracts`, `dexe_get_abi`, `dexe_get_methods`, `dexe_get_selectors`, `dexe_find_selector`, `dexe_get_natspec`, `dexe_get_source` | Contract introspection from compiled artifacts |
80
- | `dexe_decode_calldata`, `dexe_decode_proposal`, `dexe_list_gov_contract_types` | ABI-aware calldata / proposal decoding |
112
+ ## Documentation
113
+
114
+ Full docs in [`docs/`](./docs):
115
+
116
+ - [`docs/TOOLS.md`](./docs/TOOLS.md) complete catalog of all 111 tools, organized by category, with one-line descriptions and required envs per tool.
117
+ - [`docs/USAGE.md`](./docs/USAGE.md) — 10 worked examples (deploy DAO, create proposals, vote, delegate, validator chamber, decode calldata, off-chain proposals, multicall batching). Copy-pasteable JSON.
118
+ - [`docs/ENVIRONMENT.md`](./docs/ENVIRONMENT.md) full env-var reference: minimum block to get started, per-category requirements, calldata vs signer mode, chain-specific config, IPFS gateway rationale, subgraph migration, swarm harness envs, common pitfalls.
119
+
120
+ ## Tool surface (high-level)
121
+
122
+ | Group | Tools | What |
123
+ |-------|-------|------|
124
+ | Dev tooling | 4 | Hardhat wrappers: `dexe_compile`, `_test`, `_coverage`, `_lint` |
125
+ | Contract introspection | 10 | `_list_contracts`, `_get_abi`, `_get_methods`, `_get_selectors`, `_find_selector`, `_get_natspec`, `_get_source`, `_decode_calldata`, `_decode_proposal`, `_list_gov_contract_types` |
126
+ | DAO reads | 25 | `_dao_info`, `_dao_predict_addresses`, `_dao_registry_lookup`, `_proposal_state/_list/_voters`, `_vote_user_power/_get_votes`, `_read_*` family |
127
+ | IPFS | 6 | Pinata uploads, gateway fetch, CID computation |
128
+ | DAO deploy | 1 | `dexe_dao_build_deploy` (encodes `PoolFactory.deployGovPool` with full nested struct + predicted addr wiring) |
129
+ | Proposal catalog + primitives | 5 | `dexe_proposal_catalog` enumerates **all 33** types; primitives: `_build_external`, `_build_internal`, `_build_custom_abi`, `_build_offchain` |
130
+ | External proposal wrappers | 18 | Token transfer / distribution / sale, treasury withdraw, validators, experts, staking tier, math model, blacklist, reward multiplier, apply to DAO, modify profile, change voting settings, new proposal type, etc. |
131
+ | Internal validator wrappers | 4 | `_change_validator_balances`, `_change_validator_settings`, `_monthly_withdraw`, `_offchain_internal_proposal` |
132
+ | Off-chain backend | 8 | `_offchain_single_option/_multi_option/_for_against/_settings`, auth flow (`_auth_request_nonce`, `_auth_login_request`), `_offchain_build_vote/_cancel_vote` |
133
+ | Vote / stake / delegate / execute / claim | 16 | `_vote_build_*` family — every direct EOA write on GovPool / Validators |
134
+ | Composite signing flows | 4 | `_proposal_create`, `_proposal_vote_and_execute`, `_tx_send`, `_tx_status` (all opt-in via `DEXE_PRIVATE_KEY`) |
135
+ | Subgraph reads | 6 | DAO list, members, experts, user activity, delegation map, distribution status (decentralized network endpoints) |
136
+
137
+ Total: **~111**. Per-tool descriptions, args, return shapes → [`docs/TOOLS.md`](./docs/TOOLS.md).
138
+
139
+ ## Swarm test harness
140
+
141
+ `tests/swarm/` is a multi-agent DAO testing harness that exercises every dexe-mcp
142
+ tool against real BSC-testnet DAOs. Scenarios are JSON specs; the orchestrator
143
+ loads them, resolves agent wallets, and runs each step through either an inline
144
+ ethers dispatcher or the dexe-mcp stdio bridge.
145
+
146
+ **41 scenarios shipped** covering:
147
+
148
+ - Reset + delegation chains (S00, S01, S06, S14)
149
+ - Validator chamber pass / veto / full lifecycle (S02, S03, S07)
150
+ - Read-only snapshots: expert state, participation, validators, cross-DAO,
151
+ catalog, multi-proposal state, user activity (S04, S05, S09, S10, S11, S13, S15)
152
+ - Cancel-vote, decode-and-introspect (S08, S12)
153
+ - Build-only sanity for every proposal type in `dexe_proposal_catalog`
154
+ (token transfer, blacklist, withdraw treasury, apply to dao, token
155
+ distribution, token sale + recover, manage validators, change validator
156
+ balances/settings, monthly withdraw, add/remove expert (local + global),
157
+ delegate/revoke from expert, reward multiplier (4 modes), change voting
158
+ settings, new proposal type, change math model, custom ABI, manual calldata,
159
+ create staking tier, off-chain validator + for/against + settings) (S16–S40)
81
160
 
82
- ### DAO reads (on-chain state via multicall + subgraph)
83
-
84
- | Tool | Description |
85
- |------|-------------|
86
- | `dexe_dao_info` | DAO overview helpers, NFT contracts, validator count |
87
- | `dexe_dao_predict_addresses` | Predict CREATE2 addresses for a future DAO |
88
- | `dexe_dao_registry_lookup` | Is this address a registered GovPool? |
89
- | `dexe_proposal_state`, `dexe_proposal_list`, `dexe_proposal_voters` | Proposal reads (voters via subgraph) |
90
- | `dexe_vote_user_power`, `dexe_vote_get_votes` | User staking + per-proposal vote info |
91
- | `dexe_read_multicall` | Generic Multicall3 batched `eth_call` |
92
- | `dexe_read_treasury`, `dexe_read_validators`, `dexe_read_settings`, `dexe_read_expert_status` | Canned live reads |
93
- | `dexe_read_gov_state` | Aggregate gov-pool state (legacy helper) |
94
-
95
- ### IPFS
96
-
97
- | Tool | Description |
98
- |------|-------------|
99
- | `dexe_ipfs_upload_proposal_metadata`, `dexe_ipfs_upload_dao_metadata`, `dexe_ipfs_upload_file` | Pinata uploads (requires `DEXE_PINATA_JWT`) |
100
- | `dexe_ipfs_fetch` | Fetch by CID via configured dedicated gateway |
101
- | `dexe_ipfs_cid_info` | Parse CID + v0↔v1 conversion + gateway URLs |
102
- | `dexe_ipfs_cid_for_json` | Compute CIDv1 locally (no network) for dry-run flows |
103
-
104
- ### DAO deploy
105
-
106
- | Tool | Description |
107
- |------|-------------|
108
- | `dexe_dao_build_deploy` | Encode `PoolFactory.deployGovPool(GovPoolDeployParams)` with full nested-struct input (settings / validators / userKeeper / token / votePower / verifier / BABT flag / descriptionURL / name). Auto-resolves PoolFactory via registry; optionally returns the predicted GovPool address |
109
-
110
- ### Proposals — primitives + catalog
111
-
112
- | Tool | Description |
113
- |------|-------------|
114
- | `dexe_proposal_catalog` | Enumerate **all 33** proposal types with schemas, gating, metadata shape, and the MCP tool that handles each |
115
- | `dexe_proposal_build_external` | Raw `GovPool.createProposal(url, actionsFor, actionsAgainst)` (+ `createProposalAndVote` variant) |
116
- | `dexe_proposal_build_internal` | Raw `GovValidators.createInternalProposal(type, url, data)` |
117
- | `dexe_proposal_build_custom_abi` | Encode any ABI call → one `ProposalAction` |
118
- | `dexe_proposal_build_offchain` | Generic DeXe backend HTTP request builder |
119
-
120
- ### Proposal wrappers — external (on-chain)
121
-
122
- Each returns `{ metadata, actions[] }` — upload the metadata via `dexe_ipfs_upload_proposal_metadata`, then feed actions into `dexe_proposal_build_external`:
123
-
124
- `dexe_proposal_build_token_transfer`, `_token_distribution`, `_token_sale`, `_token_sale_recover`, `_change_voting_settings`, `_manage_validators`, `_add_expert`, `_remove_expert`, `_withdraw_treasury`, `_delegate_to_expert`, `_revoke_from_expert`, `_create_staking_tier`, `_change_math_model`, `_modify_dao_profile`, `_blacklist`, `_reward_multiplier`, `_apply_to_dao`, `_new_proposal_type` (also covers *Enable Staking*).
125
-
126
- ### Proposal wrappers — internal validator
127
-
128
- Return `{ metadata, proposalType, data }` — compose with `dexe_proposal_build_internal`:
129
-
130
- `dexe_proposal_build_change_validator_balances` (type 0), `_change_validator_settings` (type 1), `_monthly_withdraw` (type 2), `_offchain_internal_proposal` (type 3).
131
-
132
- ### Proposal wrappers — off-chain (DeXe backend)
133
-
134
- `dexe_proposal_build_offchain_single_option`, `_offchain_multi_option`, `_offchain_for_against`, `_offchain_settings`.
135
-
136
- Plus auth + vote helpers: `dexe_auth_request_nonce`, `dexe_auth_login_request`, `dexe_offchain_build_vote`, `dexe_offchain_build_cancel_vote`.
137
-
138
- ### Vote / stake / execute / claim (direct EOA writes)
161
+ ```bash
162
+ # 1) generate 9 wallets (8 agents + funder), fund the funder from your wallet
163
+ # 2) deploy fixture DAOs via dexe_dao_build_deploy (one 50% quorum + one with validators)
164
+ # 3) configure SWARM_DAOS_TESTNET / SWARM_TOKENS_TESTNET / SWARM_RPC_URL_TESTNET
165
+ npm run swarm:preflight # red/green table per wallet
166
+ npm run swarm:fund -- --confirm # broadcast top-ups from funder
167
+ npm run swarm:run # full sweep, all scenarios
168
+ npm run swarm:run -- --scenarios=S00-reset,S01-delegation-chain-3hop --dry-run
169
+ ```
139
170
 
140
- | Tool | Description |
141
- |------|-------------|
142
- | `dexe_vote_build_erc20_approve` | ERC20 approve — prepend before `deposit` for ERC20-staking DAOs |
143
- | `dexe_vote_build_deposit` | `GovPool.deposit(amount, nftIds)` — payable for native-coin DAOs |
144
- | `dexe_vote_build_withdraw` | `GovPool.withdraw(receiver, amount, nftIds)` |
145
- | `dexe_vote_build_delegate`, `_undelegate` | User-level delegation on `GovPool` |
146
- | `dexe_vote_build_vote`, `_cancel_vote` | `GovPool.vote(pid, isFor, amount, nftIds)` / `cancelVote` |
147
- | `dexe_vote_build_validator_vote`, `_validator_cancel_vote` | Validator voting (internal/external scope) |
148
- | `dexe_vote_build_move_to_validators`, `_execute` | Proposal lifecycle |
149
- | `dexe_vote_build_claim_rewards`, `_claim_micropool_rewards` | Reward claiming |
150
- | `dexe_vote_build_multicall` | Atomic `GovPool.multicall(bytes[])` — batch any of the above into one tx |
171
+ Setup runbook: [`tests/swarm/README.md`](tests/swarm/README.md).
172
+ Scenario schema: [`tests/swarm/scenarios/_schema.md`](tests/swarm/scenarios/_schema.md).
173
+ Per-role agent prompts: `tests/swarm/prompts/`.
151
174
 
152
175
  ## Contributing
153
176
 
package/dist/config.d.ts CHANGED
@@ -15,6 +15,8 @@ export interface DexeConfig {
15
15
  subgraphInteractionsUrl?: string;
16
16
  /** Optional fork block pin (Phase B). */
17
17
  forkBlock?: number;
18
+ /** Private key for tx signing. When set, `dexe_tx_send` can broadcast. */
19
+ privateKey?: string;
18
20
  }
19
21
  /**
20
22
  * Reads environment and returns a frozen config. **Fast and side-effect-free**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,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;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAqDtD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,mFAAmF;IACnF,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,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;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAgEtD"}
package/dist/config.js CHANGED
@@ -32,6 +32,15 @@ export async function loadConfig() {
32
32
  const subgraphPoolsUrl = process.env.DEXE_SUBGRAPH_POOLS_URL?.trim() || undefined;
33
33
  const subgraphValidatorsUrl = process.env.DEXE_SUBGRAPH_VALIDATORS_URL?.trim() || undefined;
34
34
  const subgraphInteractionsUrl = process.env.DEXE_SUBGRAPH_INTERACTIONS_URL?.trim() || undefined;
35
+ const privateKey = process.env.DEXE_PRIVATE_KEY?.trim() || undefined;
36
+ if (privateKey && !rpcUrl) {
37
+ fatal("DEXE_PRIVATE_KEY requires DEXE_RPC_URL to be set (signing needs an RPC endpoint).");
38
+ }
39
+ if (privateKey) {
40
+ const { Wallet } = await import("ethers");
41
+ const addr = new Wallet(privateKey).address;
42
+ process.stderr.write(`[dexe-mcp] signing enabled for ${addr}\n`);
43
+ }
35
44
  let forkBlock;
36
45
  if (process.env.DEXE_FORK_BLOCK) {
37
46
  const n = Number(process.env.DEXE_FORK_BLOCK);
@@ -50,6 +59,7 @@ export async function loadConfig() {
50
59
  subgraphValidatorsUrl,
51
60
  subgraphInteractionsUrl,
52
61
  forkBlock,
62
+ privateKey,
53
63
  });
54
64
  }
55
65
  function fatal(msg) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAqBnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEpD,0EAA0E;IAC1E,0EAA0E;IAC1E,gEAAgE;IAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,YAAY,mDAAmD,CAClH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wCAAwC,YAAY,0GAA0G,CAC/J,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAE7D,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,kDAAkD,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,GAAG,CAAC,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAClF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACnE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAClF,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC5F,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAEhG,IAAI,SAA6B,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,wDAAwD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,YAAY;QACZ,MAAM;QACN,OAAO;QACP,gBAAgB;QAChB,SAAS;QACT,gBAAgB;QAChB,qBAAqB;QACrB,uBAAuB;QACvB,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,oDAAoD;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAuBnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAEpD,0EAA0E;IAC1E,0EAA0E;IAC1E,gEAAgE;IAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,YAAY,mDAAmD,CAClH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,wCAAwC,YAAY,0GAA0G,CAC/J,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAE7D,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,KAAK,CAAC,kDAAkD,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,GAAG,CAAC,CAAC;IACd,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAClF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACnE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAClF,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC5F,MAAM,uBAAuB,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAEhG,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACrE,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,KAAK,CAAC,mFAAmF,CAAC,CAAC;IAC7F,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,IAAI,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,SAA6B,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,wDAAwD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC/F,CAAC;QACD,SAAS,GAAG,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,YAAY;QACZ,MAAM;QACN,OAAO;QACP,gBAAgB;QAChB,SAAS;QACT,gBAAgB;QAChB,qBAAqB;QACrB,uBAAuB;QACvB,SAAS;QACT,UAAU;KACX,CAAC,CAAC;AACL,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,oDAAoD;IACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}