dexe-mcp 0.16.0 → 0.19.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 (83) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/README.md +1 -1
  3. package/dexe-plugin/skills/dexe-create-dao/SKILL.md +90 -66
  4. package/dexe-plugin/skills/dexe-setup/SKILL.md +117 -73
  5. package/dist/cli/init.d.ts.map +1 -1
  6. package/dist/cli/init.js +7 -4
  7. package/dist/cli/init.js.map +1 -1
  8. package/dist/config.d.ts +32 -1
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +45 -7
  11. package/dist/config.js.map +1 -1
  12. package/dist/diag/checks.d.ts.map +1 -1
  13. package/dist/diag/checks.js +53 -4
  14. package/dist/diag/checks.js.map +1 -1
  15. package/dist/env/schema.d.ts +7 -0
  16. package/dist/env/schema.d.ts.map +1 -1
  17. package/dist/env/schema.js +7 -0
  18. package/dist/env/schema.js.map +1 -1
  19. package/dist/lib/ipfs.d.ts +9 -7
  20. package/dist/lib/ipfs.d.ts.map +1 -1
  21. package/dist/lib/ipfs.js +36 -8
  22. package/dist/lib/ipfs.js.map +1 -1
  23. package/dist/lib/preflight.d.ts +67 -4
  24. package/dist/lib/preflight.d.ts.map +1 -1
  25. package/dist/lib/preflight.js +155 -14
  26. package/dist/lib/preflight.js.map +1 -1
  27. package/dist/lib/qr.d.ts +43 -0
  28. package/dist/lib/qr.d.ts.map +1 -0
  29. package/dist/lib/qr.js +95 -0
  30. package/dist/lib/qr.js.map +1 -0
  31. package/dist/lib/requireEnv.d.ts +7 -0
  32. package/dist/lib/requireEnv.d.ts.map +1 -1
  33. package/dist/lib/requireEnv.js +13 -0
  34. package/dist/lib/requireEnv.js.map +1 -1
  35. package/dist/lib/walletconnect.d.ts +15 -0
  36. package/dist/lib/walletconnect.d.ts.map +1 -1
  37. package/dist/lib/walletconnect.js +26 -0
  38. package/dist/lib/walletconnect.js.map +1 -1
  39. package/dist/rpc.d.ts.map +1 -1
  40. package/dist/rpc.js +47 -1
  41. package/dist/rpc.js.map +1 -1
  42. package/dist/tools/daoCreate.d.ts +40 -1
  43. package/dist/tools/daoCreate.d.ts.map +1 -1
  44. package/dist/tools/daoCreate.js +264 -29
  45. package/dist/tools/daoCreate.js.map +1 -1
  46. package/dist/tools/daoDeploy.d.ts.map +1 -1
  47. package/dist/tools/daoDeploy.js +41 -3
  48. package/dist/tools/daoDeploy.js.map +1 -1
  49. package/dist/tools/flow.d.ts +16 -1
  50. package/dist/tools/flow.d.ts.map +1 -1
  51. package/dist/tools/flow.js +67 -12
  52. package/dist/tools/flow.js.map +1 -1
  53. package/dist/tools/getConfig.d.ts.map +1 -1
  54. package/dist/tools/getConfig.js +7 -0
  55. package/dist/tools/getConfig.js.map +1 -1
  56. package/dist/tools/index.js +3 -3
  57. package/dist/tools/index.js.map +1 -1
  58. package/dist/tools/ipfs.d.ts.map +1 -1
  59. package/dist/tools/ipfs.js +34 -14
  60. package/dist/tools/ipfs.js.map +1 -1
  61. package/dist/tools/operationalContext.d.ts.map +1 -1
  62. package/dist/tools/operationalContext.js +16 -1
  63. package/dist/tools/operationalContext.js.map +1 -1
  64. package/dist/tools/otc.d.ts +2 -1
  65. package/dist/tools/otc.d.ts.map +1 -1
  66. package/dist/tools/otc.js +6 -4
  67. package/dist/tools/otc.js.map +1 -1
  68. package/dist/tools/proposalBuild.d.ts.map +1 -1
  69. package/dist/tools/proposalBuild.js +3 -4
  70. package/dist/tools/proposalBuild.js.map +1 -1
  71. package/dist/tools/proposalBuildOffchain.d.ts.map +1 -1
  72. package/dist/tools/proposalBuildOffchain.js +3 -6
  73. package/dist/tools/proposalBuildOffchain.js.map +1 -1
  74. package/dist/tools/read.d.ts.map +1 -1
  75. package/dist/tools/read.js +7 -9
  76. package/dist/tools/read.js.map +1 -1
  77. package/dist/tools/txSend.d.ts.map +1 -1
  78. package/dist/tools/txSend.js +36 -14
  79. package/dist/tools/txSend.js.map +1 -1
  80. package/dist/tools/walletconnectStatus.d.ts.map +1 -1
  81. package/dist/tools/walletconnectStatus.js +13 -29
  82. package/dist/tools/walletconnectStatus.js.map +1 -1
  83. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,113 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.0 — 2026-07-06
4
+
5
+ ### DAO creation: governance coherence guards + frontend parity
6
+
7
+ `dexe_dao_create` could ship broken/reverting DAOs — it invented no defaults, ran
8
+ no coherence checks, and carried assumptions that diverged from the frontend
9
+ (`investing-dashboard`, the 3-year production source of truth that deploys to BSC
10
+ mainnet daily). Reconciled the whole path to the frontend.
11
+
12
+ - **SIMPLE mode.** `dexe_dao_create` now takes high-level fields (`symbol`,
13
+ `totalSupply`, optional `treasuryPercent`/`quorumPercent`/`voteModel`/
14
+ `durationSeconds`) and synthesizes a coherent, frontend-equivalent deploy
15
+ config — LINEAR power, treasury as an **implicit remainder**, a reachable
16
+ quorum. It returns a `mode:"preview"` (resolved config + safety proof) and only
17
+ broadcasts on a second call with `confirm:true`. ADVANCED mode (full `params`)
18
+ still works. `params` is now optional.
19
+ - **Governance coherence guards** (`src/lib/preflight.ts`, enforced in
20
+ `buildDeployGovPool` for both `dexe_dao_create` and `dexe_dao_build_deploy`),
21
+ mirroring the frontend's blocking validation:
22
+ - `checkQuorumReachable` — `quorum% × supply ≤ votable tokens` (treasury/
23
+ undistributed tokens can't vote). LINEAR exact; POLYNOMIAL via a port of the
24
+ frontend `calcMeritocraticVotingPower`. **Hard block.**
25
+ - `checkMinVotesVsDistribution` — `minVotesForVoting/Creating ≤ largest
26
+ recipient`. **Hard block.**
27
+ - `checkSettingsBounds` — `0<quorum≤1e27`, `duration>0`, etc. (`GovSettings.sol`).
28
+ - `checkNoTreasuryRecipient` — the predicted govPool must never be in
29
+ `tokenParams.users[]`.
30
+ - **Corrected the cap rule (verified live on mainnet via eth_call).** The gov
31
+ token is `ERC20Capped`: `cap = 0` reverts (`ERC20Capped: cap is 0`) — there is
32
+ **no uncapped mode** — and `cap < mintedTotal` reverts. `cap == mintedTotal` is
33
+ a valid fixed supply (old bug #28 "cap==minted reverts" is outdated). New rule:
34
+ `cap ≥ mintedTotal > 0`. `checkDeployCap` + the deploy builder now enforce it;
35
+ SIMPLE mode sets `cap = totalSupply`.
36
+ - **Reversed the treasury-remainder rule (old bug #32 was wrong — verified live).**
37
+ A treasury remainder (`sum(amounts) < mintedTotal`) deploys fine on mainnet — the
38
+ contract mints the remainder to the DAO. `checkTreasuryRemainder` now only rejects
39
+ OVER-distribution (`sum > minted`), on all chains. The prior "mainnet needs
40
+ `mintedTotal == sum(amounts)`" belief forced the treasury address into the voter list.
41
+ - **Mainnet is NOT broken.** Dropped the false "mainnet deployGovPool reverts /
42
+ `require(false)`" gating text. Mainnet (56) is a supported target; it just
43
+ requires `confirm:true` (spends real BNB). Testnet-first is a recommendation.
44
+ - Default vote model = **LINEAR**; default quorum **51%** with a ≥50% advisory
45
+ floor. No new tools.
46
+
47
+ ## 0.18.0 — 2026-07-06
48
+
49
+ ### WalletConnect QR + hot-key "NOT SAFE" warnings
50
+
51
+ WalletConnect is now the clearly-primary signer, and pairing takes zero copy-paste.
52
+
53
+ - **`dexe_wc_connect` renders a scannable QR**, not a raw URI. It returns both a
54
+ terminal ASCII QR (scannable in a bare terminal, no browser, no external
55
+ service) **and** an `image/png` MCP content block (crisp QR in GUI clients).
56
+ The raw `uri` + an `api.qrserver.com` fallback URL are still included. New
57
+ helper `src/lib/qr.ts` (lazy-imports `qrcode`, so read-only installs pay
58
+ nothing and a missing install degrades gracefully).
59
+ - **Auto-print QR when a write needs a wallet.** `dexe_tx_send` in WalletConnect
60
+ mode with no session now *starts pairing and prints the QR* instead of
61
+ erroring "call dexe_wc_connect". The composite flows (`dexe_dao_create`,
62
+ `dexe_proposal_create`, `dexe_proposal_vote_and_execute`, OTC) attach a live
63
+ `pairing` QR to their read-only response. (Composites still emit payloads to
64
+ feed to `dexe_tx_send` — no WC broadcast routing inside composites.)
65
+ - **Hot keys are flagged "⚠️ NOT SAFE" everywhere.** Every `dexe_tx_send`
66
+ hot-key broadcast carries a `safety` field; `dexe_get_config` reports
67
+ `recommendedSigner: "walletconnect"` + a `safety` note; `dexe_doctor` adds a
68
+ `signer.hotKey` advisory; the startup log warns about the plaintext key.
69
+ - **`dexe_wc_connect` no longer refuses when `DEXE_PRIVATE_KEY` is set** — it
70
+ pairs and tells you the hot key still takes signing precedence until removed
71
+ (non-breaking: key-wins precedence is unchanged).
72
+ - New: `WalletConnectManager.ensurePairing()` (reuses an in-flight URI / live
73
+ session). No new tools — tool count unchanged.
74
+
75
+ ## 0.17.0 — 2026-07-06
76
+
77
+ ### Zero-config public defaults + guided setup
78
+
79
+ A fresh install is now useful immediately — **reads and WalletConnect signing
80
+ work with no `.env` at all.** The plugin ships public defaults, all overridable
81
+ by a user `.env` (env value always wins).
82
+
83
+ - **Baked defaults** (`src/config.ts` `DEFAULTS`): DeXe backend (`api.dexe.io`),
84
+ a shared WalletConnect project id, and the three DeXe subgraph URLs (The Graph
85
+ decentralized network, modern `gateway.thegraph.com` host, key embedded in the
86
+ path — no standalone `DEXE_GRAPH_API_KEY` needed, which also removes the old
87
+ Bearer-vs-URL key mismatch). RPC public fallback + the chain-56 registry were
88
+ already baked.
89
+ - **IPFS reads default to public gateways** (ipfs.io, dweb.link, cloudflare) when
90
+ no dedicated gateway is set. New `DEXE_IPFS_DISABLE_PUBLIC_FALLBACK=1` opt-out.
91
+ - **Behavior change:** with no hot key, `signerMode` is now `walletconnect`
92
+ (WalletConnect available) instead of `readonly`. Signing is still gated on an
93
+ actual `dexe_wc_connect`; `address` stays `null` until you connect.
94
+ - **Runtime hints instead of bare errors.** A failing public-RPC call now carries
95
+ a "set a private RPC" nudge (only for the public fallback, never your own RPC;
96
+ contract reverts pass through untouched). A failing all-public IPFS fetch nudges
97
+ toward a dedicated gateway. The Pinata-JWT block on create flows now uses a
98
+ shared, actionable message pointing at `/dexe-setup`.
99
+ - **`dexe_doctor`** validates the *default* subgraph + backend endpoints (no
100
+ longer skipped when unset) and adds an `env.sharedDefaults` advisory — the
101
+ shared Graph key + WC id are billable-shared, so heavy users should bring their
102
+ own. `dexe_context.env` gains `usingSharedDefaults`, `ipfsReads`,
103
+ `walletConnectAvailable`, and `usingPublicRpcFallback`.
104
+ - **`/dexe-setup` rewritten** as a tiered "skip → what breaks" journey, plus a
105
+ once-only SessionStart onboarding nudge shipped with the plugin.
106
+ - Docs: `docs/ENVIRONMENT.md` gains a baked-defaults table + key-rotation note;
107
+ `.env.example` reframed around optional overrides with current var names.
108
+
109
+ No new tools (159). No breaking config changes — every default is overridable.
110
+
3
111
  ## 0.16.0 — 2026-07-04
4
112
 
5
113
  ### Backend-powered treasury + holder/stats/NFT reads (156 → 159 tools)
package/README.md CHANGED
@@ -46,7 +46,7 @@ Then just ask:
46
46
 
47
47
  > *"Show the treasury of `0x…` on BSC."*
48
48
 
49
- Reads work with **zero setup** — the server falls back to public BSC RPC out of the box, and the governance skills (create DAO, create proposal, vote & execute, OTC) install with the plugin.
49
+ Reads work with **zero setup** — on-chain data, subgraphs, the DeXe backend, and IPFS all run on public defaults out of the box, and WalletConnect signing is available immediately (connect a wallet with `dexe_wc_connect`). The governance skills (create DAO, create proposal, vote & execute, OTC) install with the plugin.
50
50
 
51
51
  **Want to create DAOs or proposals, or broadcast transactions?** Type **`/dexe-setup`** and Claude walks you through adding your keys (a Pinata token for IPFS, a wallet for signing) — one guided step, nothing to hand-edit.
52
52
 
@@ -1,99 +1,123 @@
1
1
  ---
2
2
  name: dexe-create-dao
3
3
  description: |
4
- Deploy a new DeXe DAO with the one-call `dexe_dao_create` composite. Covers the
5
- exact param recipe, the decimal conventions, and the four deploy gotchas that
6
- silently revert (cap>minted, LINEAR initData, non-zero userKeeper asset, mainnet
7
- treasury remainder). Use when the user says "create/deploy a DAO".
4
+ Deploy a new DeXe DAO with the one-call `dexe_dao_create` composite. Use SIMPLE
5
+ mode (symbol + totalSupply) and let the tool synthesize a coherent, governance-
6
+ safe config it previews the resolved config + a safety proof and only
7
+ broadcasts on confirm. Covers the two quorum rules (reachable ≤ votable, floor
8
+ ≥50%), the implicit-treasury pattern, and the deploy gotchas. Use when the user
9
+ says "create/deploy a DAO".
8
10
  ---
9
11
 
10
12
  # dexe-create-dao
11
13
 
12
- Deploy a DeXe governance DAO in **one tool call** `dexe_dao_create` handles
14
+ Deploy a DeXe governance DAO in **one tool call**. `dexe_dao_create` handles
13
15
  avatar → DAO IPFS metadata → `PoolFactory.deployGovPool` (predicted-address
14
16
  wiring, 1→5 settings auto-expand, executorDescription upload) → broadcast.
15
17
 
16
- ## Golden rule: testnet first
18
+ **Do NOT hand-fabricate token splits or quorum numbers.** That is exactly how you
19
+ ship a broken DAO. Use SIMPLE mode and let the tool synthesize + verify a coherent
20
+ config, or read the two rules below and satisfy them.
17
21
 
18
- **Validate on BSC testnet (chain 97).** Mainnet `deployGovPool` is broken
19
- upstream (`require(false)`). Never spend mainnet BNB on a deploy without the
20
- user explicitly asking. Pass `chainId: 97`.
22
+ ## The two rules that make a DAO usable (the tool enforces both)
21
23
 
22
- ## Recipe
24
+ A DeXe DAO holds two kinds of tokens: **votable** (distributed to real wallets)
25
+ and **treasury** (held by the DAO/govPool — these **cannot vote**).
23
26
 
24
- 0. **Orient:** call `dexe_context` first it shows the signer, active chain,
25
- env readiness, and DAOs you already deployed (so you don't re-create one).
26
- 1. **Confirm chain + signer:** `dexe_get_config` (or the `dexe_context` output).
27
- Ensure the active/target chain is 97 and `DEXE_PINATA_JWT` is set (required
28
- for metadata upload).
29
- 2. **(Optional) avatar:** `dexe_dao_generate_avatar` or `dexe_ipfs_upload_avatar`
30
- → take the returned `cid` as `avatarCID`. Must be a **real JPEG**, not SVG
31
- bytes named `.jpeg` (the frontend gateway rejects the mismatch).
32
- 3. **Create:** call `dexe_dao_create` once. `deployer` defaults to the signer.
27
+ 1. **Quorum must be REACHABLE:** `quorum% × totalSupply votable tokens`.
28
+ Equivalently `quorum% (100 treasury%)`. If quorum is higher than the
29
+ votable share, **no proposal can ever pass** the tool hard-blocks this
30
+ (mirrors the frontend's blocking check).
31
+ 2. **Quorum floor ≥ 50%** (51% recommended). Below 50%, a small group can pass
32
+ proposals and even drain the treasury. Advisory, surfaced in the preview.
33
+
34
+ Together these mean **treasury% ≤ 50%** (so a ≥50% quorum can still be reached).
35
+ The default (treasury 49% / quorum 51%) sits right at the boundary.
36
+
37
+ ## Golden rule: validate on testnet first
38
+
39
+ Deploy to **BSC testnet (chain 97)** first (`chainId: 97`) — free faucet BNB.
40
+ **Mainnet (chain 56) works** (the frontend ships there daily) and is supported,
41
+ but it spends real BNB, so `dexe_dao_create` requires `confirm: true` for any
42
+ mainnet broadcast. Never confirm a mainnet deploy without the user explicitly
43
+ asking.
44
+
45
+ ## Recipe — SIMPLE mode (recommended)
46
+
47
+ 0. **Orient:** `dexe_context` — shows signer, active chain, env readiness, and
48
+ DAOs you already deployed.
49
+ 1. **Env:** ensure the target chain is 97 and `DEXE_PINATA_JWT` is set (metadata).
50
+ 2. **(Optional) avatar:** `dexe_dao_generate_avatar` / `dexe_ipfs_upload_avatar`
51
+ → pass the `cid` as `avatarCID` (a real JPEG, not SVG named `.jpeg`).
52
+ 3. **Preview:** call `dexe_dao_create` with just the essentials:
33
53
 
34
54
  ```jsonc
35
55
  dexe_dao_create({
36
56
  chainId: 97,
37
57
  daoName: "Aurora Collective",
38
- daoDescription: "A community treasury DAO.", // markdown → slate, uploaded for you
39
- websiteUrl: "https://aurora.example",
40
- socialLinks: [["twitter", "https://x.com/aurora"]],
41
- avatarCID: "bafy…", // optional
42
- params: {
43
- settingsParams: {
44
- proposalSettings: [{ // pass ONE → auto-expands to 5
45
- earlyCompletion: true,
46
- delegatedVotingAllowed: false, // INVERTED: false = delegation ALLOWED
47
- validatorsVote: false,
48
- duration: "86400", // seconds (1 day)
49
- durationValidators: "86400",
50
- executionDelay: "0",
51
- quorum: "500000000000000000000000000", // 25-dec wei = 50%
52
- quorumValidators: "500000000000000000000000000",
53
- minVotesForVoting: "1000000000000000000", // 18-dec wei = 1 token
54
- minVotesForCreating: "1000000000000000000",
55
- rewardsInfo: { rewardToken: "0x0000000000000000000000000000000000000000",
56
- creationReward: "0", executionReward: "0", voteRewardsCoefficient: "0" },
57
- executorDescription: "" // auto-uploaded to IPFS
58
- }]
59
- },
60
- userKeeperParams: { tokenAddress: "0x0000000000000000000000000000000000000000",
61
- nftAddress: "0x0000000000000000000000000000000000000000",
62
- individualPower: "0", nftsTotalSupply: "0" },
63
- tokenParams: { // non-empty name => create a gov token
64
- name: "Aurora", symbol: "AUR",
65
- users: ["0xYourAddr"],
66
- cap: "0", // 0 = uncapped (or > mintedTotal)
67
- mintedTotal: "1000000000000000000000", // 1000 tokens (18-dec)
68
- amounts: ["1000000000000000000000"] // MUST sum to mintedTotal on mainnet
69
- },
70
- votePowerParams: { voteType: "LINEAR_VOTES" } // initData auto-encoded — do NOT pass it
71
- }
58
+ symbol: "AUR",
59
+ totalSupply: "1000000", // whole tokens
60
+ // optional (these are the defaults):
61
+ treasuryPercent: 49, // implicit remainder held by the DAO (can't vote)
62
+ quorumPercent: 51, // must be ≥50 AND ≤ (100 − treasuryPercent)
63
+ voteModel: "LINEAR", // 1 token = 1 vote (default); or "POLYNOMIAL"
64
+ durationSeconds: 86400, // 1 day
65
+ daoDescription: "A community treasury DAO.",
66
+ avatarCID: "bafy…" // optional
72
67
  })
73
68
  ```
74
69
 
70
+ This returns `mode: "preview"` with the **resolved config** (who holds what) and a
71
+ **safety proof** (votable %, quorum %, reachable?, floor OK?). Show it to the user.
72
+
73
+ 4. **Confirm:** re-call with the **same arguments plus `confirm: true`** to broadcast.
74
+ The deployer holds the entire distributed portion; the treasury is an **implicit
75
+ remainder** (the govPool address is never a token recipient).
76
+
77
+ ## Recipe — ADVANCED mode (full control)
78
+
79
+ Pass a full `params` struct (same shape as `dexe_dao_build_deploy`) instead of the
80
+ SIMPLE fields. The coherence guards still run. Key rules for hand-built params:
81
+
82
+ - **Treasury is an implicit remainder.** `tokenParams.users`/`amounts` list only
83
+ external wallets; `sum(amounts)` is **less than** `mintedTotal` (the contract
84
+ mints the remainder to the DAO). **Never** put the predicted govPool in `users[]`.
85
+ - Pass **one** `proposalSettings` entry → auto-expands to 5.
86
+ - `votePowerParams.voteType: "LINEAR_VOTES"` — `initData` is auto-encoded; don't pass it.
87
+
75
88
  ## Deploy gotchas (the tool pre-flights these — heed the errors)
76
89
 
77
- 1. **cap > mintedTotal** — or `cap = 0` (uncapped). `cap == mintedTotal` reverts
78
- ERC20Gov init silently (bug #28).
79
- 2. **LINEAR initData** — the tool auto-encodes `__LinearPower_init()`
80
- (`0x892aea1f`). Never pass `initData` for LINEAR/POLYNOMIAL; only CUSTOM_VOTES
81
- takes a manual `initData`.
82
- 3. **Non-zero governance asset** if not creating a token (`tokenParams.name`
83
- empty), set `userKeeperParams.tokenAddress` or `.nftAddress`.
84
- 4. **Treasury remainder (mainnet)** — `mintedTotal` must equal `sum(amounts)`;
85
- a remainder reverts on chain 56 (bug #32). Distribute the whole mint.
90
+ 1. **Unreachable quorum** — `quorum% × supply > votable`. Lower quorum, distribute
91
+ more to voters, or shrink the treasury. (hard block)
92
+ 2. **min-votes above every holder** — `minVotesForVoting/Creating` must be ≤ the
93
+ largest single recipient. (hard block)
94
+ 3. **cap** must be `> 0` AND `≥ mintedTotal`. There is **no uncapped mode**
95
+ (`cap = 0` reverts `ERC20Capped: cap is 0`); `cap == mintedTotal` is a valid
96
+ fixed supply; `cap < mintedTotal` reverts. SIMPLE mode sets `cap = totalSupply`. (hard block)
97
+ 4. **LINEAR initData** — auto-encoded (`__LinearPower_init()` = `0x892aea1f`). Never
98
+ pass `initData` for LINEAR/POLYNOMIAL; only CUSTOM_VOTES takes a manual one.
99
+ 5. **Non-zero governance asset** — if not creating a token, set
100
+ `userKeeperParams.tokenAddress` or `.nftAddress`.
101
+ 6. **Over-distribution** — `sum(amounts)` must be ≤ `mintedTotal`. (An implicit
102
+ treasury remainder is correct and expected — do NOT force them equal.)
86
103
 
87
104
  ## Decimal conventions (must match the frontend)
88
105
 
89
- - `quorum`, `quorumValidators`, `voteRewardsCoefficient`: **25-dec** wei (50% = `5e26`).
106
+ - `quorum`, `quorumValidators`, `voteRewardsCoefficient`: **25-dec** wei (50% = `5e26`, 100% = `1e27`).
90
107
  - `minVotes*`, `cap`, `mintedTotal`, `amounts`, `individualPower`, rewards: **18-dec** wei.
91
108
  - `duration*`, `executionDelay`: plain **seconds** as string.
92
- - `delegatedVotingAllowed` is **inverted**: `true` DISABLES delegation.
109
+ - `delegatedVotingAllowed` is **inverted**: `true` DISABLES delegation, `false` ALLOWS it.
110
+
111
+ ## Pre-submit self-check (before `confirm: true`)
112
+
113
+ - [ ] `quorumPercent ≤ 100 − treasuryPercent` (reachable) and `≥ 50` (floor)?
114
+ - [ ] treasury is an implicit remainder — govPool NOT in `users[]`?
115
+ - [ ] `sum(amounts) ≤ mintedTotal`, and `cap ≥ mintedTotal > 0` (never cap=0)?
116
+ - [ ] validating on testnet (97) first, or the user explicitly asked for mainnet?
93
117
 
94
118
  ## After deploy
95
119
 
96
- The result includes `predictedGovPool` — that is the DAO's GovPool address once
97
- the tx confirms. Use it for `dexe_proposal_create` / `dexe_proposal_vote_and_execute`.
120
+ The result includes `predictedGovPool` — the DAO's GovPool address once the tx
121
+ confirms. Use it for `dexe_proposal_create` / `dexe_proposal_vote_and_execute`.
98
122
 
99
123
  Related: [[dexe-create-proposal]], [[dexe-vote-execute]].
@@ -1,108 +1,152 @@
1
1
  ---
2
2
  name: dexe-setup
3
3
  description: |
4
- Onboard a user to dexe-mcp. Runs `dexe_doctor`, parses the report, asks the
5
- user only for what is missing, edits `.env` (NEVER `.claude.json`), and
6
- tells them to restart Claude Code. Triggered by `/dexe-setup`, or
7
- proactively when the user reports an env-related MCP tool failure
8
- ("DEXE_PINATA_JWT not set", "RPC unreachable", "subgraph 401", etc.).
4
+ Guided setup journey for dexe-mcp. Explains that reads work with ZERO config,
5
+ then walks the user through only the keys that unlock more signing, DAO/
6
+ proposal creation (Pinata JWT), and optional reliability upgrades telling
7
+ them for each one exactly what breaks if they skip it. Drives from
8
+ `dexe_doctor`, edits `.env` (NEVER `.claude.json`), and tells them to restart.
9
+ Triggered by `/dexe-setup`, or proactively when a tool reports a missing key
10
+ ("DEXE_PINATA_JWT is required…", "public RPC unstable", "shared public defaults").
9
11
  ---
10
12
 
11
13
  # dexe-setup
12
14
 
13
15
  ## What this does
14
16
 
15
- Iterative env-setup loop for `dexe-mcp`. Replaces the brittle workflow where
16
- Claude guesses which file to edit and which keys are needed. Drives entirely
17
- from the `dexe_doctor` tool no guessing.
17
+ A guided onboarding journey for `dexe-mcp`. The plugin ships with sane public
18
+ defaults, so **reads work the moment it's installed** — no keys required. This
19
+ skill's job is to explain that reality and then help the user unlock the parts
20
+ that *do* need a key, one tier at a time, always saying what they lose by
21
+ skipping. It drives from the `dexe_doctor` tool — no guessing which file or key.
22
+
23
+ ## The two-tier reality (say this first)
24
+
25
+ Open by orienting the user:
26
+
27
+ > **Reads already work** — DAO info, treasury, holders, proposals, subgraph
28
+ > queries, IPFS reads all run on shared public defaults with zero setup.
29
+ > You only need to configure something to **write** or to **create DAOs/
30
+ > proposals**. Want me to walk you through it, or are reads all you need?
31
+
32
+ If reads are all they need: confirm they're done, mention `dexe_doctor` is there
33
+ if anything misbehaves, and stop.
18
34
 
19
35
  ## When to invoke
20
36
 
21
37
  - The user types `/dexe-setup`.
22
- - The user reports any of:
23
- - "dexe-mcp not working", "tools failing", "RPC error", "missing env"
24
- - A specific MCP tool error mentioning a `DEXE_*` env var
25
- - "How do I configure dexe-mcp?"
26
- - You see a tool result containing `"Missing required env: DEXE_*"` or
27
- `"DEXE_* is not set"` — invoke proactively.
38
+ - The user says "set up dexe", "enable writes", "I want to create a DAO/
39
+ proposal", "how do I configure dexe-mcp?".
40
+ - You see a tool result containing any of: `"DEXE_PINATA_JWT is required"`,
41
+ `"Missing required env"`, `"public RPC unstable"`, `"public IPFS gateways
42
+ are failing"`, `env.sharedDefaults` invoke proactively.
28
43
 
29
44
  ## Hard rules (do not violate)
30
45
 
31
46
  1. **Never write `DEXE_*` values to `.claude.json`.** The MCP host's env block
32
47
  SHADOWS `.env` silently. Edits go in `.env` at the dexe-mcp repo root.
33
- 2. **Never write `DEXE_PRIVATE_KEY` without explicit user opt-in.** Default
34
- to readonly mode. If the user says "I want to broadcast", first suggest
35
- WalletConnect (`DEXE_WALLETCONNECT_PROJECT_ID`); only fall back to
36
- `DEXE_PRIVATE_KEY` if the user insists, and warn them that the key
37
- lives in plaintext on disk.
48
+ 2. **Never write `DEXE_PRIVATE_KEY` without explicit user opt-in.** Signing is
49
+ available by default via WalletConnect (below) reach for a hot key only if
50
+ the user insists, and warn it lives in plaintext on disk.
38
51
  3. **Always tell the user to restart Claude Code after editing `.env`.**
39
- `process.loadEnvFile()` runs once at startup; mid-session edits do
40
- nothing until restart.
41
- 4. **Cap the loop at 3 iterations.** If `dexe_doctor` still shows failures
42
- after three doctor → fix → restart cycles, stop and present the full
43
- report to the user — the remaining issues need manual investigation.
52
+ `process.loadEnvFile()` runs once at startup; mid-session edits do nothing
53
+ until restart.
54
+ 4. **Cap the doctor loop at 3 iterations.** After three doctor fix → restart
55
+ cycles still failing, stop and present the full report for manual triage.
56
+
57
+ ## The setup tiers (walk in order; for each, state what breaks if skipped)
58
+
59
+ ### Tier 0 — Reads (nothing to do)
60
+ On-chain reads, subgraph reads, backend reads, IPFS reads all work on shared
61
+ public defaults. **Skip cost: none.** The only downside is the shared Graph API
62
+ key + public RPC/IPFS gateways are rate-limited and billable-shared — fine for
63
+ light use, upgrade under Tier 3 for heavy use.
64
+
65
+ ### Tier 1 — Signing (to vote / execute / broadcast)
66
+ WalletConnect is **available by default** (shared project id). To sign: run
67
+ `dexe_wc_connect`, scan the QR with a wallet, approve each tx on your phone. No
68
+ key touches disk.
69
+ - **Skip cost:** you can build calldata and read, but can't broadcast.
70
+ - Optional: set your own `DEXE_WALLETCONNECT_PROJECT_ID` (free at
71
+ cloud.reown.com) to stop sharing the default id.
72
+ - Only if the user *insists* on unattended/CI signing → hot key ladder below.
73
+
74
+ ### Tier 2 — Creating DAOs / proposals (the one hard blocker)
75
+ Creating a DAO or proposal pins metadata to IPFS, which needs a **Pinata JWT**
76
+ (`DEXE_PINATA_JWT`). This is the only thing reads/signing can't default around.
77
+ - **Skip cost:** `dexe_dao_create`, `dexe_proposal_create`, and metadata uploads
78
+ refuse up front (no on-chain tx is attempted).
79
+ - How to get one (say this to non-technical users): sign up free at
80
+ https://app.pinata.cloud → API Keys → New Key → enable `pinJSONToIPFS` and
81
+ `pinFileToIPFS` → copy the JWT.
82
+ - Validate it before saving: `GET https://api.pinata.cloud/data/testAuthentication`
83
+ with header `Authorization: Bearer <jwt>` should return `{"message":
84
+ "Congratulations! ..."}`. (The `npx dexe-mcp init` wizard does this check for you.)
85
+
86
+ ### Tier 3 — Reliability upgrades (optional, offer when errors appear)
87
+ - **Private RPC** — if a read fails with *"public RPC unstable"*: set
88
+ `DEXE_RPC_URL_MAINNET` (chain 56) / `DEXE_RPC_URL_TESTNET` (chain 97) to an
89
+ Alchemy / QuickNode / Ankr URL. **Skip cost:** occasional rate-limit flakiness.
90
+ - **Dedicated IPFS gateway** — if a read fails with *"public IPFS gateways are
91
+ failing"*: set `DEXE_IPFS_GATEWAY` (a free Pinata dedicated gateway comes with
92
+ your JWT — `https://<subdomain>.mypinata.cloud`). **Skip cost:** slower/flaky
93
+ metadata reads.
94
+ - **Own Graph key** — if `dexe_doctor` shows `env.sharedDefaults`: set your own
95
+ `DEXE_SUBGRAPH_*_URL` (with your Graph key embedded, or `DEXE_GRAPH_API_KEY`).
96
+ **Skip cost:** you share a rate-limited, billable key.
44
97
 
45
98
  ## Algorithm
46
99
 
47
100
  1. Call `dexe_doctor` (no input).
48
- 2. Read the `summary` and `checks` arrays from the structured response.
49
- - If `summary.status === "pass"`, congratulate the user no work to do.
50
- - If only `warnings`, surface them but don't block.
51
- 3. For every `fail`:
52
- - If it is an env presence/validation issue: collect the env key.
53
- - If it is a network reachability issue (RPC unreachable, Pinata 401):
54
- use the `remediation` field verbatim; ask the user for a replacement
55
- value.
56
- 4. Batch the questions by category (RPC, IPFS, subgraph, signer) using
57
- `AskUserQuestion`. One question per category, not one per key.
58
- 5. Locate the `.env` file. The startup banner in the doctor response shows
59
- `environment.envFile`; if absent, look at the repo root (where
60
- `package.json` lives usually `D:\dev\dexe-mcp\.env`).
61
- 6. Edit `.env` with the Edit tool. For each provided value:
62
- - If the key already exists, replace its line.
63
- - Otherwise, append `KEY=value` at the bottom (preserve trailing newline).
101
+ 2. Read `summary` and `checks` from the structured response.
102
+ - `summary.status === "pass"` (only warnings) reads are healthy. Ask which
103
+ tier (if any) the user wants; don't block on warnings.
104
+ - Treat `warn` checks (`chain.publicRpcFallback`, `env.sharedDefaults`) as
105
+ *offers*, not problems.
106
+ 3. For each `fail` or the user's chosen tier, collect the env key(s). Use the
107
+ check's `remediation` verbatim for network failures.
108
+ 4. Batch questions by tier/category with `AskUserQuestion` — one question per
109
+ tier, not one per key. Only ask for what the chosen tier needs.
110
+ 5. Locate `.env` at the repo root (where `package.json` lives — usually
111
+ `D:\dev\dexe-mcp\.env`). The doctor/banner shows the env-file path.
112
+ 6. Edit `.env` with the Edit tool: replace the key's line if present, else
113
+ append `KEY=value` (preserve the trailing newline).
64
114
  7. Tell the user, verbatim:
65
115
  > Edits saved to `.env`. **Restart Claude Code** so the new values load
66
- > (`Ctrl+R` rebuilds the session, or quit and relaunch). Then I will
67
- > re-run `dexe_doctor` to confirm.
68
- 8. After restart, call `dexe_doctor` again. If still failing, go to step 3.
69
- Iterate at most 3 times.
70
- 9. If after 3 iterations there are still failures, present the full
71
- `checks` array and tell the user the remaining issues need manual
72
- investigation (likely: bad credentials, account suspended, paid plan
73
- required, or a corporate proxy blocking the relevant host).
116
+ > (quit and relaunch). Then I'll re-run `dexe_doctor` to confirm.
117
+ 8. After restart, re-run `dexe_doctor`. If still failing, go to step 3. Iterate
118
+ at most 3 times.
119
+ 9. After 3 iterations still failing, present the full `checks` array — remaining
120
+ issues need manual triage (bad credentials, suspended account, paid-plan
121
+ required, corporate proxy).
74
122
 
75
123
  ## Signer mode escalation
76
124
 
77
- If a user wants broadcast capability, walk this ladder (top = safest):
78
-
79
- 1. **WalletConnect (`DEXE_WALLETCONNECT_PROJECT_ID`).** Key stays on phone.
80
- Every tx is approved manually.
81
- 2. **Safe multisig (`DEXE_SAFE_TX_SERVICE_URL`).** Proposes tx to a Safe;
82
- owners co-sign separately.
83
- 3. **Hot key (`DEXE_PRIVATE_KEY`).** Plaintext on disk. Convenient for CI
84
- bots, dangerous for humans. Show this warning before writing:
85
- > Setting `DEXE_PRIVATE_KEY` stores your key in plaintext at `.env`.
86
- > Anyone who reads the file can drain that wallet. Are you sure you
87
- > don't want WalletConnect (above) or a Safe multisig instead?
88
- 4. Refuse to proceed past step 3 without an explicit "yes" confirming
89
- the user understands the trade-off.
125
+ If the user wants signing beyond phone-approval WalletConnect, walk this ladder
126
+ (top = safest):
127
+
128
+ 1. **WalletConnect (default).** `dexe_wc_connect` → approve on phone. No key on
129
+ disk. This is already available; prefer it.
130
+ 2. **Safe multisig (`DEXE_SAFE_TX_SERVICE_URL`).** Proposes tx to a Safe; owners
131
+ co-sign separately.
132
+ 3. **Hot key (`DEXE_PRIVATE_KEY`).** Plaintext on disk. Convenient for CI bots,
133
+ dangerous for humans. Show this before writing:
134
+ > Setting `DEXE_PRIVATE_KEY` stores your key in plaintext at `.env`. Anyone
135
+ > who reads the file can drain that wallet. Are you sure you don't want
136
+ > WalletConnect (already available) or a Safe multisig instead?
137
+ 4. Refuse to proceed to a hot key without an explicit "yes" confirming the
138
+ trade-off.
90
139
 
91
140
  ## .env precedence trap
92
141
 
93
- If `dexe_doctor` returns a check named `env.<KEY>` with the message
94
- "shadowed by host env block", the user has the same key defined in BOTH
95
- `.env` AND `.claude.json`. The host wins. Tell them to either:
96
- - remove the key from `.claude.json` `env` block (use `.env`), OR
97
- - update it in `.claude.json` instead of `.env`.
98
-
99
- Whichever they pick, restart Claude Code after.
142
+ If `dexe_doctor` returns a check named `env.<KEY>` with "shadowed by host env
143
+ block", the same key is defined in BOTH `.env` and `.claude.json`. The host
144
+ wins. Tell them to keep it in one place (prefer `.env`) and restart.
100
145
 
101
146
  ## Useful tools (reference)
102
147
 
103
148
  - `dexe_doctor` — diagnostic (read-only, safe to call repeatedly).
104
- - `dexe_get_config` — current chain/signer state (lower detail than doctor).
105
- - `npx dexe-mcp doctor` — CLI form of the same diagnostic. Useful when the
106
- MCP server itself failed to start.
107
- - `npx dexe-mcp init` fresh-start wizard. Overwrites `.env`. Use for new
108
- installations, not for fixing an existing setup.
149
+ - `dexe_context` — signer/mode + env readiness + `usingSharedDefaults` list.
150
+ - `npx dexe-mcp doctor` — CLI form; useful when the MCP server failed to start.
151
+ - `npx dexe-mcp init` fresh-start wizard (prompts + live-validates Pinata JWT).
152
+ Overwrites `.env`; use for new installs, not for fixing an existing setup.
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AA+BA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA2MzC;AA0CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB3E;AA2HD,wBAAgB,YAAY,IAAI,MAAM,CAWrC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AA+BA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA8MzC;AA0CD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB3E;AA2HD,wBAAgB,YAAY,IAAI,MAAM,CAWrC"}
package/dist/cli/init.js CHANGED
@@ -28,8 +28,10 @@ export async function run() {
28
28
  try {
29
29
  output.write(line("dexe-mcp init — onboarding wizard"));
30
30
  output.write(line("─".repeat(64)));
31
- output.write(line("Builds a minimal .env. Answers are stored in plaintext;"));
32
- output.write(line("use WalletConnect or readonly mode if that worries you."));
31
+ output.write(line("Reads already work with ZERO config (RPC, subgraphs, backend,"));
32
+ output.write(line("IPFS reads, WalletConnect). This only overrides a default or"));
33
+ output.write(line("enables writes. Answers are stored in plaintext; use WalletConnect"));
34
+ output.write(line("or readonly mode if that worries you."));
33
35
  output.write("\n");
34
36
  const repoRoot = findRepoRoot();
35
37
  // ---- Top-level intent -----------------------------------------------
@@ -85,8 +87,9 @@ export async function run() {
85
87
  ? (await ask(rl, "IPFS gateway URL", "https://gateway.pinata.cloud")).trim()
86
88
  : "";
87
89
  // ---- Subgraph (optional) -------------------------------------------
88
- output.write(line("Subgraph reads need a Graph API key (free at thegraph.com)."));
89
- const graphKey = (await ask(rl, "Graph API key (blank to skip subgraph reads)", "")).trim();
90
+ output.write(line("Subgraph reads work by default via a shared DeXe Graph key."));
91
+ output.write(line("Set your own only for heavy use (blank keeps the default)."));
92
+ const graphKey = (await ask(rl, "Graph API key (blank = use shared default)", "")).trim();
90
93
  // ---- Signer mode ---------------------------------------------------
91
94
  output.write(line(""));
92
95
  output.write(line("Signer mode:"));