@continuumdao/ctm-mpc-defi 0.2.29 → 0.2.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/catalog.cjs +2892 -13
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +5454 -977
- package/dist/agent/catalog.js +2784 -15
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aerodrome/SKILL.md +93 -0
- package/dist/agent/skills/compound-v3/SKILL.md +132 -0
- package/dist/agent/skills/continuum-dao/SKILL.md +139 -0
- package/dist/agent/skills/morpho/SKILL.md +16 -8
- package/dist/buildBatch-CngvebiD.d.ts +45 -0
- package/dist/chains/evm/index.d.ts +6 -44
- package/dist/core/index.cjs +44 -40
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +44 -40
- package/dist/core/index.js.map +1 -1
- package/dist/{eip712Multisign-xhXpUYp3.d.ts → eip712Multisign-DCW7heqX.d.ts} +11 -8
- package/dist/index.cjs +183 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +182 -58
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aerodrome/index.cjs +3922 -0
- package/dist/protocols/evm/aerodrome/index.cjs.map +1 -0
- package/dist/protocols/evm/aerodrome/index.d.ts +792 -0
- package/dist/protocols/evm/aerodrome/index.js +3843 -0
- package/dist/protocols/evm/aerodrome/index.js.map +1 -0
- package/dist/protocols/evm/arcus/index.cjs +62 -55
- package/dist/protocols/evm/arcus/index.cjs.map +1 -1
- package/dist/protocols/evm/arcus/index.js +62 -55
- package/dist/protocols/evm/arcus/index.js.map +1 -1
- package/dist/protocols/evm/compound-v3/index.cjs +1542 -0
- package/dist/protocols/evm/compound-v3/index.cjs.map +1 -0
- package/dist/protocols/evm/compound-v3/index.d.ts +683 -0
- package/dist/protocols/evm/compound-v3/index.js +1488 -0
- package/dist/protocols/evm/compound-v3/index.js.map +1 -0
- package/dist/protocols/evm/continuum-dao/index.cjs +2237 -0
- package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -0
- package/dist/protocols/evm/continuum-dao/index.d.ts +700 -0
- package/dist/protocols/evm/continuum-dao/index.js +2110 -0
- package/dist/protocols/evm/continuum-dao/index.js.map +1 -0
- package/dist/protocols/evm/hyperliquid/index.cjs +125 -110
- package/dist/protocols/evm/hyperliquid/index.cjs.map +1 -1
- package/dist/protocols/evm/hyperliquid/index.js +125 -110
- package/dist/protocols/evm/hyperliquid/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +746 -39
- package/dist/protocols/evm/morpho/index.cjs.map +1 -1
- package/dist/protocols/evm/morpho/index.d.ts +161 -14
- package/dist/protocols/evm/morpho/index.js +736 -42
- package/dist/protocols/evm/morpho/index.js.map +1 -1
- package/dist/protocols/evm/permit2/index.cjs +66 -59
- package/dist/protocols/evm/permit2/index.cjs.map +1 -1
- package/dist/protocols/evm/permit2/index.js +66 -59
- package/dist/protocols/evm/permit2/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +63 -56
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.d.ts +1 -1
- package/dist/protocols/evm/uniswap-v4/index.js +63 -56
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/package.json +20 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aerodrome
|
|
3
|
+
description: Aerodrome AMM on Base — Sugar discovery, swaps, basic LP, Slipstream CL, gauges, and MPC multisign.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Aerodrome (MCP)
|
|
7
|
+
|
|
8
|
+
Aerodrome is **Base-only (`chainId` 8453)**. Reads use the on-chain **LpSugar** aggregator. Writes build unsigned EVM batches (optional ERC-20 approve + Router / NFPM / gauge) for Continuum MPC.
|
|
9
|
+
|
|
10
|
+
Native ETH in the app and MCP is **`0x0000000000000000000000000000000000000000`**. Map to WETH (`0x4200000000000000000000000000000000000006`) at the Sugar/router boundary. Do not pass Curve’s `0xeeee…` placeholder.
|
|
11
|
+
|
|
12
|
+
## Quote first (Coinbase B20 / AAPLc)
|
|
13
|
+
|
|
14
|
+
**Do not** dump listed tokens or `ctm_aerodrome_fetch_pools`. There is no Sugar token directory on MCP. Tickers resolve inside quote / discover.
|
|
15
|
+
|
|
16
|
+
For a price, **call `ctm_aerodrome_quote` immediately**:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ctm_aerodrome_quote({ chainId: 8453, tokenIn: "USDC", tokenOut: "AAPLc", amountHuman: "1000" })
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `tokenIn` / `tokenOut` accept **tickers** (`AAPLc`, `USDC`, `ETH`, `WETH`, `AERO`) or 0x addresses. Do **not** ask the user for a B20 contract address.
|
|
23
|
+
- B20 stocks are **8 decimals**. Omit `tokenInDecimals`.
|
|
24
|
+
- Quote output includes `amountOutHuman` and `priceImpactPercent` (0–100, vs a tiny same-route probe; `null` if the probe failed). State both before building a swap.
|
|
25
|
+
- To see **which pools exist** for a token (not a price): `ctm_aerodrome_discover_pools({ token: "AAPLc" })` — factory `getPool` vs USDC/WETH/AERO (optional `tokenOut`). Then quote.
|
|
26
|
+
|
|
27
|
+
Use `get_defi_protocol_supported_tokens` only as a slim ticker list (ETH, USDC, AERO, B20). `issued` for a stock is `totalSupply > 0` on quote/discover (unissued throws).
|
|
28
|
+
|
|
29
|
+
## Before writes
|
|
30
|
+
|
|
31
|
+
1. `load_defi_protocol({ protocolId: "aerodrome" })` — activates **market-data** (includes quote)
|
|
32
|
+
2. `get_defi_protocol_supported_chains` — must include 8453 with a node `rpcGateway`
|
|
33
|
+
3. Writes: `activate_tool_group` with `aerodrome:swap`, `aerodrome:lp`, or `aerodrome:rewards`
|
|
34
|
+
|
|
35
|
+
`aerodrome:trading` expands to swaps + lp + rewards (not market-data).
|
|
36
|
+
|
|
37
|
+
## Confirm before creating a sign request
|
|
38
|
+
|
|
39
|
+
After the quote (include `amountOutHuman` and `priceImpactPercent`), **stop and ask** before any `ctm_aerodrome_build_*_multisign`:
|
|
40
|
+
|
|
41
|
+
1. `get_multi_sign_gas_options({ chainId: 8453 })` — confirm `useCustomGas` **false** (live RPC, default) vs **true** (Custom Gas Config from the chain registry).
|
|
42
|
+
2. Confirm the **30-minute** multiSignRequest deadline (members must agree, Get Sig, and broadcast before it expires). The on-chain router/NFPM deadline uses the same window. Omit `expiryDate` for 30 minutes; pass `expiryDate` as unix seconds only if they choose a different window.
|
|
43
|
+
|
|
44
|
+
Do not create the request until they confirm both.
|
|
45
|
+
|
|
46
|
+
## Tool packs
|
|
47
|
+
|
|
48
|
+
| Pack | Tools | Sign request? |
|
|
49
|
+
|------|-------|----------------|
|
|
50
|
+
| market-data | `ctm_aerodrome_discover_pools`, `ctm_aerodrome_quote`, `ctm_aerodrome_fetch_positions`, `ctm_aerodrome_fetch_pools` (Sugar dump — avoid) | No |
|
|
51
|
+
| swaps | `ctm_aerodrome_build_swap_multisign` | Yes |
|
|
52
|
+
| lp | `quote_add_liquidity`, `quote_cl_deposit`, add/remove liquidity, CL mint/increase/decrease/burn, gauge stake/unstake | Quotes no; builds yes |
|
|
53
|
+
| rewards | claim fees, CL collect, claim emissions | Yes |
|
|
54
|
+
|
|
55
|
+
## Liquidity (dialog parity)
|
|
56
|
+
|
|
57
|
+
Same as the Multi-Sign Liquidity tab:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
ctm_aerodrome_quote_add_liquidity({ chainId: 8453, tokenA: "ETH", tokenB: "USDC", amountAHuman: "0.01" })
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- One-sided: pass **either** `amountAHuman` or `amountBHuman`. The other side is filled from the current vAMM/sAMM reserves, or from Slipstream `slot0` when there is no v2 pool.
|
|
64
|
+
- Tickers work (`AAPLc`, `USDC`, `ETH`). B20 stocks are 8 decimals. Unissued stocks (`totalSupply == 0`) error the same as the dialog.
|
|
65
|
+
- **ETH / Coinbase stock has no pool.** `seedable` is `false` and `hint` tells you to pair the stock vs **USDC**. Do not first-deposit an empty vAMM.
|
|
66
|
+
- `kind: "cl"` means the ratio came from Slipstream. `ctm_aerodrome_build_add_liquidity_multisign` is **v2 only** — use `ctm_aerodrome_quote_cl_deposit` + `ctm_aerodrome_build_cl_mint_multisign` for that pool. AAPLc/USDC also has a small vAMM if you want basic LP.
|
|
67
|
+
|
|
68
|
+
## Rewards (dialog parity)
|
|
69
|
+
|
|
70
|
+
Same as the Multi-Sign Rewards tab. **Start with** `ctm_aerodrome_fetch_positions` (account / keyGen). Rows are labeled (`vAMM-USDC/AERO`, `CL #id`) and dust-filtered.
|
|
71
|
+
|
|
72
|
+
| Dialog radio | Tool | Argument |
|
|
73
|
+
|--------------|------|----------|
|
|
74
|
+
| Fees from the pool | `ctm_aerodrome_build_claim_fees_multisign` | `pool` = `claimFees.pool` (`lp`) |
|
|
75
|
+
| Emissions from the gauge in AERO | `ctm_aerodrome_build_claim_emissions_multisign` | `gauge` = `claimEmissions.gauge`; Slipstream staked also needs `tokenId` + `cl: true` |
|
|
76
|
+
|
|
77
|
+
Skip emissions when `claimEmissions` is `null` (no gauge). Slipstream unstaked fees use `ctm_aerodrome_build_cl_collect_fees_multisign` with the NFT `id`.
|
|
78
|
+
|
|
79
|
+
## Native ETH
|
|
80
|
+
|
|
81
|
+
| Phase | tokenIn / tokenA |
|
|
82
|
+
|-------|------------------|
|
|
83
|
+
| Quote / build | `0x0` or `eth` for native; ticker or ERC-20 otherwise |
|
|
84
|
+
|
|
85
|
+
## Addresses
|
|
86
|
+
|
|
87
|
+
Loaded from official GitHub (`velodrome-finance/sugar` `deployments/base.env` and `aerodrome-finance/docs` security.mdx) with baked fallbacks. Do not invent addresses.
|
|
88
|
+
|
|
89
|
+
Coinbase B20 stocks (AAPLc, NVDAc, METAc, GOOGLc, SPCXc, …) trade on **Slipstream 3** (`clFactory3`) vs USDC. New official names are picked up from the [Base tokenized-stocks docs](https://docs.base.org/base-chain/asset-issuance/tokenized-stocks-on-base) and from Sugar tokens whose address uses the B20 ASSET prefix `0xb200…`. The docs fetch is optional: if that page is gone or unusable, discovery continues from the seed list + Sugar. `issued` is live `totalSupply() > 0` — do not hard-code unissued tickers. Quotes use factory `getPool` discovery + MixedRouteQuoterV3 (path bitmasks). Sugar `forSwaps` alone misses these pools. Native ETH → stock is typically WETH → USDC → stock.
|
|
90
|
+
|
|
91
|
+
## Out of scope
|
|
92
|
+
|
|
93
|
+
veNFT lock/vote/rebases, Velodrome Superchain, Pool Launcher, incentives.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: compound-v3
|
|
3
|
+
description: Compound III (Comet) lending — supply, withdraw/borrow, repay, claim rewards, optional Bulker.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Compound III (MCP)
|
|
7
|
+
|
|
8
|
+
Each Compound III market is an isolated **Comet**. You always call the **Comet proxy** with the **CometInterface ABI**. Never the implementation or `CometExt` address.
|
|
9
|
+
|
|
10
|
+
| Concept | What it is | Agent needs to know |
|
|
11
|
+
|---------|------------|---------------------|
|
|
12
|
+
| **Comet proxy** | The only market address you call | From `ctm_compound_v3_fetch_markets` → `comet` |
|
|
13
|
+
| **Base asset** | The one asset you earn or borrow | `baseToken` on the market |
|
|
14
|
+
| **Collateral** | Other assets that back a borrow | `assets` where `role = collateral` |
|
|
15
|
+
| **Supply base** | Earn interest | Also **repays** if the account is borrowed |
|
|
16
|
+
| **Withdraw base** | Withdraw supplied base, or **borrow** if undercollateralized | Same `withdraw` tool |
|
|
17
|
+
| **Bulker** | Optional combined `invoke` | Not required for ETH wrap |
|
|
18
|
+
|
|
19
|
+
## Before any action
|
|
20
|
+
|
|
21
|
+
1. `load_defi_protocol({ protocolId: "compound-v3" })`
|
|
22
|
+
2. `get_defi_protocol_skill({ protocolId: "compound-v3" })`
|
|
23
|
+
3. `get_defi_protocol_supported_chains` — intersect with `get_chain_registry` (`rpcGateway` required)
|
|
24
|
+
4. `get_defi_protocol_supported_tokens({ protocolId: "compound-v3", chainId })`
|
|
25
|
+
5. `ctm_compound_v3_fetch_markets` → copy `comet`
|
|
26
|
+
6. `ctm_compound_v3_fetch_account` before withdraw / repay / claim
|
|
27
|
+
|
|
28
|
+
## Tool selection
|
|
29
|
+
|
|
30
|
+
Do **not** web-search Compound III markets, collaterals, or APRs. Load the protocol and use the fetch tools below.
|
|
31
|
+
|
|
32
|
+
| User intent | MCP tool |
|
|
33
|
+
|-------------|----------|
|
|
34
|
+
| List markets / what can I borrow against X | `ctm_compound_v3_fetch_markets` |
|
|
35
|
+
| Market detail (CFs, prices, APR) | `ctm_compound_v3_fetch_market` |
|
|
36
|
+
| Position + liquidation risk + claimable | `ctm_compound_v3_fetch_account` |
|
|
37
|
+
| Supply collateral or base (earn / repay) | `ctm_compound_v3_build_supply_multisign` |
|
|
38
|
+
| Withdraw or borrow base | `ctm_compound_v3_build_withdraw_multisign` |
|
|
39
|
+
| Repay debt | `ctm_compound_v3_build_repay_multisign` |
|
|
40
|
+
| Claim COMP / rewards | `ctm_compound_v3_build_claim_rewards_multisign` |
|
|
41
|
+
| Combined actions | `ctm_compound_v3_build_bulker_multisign` |
|
|
42
|
+
|
|
43
|
+
## Common write inputs
|
|
44
|
+
|
|
45
|
+
| Field | Required | Notes |
|
|
46
|
+
|-------|----------|-------|
|
|
47
|
+
| `keyGenId` | yes | Preferred KeyGen |
|
|
48
|
+
| `chainId` | yes | EVM chain id |
|
|
49
|
+
| `purposeText` | yes | Human-readable reason |
|
|
50
|
+
| `comet` | yes | **Proxy** from fetch_markets |
|
|
51
|
+
| `asset` | yes (except claim) | Token; native ETH = `0x000…000` |
|
|
52
|
+
| `amountHuman` | yes (except claim) | Human amount |
|
|
53
|
+
| `isNative` | no | Wrap/unwrap ETH automatically |
|
|
54
|
+
| `useCustomGas` | no | Chain registry gas |
|
|
55
|
+
|
|
56
|
+
## ETH wrap / unwrap (automatic)
|
|
57
|
+
|
|
58
|
+
If the user supplies or withdraws **native ETH** (`asset` is the zero address, or `isNative: true`):
|
|
59
|
+
|
|
60
|
+
- **Without Bulker:** `WETH.deposit` → approve → `Comet.supply` on the way in; `Comet.withdraw` → `WETH.withdraw` on the way out.
|
|
61
|
+
- **With Bulker:** native legs use `ACTION_SUPPLY_NATIVE_TOKEN` / `ACTION_WITHDRAW_NATIVE_TOKEN`.
|
|
62
|
+
|
|
63
|
+
Do **not** ask the user to wrap first. Do **not** require `useBulker` for ETH.
|
|
64
|
+
|
|
65
|
+
## Workflows
|
|
66
|
+
|
|
67
|
+
### What can I borrow against an asset (read-only)
|
|
68
|
+
|
|
69
|
+
Example: “What assets can I borrow against USDC on Ethereum using Compound III?”
|
|
70
|
+
|
|
71
|
+
1. `load_defi_protocol({ protocolId: "compound-v3" })` then `get_defi_protocol_skill`.
|
|
72
|
+
2. `ctm_compound_v3_fetch_markets` with `chainId` 1 (Ethereum). Do not guess collaterals from the web.
|
|
73
|
+
3. Each Comet has **one borrowable base** and a list of **collateral** assets (`role`).
|
|
74
|
+
- “Borrow **against** USDC” → markets where USDC is `role = collateral`. The **base** of those markets is what you can borrow (e.g. cWETHv3 → WETH).
|
|
75
|
+
- “Borrow USDC” / “collateral to borrow USDC” → the market whose base is USDC (`cUSDCv3`). Assets with `role = collateral` are accepted collateral.
|
|
76
|
+
4. `ctm_compound_v3_fetch_market` on the chosen `comet` for collateral factors and APRs.
|
|
77
|
+
|
|
78
|
+
### Earn (supply base)
|
|
79
|
+
|
|
80
|
+
1. `ctm_compound_v3_fetch_markets` — pick the Comet whose `baseToken` matches the token.
|
|
81
|
+
2. `ctm_compound_v3_build_supply_multisign` with that `comet`, `asset`, `amountHuman`.
|
|
82
|
+
|
|
83
|
+
### Borrow
|
|
84
|
+
|
|
85
|
+
1. Supply collateral first (`build_supply_multisign` with a collateral `asset`).
|
|
86
|
+
2. `ctm_compound_v3_fetch_account` — confirm `isBorrowCollateralized` and not `isLiquidatable`.
|
|
87
|
+
3. `ctm_compound_v3_build_withdraw_multisign` with `asset` = **base token**. That withdraw **is** the borrow.
|
|
88
|
+
|
|
89
|
+
### Repay then withdraw collateral
|
|
90
|
+
|
|
91
|
+
1. `ctm_compound_v3_build_repay_multisign` (`asset` = base).
|
|
92
|
+
2. `ctm_compound_v3_build_withdraw_multisign` (`asset` = collateral).
|
|
93
|
+
|
|
94
|
+
### Combined (optional Bulker)
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"keyGenId": "<keygen-id>",
|
|
99
|
+
"chainId": 1,
|
|
100
|
+
"purposeText": "Supply WETH collateral and borrow USDC on Compound III",
|
|
101
|
+
"comet": "0xc3d688B66703497DAA19211EEdff47f25384cdc3",
|
|
102
|
+
"steps": [
|
|
103
|
+
{ "action": "supply", "asset": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "amountHuman": "0.1" },
|
|
104
|
+
{ "action": "withdraw", "asset": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "amountHuman": "100" }
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Example: supply 0.001 ETH on Ethereum cWETHv3
|
|
110
|
+
|
|
111
|
+
```json
|
|
112
|
+
{
|
|
113
|
+
"keyGenId": "<keygen-id>",
|
|
114
|
+
"chainId": 1,
|
|
115
|
+
"purposeText": "Supply 0.001 ETH to Compound III cWETHv3",
|
|
116
|
+
"useCustomGas": true,
|
|
117
|
+
"comet": "0xA17581A9E3356d9A858b789D68B4d866e593aE94",
|
|
118
|
+
"asset": "0x0000000000000000000000000000000000000000",
|
|
119
|
+
"amountHuman": "0.001"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Troubleshooting
|
|
124
|
+
|
|
125
|
+
| Symptom | Cause | Fix |
|
|
126
|
+
|---------|--------|-----|
|
|
127
|
+
| Unknown Comet | Guessed implementation address | Use `comet` from fetch_markets |
|
|
128
|
+
| Not collateralized | Withdraw/borrow exceeds CF | Supply more collateral or repay |
|
|
129
|
+
| Native max unwrap | `amountHuman: "max"` + ETH out | Pass an explicit amount |
|
|
130
|
+
| No RPC | Chain not in node registry | Add the chain with `rpcGateway` |
|
|
131
|
+
|
|
132
|
+
Supported live chains: Ethereum, Base, Arbitrum, Optimism, Polygon, Mantle, Unichain, Linea.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: continuum-dao
|
|
3
|
+
description: ContinuumDAO CTM lock, veCTM escrow, node attach, and Linea governance (Bravo/Delta propose, vote, execute, cancel).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ContinuumDAO (MCP)
|
|
7
|
+
|
|
8
|
+
## Chains
|
|
9
|
+
|
|
10
|
+
- **Linea (59144) / Linea Sepolia (59141)** — create lock, escrow actions, attach veCTM, request detach, and governance.
|
|
11
|
+
- **Ethereum mainnet (`chainId: 1`)** — CTM hold/transfer only. Governance is Linea-only.
|
|
12
|
+
|
|
13
|
+
Addresses are placeholders until CTM / VotingEscrow / NodeProperties / Rewards / Governor are redeployed. Prefer live `GET https://app-api.continuumdao.org/protocol/dao|ve|networks` and pass `governor` when the constant is still zero. Do not submit write tools until the target address is non-zero.
|
|
14
|
+
|
|
15
|
+
## Billing
|
|
16
|
+
|
|
17
|
+
These tools build protocol batches only. Do **not** prepend MPA billing legs (`register`, `deposit`, `syncBilling`). Fee payment stays on Compose / credit modals.
|
|
18
|
+
|
|
19
|
+
## Governance encoding
|
|
20
|
+
|
|
21
|
+
One contract: `ContinuumDAO.propose`. Bravo vs Delta is encoding, not a separate function. Five UI types (Admin / Constitution / Decision / Election / Treasury) are backend tags; their **meaning** is the Constitution section **ContinuumDAO Proposals and Voting** (`get_continuum_doc` path `ContinuumDAO/Governance/Constitution`, `sectionId` `continuumdao-proposals-and-voting`). Load **`continuum-dao-proposal-standards`** and apply that fetch before choosing a type or appraising a proposal.
|
|
22
|
+
|
|
23
|
+
- **Bravo:** `targets[] / values[] / calldatas[]` are the actions; on-chain `description` is the title. Empty user actions insert one succeeding no-op (`target = KeyGen ETH`, `value = 0`, `calldata = 0x`) so `targets.length >= 1` and `targets[0] != address(0)`.
|
|
24
|
+
- **Delta:** slot 0 is metadata (`targets[0]=0`, `values[0]=0`, `calldatas[0]` = nOptions, nWinners, 1-indexed option starts). Remaining slots are flattened option actions. Empty options get the same no-op so start indices increment. Option **label** is required. Backend payload stores `actions: []` for empty options (user actions only).
|
|
25
|
+
- **Delta vote:** `weights` must be **nOptions + 1**. The last slot is baked-in NOTA. Do not ship nOptions-only params.
|
|
26
|
+
- **Queue is not implemented.** `queue()` reverts. Execute from `Succeeded`.
|
|
27
|
+
|
|
28
|
+
After a propose multi-sign request is **mined**, call `ctm_continuum_dao_register_proposal` (`POST /proposals/create`) so [app.continuumdao.org/governance](https://app.continuumdao.org/governance) stays in sync. If the POST fails, retry — do not revert the chain tx. `onchainId` comes from `hashProposal` or `ProposalCreated`.
|
|
29
|
+
|
|
30
|
+
`load_defi_protocol({ protocolId: "continuum-dao" })` loads escrow, attach, and governance together.
|
|
31
|
+
|
|
32
|
+
## Chat: “What proposals are live now?”
|
|
33
|
+
|
|
34
|
+
Do **not** answer from `ctm_continuum_dao_fetch_proposals` or backend `status` alone.
|
|
35
|
+
|
|
36
|
+
1. `load_defi_protocol({ protocolId: "continuum-dao" })` if not already loaded.
|
|
37
|
+
2. `ctm_continuum_dao_fetch_live_proposals({ chainId: 59144, rpcUrl })` (Linea Sepolia: `59141`). Get `rpcUrl` from the chain registry. Pass `governor` when the constant is still zero (from `GET https://app-api.continuumdao.org/protocol/dao`).
|
|
38
|
+
3. Read the returned `note`, then the buckets:
|
|
39
|
+
- **`live`** — `state === Active` (voting now). This is the answer to “live now.”
|
|
40
|
+
- **`pending`** — proposed, voting has not started.
|
|
41
|
+
- **`readyToExecute`** — `Succeeded`. No queue. Offer `ctm_continuum_dao_build_execute_multisign`.
|
|
42
|
+
- **`recentlyCompleted`** — Canceled / Defeated / Expired / Executed in this scan.
|
|
43
|
+
- **`unknown`** — no on-chain overlay (missing governor/RPC, or a failed `state` read). Do not call these live.
|
|
44
|
+
4. If `overlay` is `backend-only`, say you could not confirm live Governor state.
|
|
45
|
+
|
|
46
|
+
For one proposal, call `ctm_continuum_dao_explain_proposal` and read `briefing` aloud (every action / Delta option, no-ops labeled signaling, C3 called out). Do not vote from this protocol skill.
|
|
47
|
+
|
|
48
|
+
Operator presentation and vote policy live in the node catalogue (mpc-config): load skills **`continuum-dao-proposals`** and **`continuum-dao-vote-policy`** via `agent_load_skill`. To **create** a proposal in chat, load **`continuum-dao-compose-proposal`** (interactive only). Cron must never propose or load that skill — vote and governor Join only.
|
|
49
|
+
|
|
50
|
+
When a proposal has a `forumKey`, fetch that thread (`ctm_continuum_dao_forum_resolve` then `forum_fetch_thread` / `forum_fetch_post`) before voting. Check `section` on the thread against the proposal type. List recent posts with `forum_recent` (`hours` or `since`; privilege-filtered, whole forum; id, title, username, createdAt), or find matching posts with `forum_search` (title of a new thread or body text, case-insensitive; optional `hours` / `since`), then `forum_fetch_post` on a returned `id`. Walk a user's posts with `forum_user_post_ids` then `forum_fetch_post`. Writes need a `ticket` from forum EIP-712 login. `forum_unread` / `forum_mark_read` / `forum_mark_unread` are **interactive inbox** tools (NodeBB Unread is per topic). Confirm before `forum_mark_read` with `all: true`. `forum_delete` is **admin/moderator only** (not the post owner): exactly one of `pid`, `tid`/`url`, or `username`; optional `hours` / `since` (default all). Confirm with the operator before deleting. Never from cron.
|
|
51
|
+
|
|
52
|
+
**Classify first: Idea vs formal proposal.** An Idea/Suggestion is early discussion or feedback — not a Temperature Check. Post it with `forum_create_idea`. Do **not** use that URL as `forumKey`. A formal proposal belongs in a **Governance** section and must go on-chain.
|
|
53
|
+
|
|
54
|
+
| Type | Forum `section` | Typical vote |
|
|
55
|
+
|------|-----------------|--------------|
|
|
56
|
+
| Decision | `decision` | Bravo |
|
|
57
|
+
| Election | `election` | Delta |
|
|
58
|
+
| Treasury | `treasury` | Bravo |
|
|
59
|
+
| Constitution | `constitution` | Bravo (include the new Constitution text) |
|
|
60
|
+
| Admin | `admin` | Bravo |
|
|
61
|
+
|
|
62
|
+
**A proposal MUST have a Governance forum thread.** Never call `build_propose_*` or `register_proposal` with the homepage, an empty `forumKey`, or an Ideas thread. Required agent order:
|
|
63
|
+
|
|
64
|
+
1. `forum_sign_in_eligible` then `build_forum_sign_in_multisign` (if no ticket).
|
|
65
|
+
2. If it is only an idea: `forum_create_idea`. Stop (no propose).
|
|
66
|
+
3. If it is a proposal: `forum_create_topic` with the matching Governance `section` (proposal-threshold veCTM). Keep the returned `url`.
|
|
67
|
+
4. `build_propose_bravo_multisign` or `build_propose_delta_multisign` with that `url` as `forumKey`.
|
|
68
|
+
5. After the propose tx is mined, `register_proposal` with the same `forumKey`.
|
|
69
|
+
|
|
70
|
+
`forumKey` must match `/topic/:tid` or `/t/:tid` on forum.continuumdao.org. Builders and `register_proposal` throw otherwise.
|
|
71
|
+
|
|
72
|
+
Forum KeyGen sign-in is EIP-712 multi-sign (no EVM tx). Always check eligibility first:
|
|
73
|
+
|
|
74
|
+
1. `ctm_continuum_dao_forum_sign_in_eligible({ address })` — holder or attach-key veCTM vs `veCtmThresholdPower`. If `eligible` is false, stop. Do **not** compose a multi-sign request.
|
|
75
|
+
2. `ctm_continuum_dao_build_forum_sign_in_multisign` also refuses ineligible addresses (same gate) so other nodes never enter the sign loop. Pass `nodeKey` (username = first 16 chars) or a `username` on first login.
|
|
76
|
+
3. After the multi-sign request is signed, exchange the signature for a ticket (`/api/continuum/eip712/ticket`). Then `forum_reply` / `forum_react` / `forum_create_topic` / `forum_create_idea`.
|
|
77
|
+
4. `ctm_continuum_dao_forum_sign_out({ ticket })` revokes the ticket and forum sessions. No multi-sign.
|
|
78
|
+
|
|
79
|
+
Forum sign-in and sign-out are **agent/MCP only**. There is no Sign in / Sign out control in the node-app Compose header.
|
|
80
|
+
|
|
81
|
+
Propose builders read live `proposalThreshold()` and refuse if `getVotes(KeyGen) < threshold`. On-chain rule (vectm `ContinuumDAO`): `max(1000 ether, 1% of past total voting power)`. Do not hardcode `1000`.
|
|
82
|
+
|
|
83
|
+
## Tools
|
|
84
|
+
|
|
85
|
+
| Intent | Tool |
|
|
86
|
+
|--------|------|
|
|
87
|
+
| Create lock | `ctm_continuum_dao_build_create_lock_multisign` |
|
|
88
|
+
| Increase amount | `ctm_continuum_dao_build_increase_amount_multisign` |
|
|
89
|
+
| Increase unlock time | `ctm_continuum_dao_build_increase_unlock_time_multisign` |
|
|
90
|
+
| Split | `ctm_continuum_dao_build_split_multisign` |
|
|
91
|
+
| Merge | `ctm_continuum_dao_build_merge_multisign` |
|
|
92
|
+
| Withdraw | `ctm_continuum_dao_build_withdraw_multisign` |
|
|
93
|
+
| Liquidate | `ctm_continuum_dao_build_liquidate_multisign` |
|
|
94
|
+
| Delegate | `ctm_continuum_dao_build_delegate_multisign` |
|
|
95
|
+
| Undelegate (delegate to self) | `ctm_continuum_dao_build_undelegate_multisign` |
|
|
96
|
+
| Fetch current delegatee | `ctm_continuum_dao_fetch_delegates` |
|
|
97
|
+
| Transfer NFT | `ctm_continuum_dao_build_transfer_multisign` |
|
|
98
|
+
| Attach veCTM | `ctm_continuum_dao_build_attach_multisign` |
|
|
99
|
+
| Request detach | `ctm_continuum_dao_build_request_detach_multisign` |
|
|
100
|
+
| Propose Bravo | `ctm_continuum_dao_build_propose_bravo_multisign` |
|
|
101
|
+
| Propose Delta | `ctm_continuum_dao_build_propose_delta_multisign` |
|
|
102
|
+
| Vote Bravo | `ctm_continuum_dao_build_cast_vote_bravo_multisign` |
|
|
103
|
+
| Vote Delta (+ NOTA) | `ctm_continuum_dao_build_cast_vote_delta_multisign` |
|
|
104
|
+
| Execute | `ctm_continuum_dao_build_execute_multisign` |
|
|
105
|
+
| Cancel | `ctm_continuum_dao_build_cancel_multisign` |
|
|
106
|
+
| Register proposal (backend) | `ctm_continuum_dao_register_proposal` |
|
|
107
|
+
| Fetch live / pending / executable | `ctm_continuum_dao_fetch_live_proposals` |
|
|
108
|
+
| Explain / deconstruct one proposal | `ctm_continuum_dao_explain_proposal` |
|
|
109
|
+
| Fetch raw backend list | `ctm_continuum_dao_fetch_proposals` |
|
|
110
|
+
| Fetch one proposal | `ctm_continuum_dao_fetch_proposal` |
|
|
111
|
+
| Fetch on-chain state | `ctm_continuum_dao_fetch_proposal_state` |
|
|
112
|
+
| Fetch voting power | `ctm_continuum_dao_fetch_voting_power` |
|
|
113
|
+
| Forum sign-in eligible? | `ctm_continuum_dao_forum_sign_in_eligible` |
|
|
114
|
+
| Forum KeyGen sign-in | `ctm_continuum_dao_build_forum_sign_in_multisign` |
|
|
115
|
+
| Forum sign-out | `ctm_continuum_dao_forum_sign_out` |
|
|
116
|
+
| Resolve forum URL | `ctm_continuum_dao_forum_resolve` |
|
|
117
|
+
| Fetch forum thread | `ctm_continuum_dao_forum_fetch_thread` |
|
|
118
|
+
| Fetch one forum post | `ctm_continuum_dao_forum_fetch_post` |
|
|
119
|
+
| Search forum (title/body, optional recency) | `ctm_continuum_dao_forum_search` |
|
|
120
|
+
| Recent forum posts (id, title, username, createdAt; hours / since) | `ctm_continuum_dao_forum_recent` |
|
|
121
|
+
| Admin/mod delete post, thread, or user posts | `ctm_continuum_dao_forum_delete` |
|
|
122
|
+
| User post ids | `ctm_continuum_dao_forum_user_post_ids` |
|
|
123
|
+
| Forum reply count | `ctm_continuum_dao_forum_reply_count` |
|
|
124
|
+
| Forum reply | `ctm_continuum_dao_forum_reply` |
|
|
125
|
+
| Forum react | `ctm_continuum_dao_forum_react` |
|
|
126
|
+
| Create Governance proposal thread | `ctm_continuum_dao_forum_create_topic` |
|
|
127
|
+
| Post Idea / Suggestion | `ctm_continuum_dao_forum_create_idea` |
|
|
128
|
+
| Forum unread topics | `ctm_continuum_dao_forum_unread` |
|
|
129
|
+
| Forum mark topic read | `ctm_continuum_dao_forum_mark_read` |
|
|
130
|
+
| Forum mark topic unread | `ctm_continuum_dao_forum_mark_unread` |
|
|
131
|
+
| Forum me / sections | `ctm_continuum_dao_forum_me` / `ctm_continuum_dao_forum_sections` |
|
|
132
|
+
|
|
133
|
+
Attach requires the claimed `nodeWithdrawAuthority` KeyGen that owns the NFT. `groupId` is implicit from that KeyGen. You cannot replace an attached NFT — only governance detaches after `request detach`.
|
|
134
|
+
|
|
135
|
+
Attached locks block transfer / merge / split / withdraw on-chain (`checkNotAttached`).
|
|
136
|
+
|
|
137
|
+
Propose and vote use `getVotes` at the **KeyGen** address. If the KeyGen has delegated away (`fetch_delegates` → `self: false`), that power sits with the delegatee until `build_undelegate_multisign` (on-chain this is `delegate(self)`; there is no `undelegate()`). Attach-to-node is unrelated. Propose requires `getVotes(keyAddress) >= proposalThreshold()`. The live threshold is `max(1000e18 ve power, 1% of total voting power)`, not a flat 1000. `ctm_continuum_dao_build_propose_*` throws if the KeyGen is below the live bar.
|
|
138
|
+
|
|
139
|
+
All `ctm_continuum_dao_build_*_multisign` tools return `{ requestId }` on success (shared gas/submit section appended by the server).
|
|
@@ -66,14 +66,17 @@ Do **not** use `ctm_arcus_build_deposit_multisign` for yield — that funds perp
|
|
|
66
66
|
|
|
67
67
|
## Morpho Midnight (fixed rate / fixed term)
|
|
68
68
|
|
|
69
|
-
Midnight is a separate order-book primitive (not Blue). Users **take** existing offers via MidnightBundles. Launch liquidity is strongest on **Base (8453)** (e.g. cbBTC/USDC maturities).
|
|
69
|
+
Midnight is a separate order-book primitive (not Blue). Users can **take** existing offers via MidnightBundles, or **post a lend offer** that parks the loan token in Morpho Blue (variable yield) until a borrower fills it. Launch liquidity is strongest on **Base (8453)** (e.g. cbBTC/USDC maturities).
|
|
70
70
|
|
|
71
71
|
| Goal | Tool |
|
|
72
72
|
|------|------|
|
|
73
73
|
| List books | `ctm_morpho_fetch_midnight_books({ chainId: 8453, loan?, collateral?, side? })` |
|
|
74
74
|
| Preview fill | `ctm_morpho_fetch_midnight_quote({ marketId, side: "asks"\|"bids", assets })` |
|
|
75
75
|
| User positions | `ctm_morpho_fetch_midnight_positions({ user })` |
|
|
76
|
-
|
|
|
76
|
+
| Open lend offers | `ctm_morpho_fetch_midnight_offers({ user, chainId? })` |
|
|
77
|
+
| Lend now (take asks) | `ctm_morpho_build_midnight_lend_multisign` |
|
|
78
|
+
| Lend offer (earn until filled) | `ctm_morpho_build_midnight_lend_offer_multisign` |
|
|
79
|
+
| Cancel lend offer + withdraw unused | `ctm_morpho_build_midnight_cancel_lend_offer_multisign` |
|
|
77
80
|
| Borrow (collateral + take bids) | `ctm_morpho_build_midnight_borrow_multisign` |
|
|
78
81
|
| Repay + withdraw collateral | `ctm_morpho_build_midnight_repay_multisign` |
|
|
79
82
|
|
|
@@ -81,11 +84,13 @@ Workflow:
|
|
|
81
84
|
|
|
82
85
|
1. `ctm_morpho_fetch_midnight_books` — pick `marketId`, note `loanTokenAddress` / `primaryCollateralTokenAddress`, `lendApr` / `borrowApr`, maturity.
|
|
83
86
|
2. Optional: `ctm_morpho_fetch_midnight_quote` with raw `assets` (loan token base units).
|
|
84
|
-
3.
|
|
85
|
-
4.
|
|
86
|
-
5.
|
|
87
|
+
3. Immediate lend: `ctm_morpho_build_midnight_lend_multisign({ marketId, amountHuman, … })`.
|
|
88
|
+
4. Limit lend that earns while waiting: `ctm_morpho_build_midnight_lend_offer_multisign({ marketId, amountHuman, lendAprPct? })`. Funds are supplied to the deepest Blue market for that loan token via BlueBuyCallback.
|
|
89
|
+
5. Borrow: `ctm_morpho_build_midnight_borrow_multisign({ marketId, borrowAmountHuman, collateralAmountHuman, collateralToken, … })`.
|
|
90
|
+
6. Exit a matched borrow: `ctm_morpho_fetch_midnight_positions` → `ctm_morpho_build_midnight_repay_multisign({ marketId })`.
|
|
91
|
+
7. Cancel an unfilled offer: `ctm_morpho_fetch_midnight_offers` → `ctm_morpho_build_midnight_cancel_lend_offer_multisign({ group, callback, callbackData })`.
|
|
87
92
|
|
|
88
|
-
Server re-quotes at build time and fills `taker` / `onBehalf` from the executor.
|
|
93
|
+
Server re-quotes at build time and fills `taker` / `maker` / `onBehalf` from the executor.
|
|
89
94
|
|
|
90
95
|
## MCP multisign tools
|
|
91
96
|
|
|
@@ -96,13 +101,16 @@ Server re-quotes at build time and fills `taker` / `onBehalf` from the executor.
|
|
|
96
101
|
| `ctm_morpho_fetch_midnight_books` | List Midnight books |
|
|
97
102
|
| `ctm_morpho_fetch_midnight_quote` | Quote Midnight fill |
|
|
98
103
|
| `ctm_morpho_fetch_midnight_positions` | Midnight positions |
|
|
104
|
+
| `ctm_morpho_fetch_midnight_offers` | Open Midnight lend offers |
|
|
99
105
|
| `ctm_morpho_build_vault_deposit_multisign` | Vault deposit (listed V1 or V2) |
|
|
100
106
|
| `ctm_morpho_build_vault_withdraw_multisign` | Vault withdraw |
|
|
101
107
|
| `ctm_morpho_build_blue_collateral_deposit_multisign` | Blue supplyCollateral |
|
|
102
108
|
| `ctm_morpho_build_blue_borrow_multisign` | Blue borrow |
|
|
103
109
|
| `ctm_morpho_build_blue_repay_multisign` | Blue repay |
|
|
104
110
|
| `ctm_morpho_build_blue_collateral_withdraw_multisign` | Blue withdrawCollateral |
|
|
105
|
-
| `ctm_morpho_build_midnight_lend_multisign` | Midnight lend |
|
|
111
|
+
| `ctm_morpho_build_midnight_lend_multisign` | Midnight lend now (take asks) |
|
|
112
|
+
| `ctm_morpho_build_midnight_lend_offer_multisign` | Midnight lend offer (Blue yield until filled) |
|
|
113
|
+
| `ctm_morpho_build_midnight_cancel_lend_offer_multisign` | Cancel Midnight lend offer |
|
|
106
114
|
| `ctm_morpho_build_midnight_borrow_multisign` | Midnight borrow |
|
|
107
115
|
| `ctm_morpho_build_midnight_repay_multisign` | Midnight repay + withdraw |
|
|
108
116
|
| `ctm_morpho_build_merkl_claim_multisign` | Merkl claim |
|
|
@@ -116,7 +124,7 @@ Pass `marketId` from Morpho API for Blue/Midnight tools (not recomputed on-chain
|
|
|
116
124
|
2. `ctm_morpho_fetch_earn_vaults` — pick `vaultAddress` and `underlyingAddress` by asset and/or name.
|
|
117
125
|
3. `ctm_morpho_build_vault_deposit_multisign` — use each tool’s **input schema** (`keyGenId`, fetch output addresses, `amountHuman`, etc.). Server resolves `keyGen`, `executorAddress`, `rpcUrl`, `chainDetail`; agents must not pass those.
|
|
118
126
|
4. Blue borrow/collateral: `marketId` from Morpho API; server resolves `marketParams`.
|
|
119
|
-
5. Midnight: books → quote → lend
|
|
127
|
+
5. Midnight: books → quote → lend now, lend offer (earn until filled), borrow, or cancel/repay as above.
|
|
120
128
|
|
|
121
129
|
## Troubleshooting
|
|
122
130
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Address, PublicClient } from 'viem';
|
|
2
|
+
import { M as MultisignBuildResult } from './types-PZrvtjv8.js';
|
|
3
|
+
import { f as finalizeMultisign } from './envelope-C_bfuKab.js';
|
|
4
|
+
import { b as EvmTxStep, a as EvmProtocolContext } from './types-RZWOTm8c.js';
|
|
5
|
+
|
|
6
|
+
type EvmBatchMetaBuilder = (args: {
|
|
7
|
+
step: EvmTxStep;
|
|
8
|
+
index: number;
|
|
9
|
+
gasLimit: bigint;
|
|
10
|
+
}) => Record<string, unknown>;
|
|
11
|
+
type EvmBuildBatchArgs = {
|
|
12
|
+
context: EvmProtocolContext;
|
|
13
|
+
steps: EvmTxStep[];
|
|
14
|
+
purposeSuffix?: string;
|
|
15
|
+
buildBatchMeta: EvmBatchMetaBuilder;
|
|
16
|
+
/** First leg msgRaw without 0x prefix; defaults to first step calldata */
|
|
17
|
+
firstMsgRawNo0x?: string;
|
|
18
|
+
destinationAddress?: Address;
|
|
19
|
+
/** Top-level `value` on bodyForSign when the payable amount is not on the first leg */
|
|
20
|
+
payableValueWei?: bigint;
|
|
21
|
+
resolveGasLimit?: (args: {
|
|
22
|
+
step: EvmTxStep;
|
|
23
|
+
index: number;
|
|
24
|
+
estimatedGas: bigint;
|
|
25
|
+
publicClient: PublicClient;
|
|
26
|
+
}) => Promise<bigint> | bigint;
|
|
27
|
+
/** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */
|
|
28
|
+
estimateGasForStep?: (args: {
|
|
29
|
+
step: EvmTxStep;
|
|
30
|
+
index: number;
|
|
31
|
+
publicClient: PublicClient;
|
|
32
|
+
executor: Address;
|
|
33
|
+
}) => Promise<bigint> | bigint;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.
|
|
37
|
+
*/
|
|
38
|
+
declare function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult>;
|
|
39
|
+
declare const evmChainCategoryModule: {
|
|
40
|
+
category: "evm";
|
|
41
|
+
finalizeMultisign: typeof finalizeMultisign;
|
|
42
|
+
buildEvmMultisignBatch: typeof buildEvmMultisignBatch;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { type EvmBatchMetaBuilder as E, type EvmBuildBatchArgs as a, buildEvmMultisignBatch as b, evmChainCategoryModule as e };
|
|
@@ -1,47 +1,9 @@
|
|
|
1
|
-
import { b as EvmTxStep
|
|
2
|
-
export { E as EvmChainDetail, i as isEvmNativeToken, m as matchEvmTokenKind } from '../../types-RZWOTm8c.js';
|
|
1
|
+
import { b as EvmTxStep } from '../../types-RZWOTm8c.js';
|
|
2
|
+
export { E as EvmChainDetail, a as EvmProtocolContext, i as isEvmNativeToken, m as matchEvmTokenKind } from '../../types-RZWOTm8c.js';
|
|
3
|
+
export { E as EvmBatchMetaBuilder, a as EvmBuildBatchArgs, b as buildEvmMultisignBatch, e as evmChainCategoryModule } from '../../buildBatch-CngvebiD.js';
|
|
3
4
|
import { Address, PublicClient } from 'viem';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
type EvmBatchMetaBuilder = (args: {
|
|
8
|
-
step: EvmTxStep;
|
|
9
|
-
index: number;
|
|
10
|
-
gasLimit: bigint;
|
|
11
|
-
}) => Record<string, unknown>;
|
|
12
|
-
type EvmBuildBatchArgs = {
|
|
13
|
-
context: EvmProtocolContext;
|
|
14
|
-
steps: EvmTxStep[];
|
|
15
|
-
purposeSuffix?: string;
|
|
16
|
-
buildBatchMeta: EvmBatchMetaBuilder;
|
|
17
|
-
/** First leg msgRaw without 0x prefix; defaults to first step calldata */
|
|
18
|
-
firstMsgRawNo0x?: string;
|
|
19
|
-
destinationAddress?: Address;
|
|
20
|
-
/** Top-level `value` on bodyForSign when the payable amount is not on the first leg */
|
|
21
|
-
payableValueWei?: bigint;
|
|
22
|
-
resolveGasLimit?: (args: {
|
|
23
|
-
step: EvmTxStep;
|
|
24
|
-
index: number;
|
|
25
|
-
estimatedGas: bigint;
|
|
26
|
-
publicClient: PublicClient;
|
|
27
|
-
}) => Promise<bigint> | bigint;
|
|
28
|
-
/** Override default `estimateGas` (e.g. trade-API gas, skip post-approve deposit estimate). */
|
|
29
|
-
estimateGasForStep?: (args: {
|
|
30
|
-
step: EvmTxStep;
|
|
31
|
-
index: number;
|
|
32
|
-
publicClient: PublicClient;
|
|
33
|
-
executor: Address;
|
|
34
|
-
}) => Promise<bigint> | bigint;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Build unsigned EVM txs, estimate gas, serialize, hash — then assemble mpc-auth body via core envelope.
|
|
38
|
-
*/
|
|
39
|
-
declare function buildEvmMultisignBatch(args: EvmBuildBatchArgs): Promise<MultisignBuildResult>;
|
|
40
|
-
declare const evmChainCategoryModule: {
|
|
41
|
-
category: "evm";
|
|
42
|
-
finalizeMultisign: typeof finalizeMultisign;
|
|
43
|
-
buildEvmMultisignBatch: typeof buildEvmMultisignBatch;
|
|
44
|
-
};
|
|
5
|
+
import '../../types-PZrvtjv8.js';
|
|
6
|
+
import '../../envelope-C_bfuKab.js';
|
|
45
7
|
|
|
46
8
|
/** Parse chain id for comparisons (decimal, 0x hex, CAIP-2 eip155:N, bigint). */
|
|
47
9
|
declare function parseEvmChainIdToNumber(chainId: string | number | bigint | null | undefined): number;
|
|
@@ -91,4 +53,4 @@ declare function coingeckoPlatformForChainId(chainId: string | number): string |
|
|
|
91
53
|
/** Curve router swap gas: chain cap when set, else 12/10 estimate bump. */
|
|
92
54
|
declare function routerSwapGasLimitFromEstimate(estimatedGas: bigint, chainGasLimit?: number | null): bigint;
|
|
93
55
|
|
|
94
|
-
export { COINGECKO_PLATFORM_BY_CHAIN_ID, type ConditionalApproveStep,
|
|
56
|
+
export { COINGECKO_PLATFORM_BY_CHAIN_ID, type ConditionalApproveStep, EvmTxStep, approveStepsToEvmTxSteps, buildConditionalErc20ApproveSteps, coingeckoPlatformForChainId, normalizeCurveRouterAmountString, normalizeHumanDecimalAmount, parseEvmChainIdToNumber, publicClientForRpc, resolveErc20Decimals, routerSwapGasLimitFromEstimate };
|
package/dist/core/index.cjs
CHANGED
|
@@ -182,57 +182,60 @@ function eip712SignatureText(domain, primaryType) {
|
|
|
182
182
|
function jsonStringifyForAudit(value) {
|
|
183
183
|
return JSON.stringify(value, (_, v) => typeof v === "bigint" ? v.toString() : v);
|
|
184
184
|
}
|
|
185
|
-
function
|
|
186
|
-
|
|
185
|
+
function eip712LegEnvelope(typedData, delivery, digest) {
|
|
186
|
+
return {
|
|
187
187
|
version: 1,
|
|
188
|
-
|
|
189
|
-
delivery
|
|
190
|
-
};
|
|
191
|
-
return viem.stringToHex(jsonStringifyForAudit(envelope));
|
|
192
|
-
}
|
|
193
|
-
function buildEip712MultisignBody(args) {
|
|
194
|
-
const { typedData, delivery } = args;
|
|
195
|
-
const digest = viem.hashTypedData({
|
|
188
|
+
digest,
|
|
196
189
|
domain: typedData.domain,
|
|
197
190
|
types: typedData.types,
|
|
198
191
|
primaryType: typedData.primaryType,
|
|
199
|
-
message: typedData.message
|
|
200
|
-
});
|
|
201
|
-
const extraJSON = {
|
|
202
|
-
signRequestKind: EIP712_SIGN_REQUEST_KIND,
|
|
203
|
-
eip712: {
|
|
204
|
-
version: 1,
|
|
205
|
-
digest,
|
|
206
|
-
domain: typedData.domain,
|
|
207
|
-
types: typedData.types,
|
|
208
|
-
primaryType: typedData.primaryType,
|
|
209
|
-
message: typedData.message
|
|
210
|
-
},
|
|
192
|
+
message: typedData.message,
|
|
211
193
|
delivery
|
|
212
194
|
};
|
|
195
|
+
}
|
|
196
|
+
function eip712MsgRawHex(envelope) {
|
|
197
|
+
return viem.stringToHex(jsonStringifyForAudit(envelope));
|
|
198
|
+
}
|
|
199
|
+
function buildEip712Multisign(args) {
|
|
200
|
+
if (args.legs.length < 1) {
|
|
201
|
+
throw new Error("buildEip712Multisign requires at least one leg");
|
|
202
|
+
}
|
|
203
|
+
const eip712 = [];
|
|
204
|
+
const legs = args.legs.map((leg) => {
|
|
205
|
+
const digest = viem.hashTypedData({
|
|
206
|
+
domain: leg.typedData.domain,
|
|
207
|
+
types: leg.typedData.types,
|
|
208
|
+
primaryType: leg.typedData.primaryType,
|
|
209
|
+
message: leg.typedData.message
|
|
210
|
+
});
|
|
211
|
+
const envelope = eip712LegEnvelope(leg.typedData, leg.delivery, digest);
|
|
212
|
+
eip712.push(envelope);
|
|
213
|
+
return {
|
|
214
|
+
msgHash: msgHashNo0x(digest),
|
|
215
|
+
msgRaw: eip712MsgRawHex(envelope),
|
|
216
|
+
destinationAddress: args.destinationAddress,
|
|
217
|
+
signatureText: eip712SignatureText(leg.typedData.domain, leg.typedData.primaryType),
|
|
218
|
+
audit: {
|
|
219
|
+
kind: "EIP712",
|
|
220
|
+
primaryType: leg.typedData.primaryType,
|
|
221
|
+
deliveryKind: leg.delivery.kind,
|
|
222
|
+
...leg.audit ?? {}
|
|
223
|
+
},
|
|
224
|
+
feeSnapshot: {}
|
|
225
|
+
};
|
|
226
|
+
});
|
|
213
227
|
return finalizeMultisign({
|
|
214
228
|
keyGen: args.keyGen,
|
|
215
229
|
purposeText: args.purposeText,
|
|
216
230
|
purposeSuffix: args.purposeSuffix,
|
|
217
231
|
destinationChainID: args.destinationChainID,
|
|
218
232
|
destinationAddress: args.destinationAddress,
|
|
219
|
-
extraJSON
|
|
233
|
+
extraJSON: {
|
|
234
|
+
signRequestKind: EIP712_SIGN_REQUEST_KIND,
|
|
235
|
+
eip712
|
|
236
|
+
},
|
|
220
237
|
expiryDate: args.expiryDate,
|
|
221
|
-
legs
|
|
222
|
-
{
|
|
223
|
-
msgHash: msgHashNo0x(digest),
|
|
224
|
-
msgRaw: eip712MsgRawHex(typedData, delivery),
|
|
225
|
-
destinationAddress: args.destinationAddress,
|
|
226
|
-
signatureText: eip712SignatureText(typedData.domain, typedData.primaryType),
|
|
227
|
-
audit: {
|
|
228
|
-
kind: "EIP712",
|
|
229
|
-
primaryType: typedData.primaryType,
|
|
230
|
-
deliveryKind: delivery.kind,
|
|
231
|
-
...args.audit ?? {}
|
|
232
|
-
},
|
|
233
|
-
feeSnapshot: {}
|
|
234
|
-
}
|
|
235
|
-
]
|
|
238
|
+
legs
|
|
236
239
|
});
|
|
237
240
|
}
|
|
238
241
|
var PAYLOAD_SIGN_ED25519_REQUEST_KIND = "payload_sign_ed25519";
|
|
@@ -295,7 +298,8 @@ var DEFI_PROTOCOLS_WITH_30MIN_EXPIRY = /* @__PURE__ */ new Set([
|
|
|
295
298
|
"gmx",
|
|
296
299
|
"hyperliquid",
|
|
297
300
|
"arcus",
|
|
298
|
-
"curve-dao"
|
|
301
|
+
"curve-dao",
|
|
302
|
+
"aerodrome"
|
|
299
303
|
]);
|
|
300
304
|
function defiMultisignExpiryUnixSeconds(protocolId, explicitExpiryDate) {
|
|
301
305
|
if (typeof explicitExpiryDate === "number" && Number.isFinite(explicitExpiryDate) && explicitExpiryDate > 0) {
|
|
@@ -315,7 +319,7 @@ exports.DEFAULT_DEFI_MULTISIGN_EXPIRY_SECONDS = DEFAULT_DEFI_MULTISIGN_EXPIRY_SE
|
|
|
315
319
|
exports.DEFI_PROTOCOLS_WITH_30MIN_EXPIRY = DEFI_PROTOCOLS_WITH_30MIN_EXPIRY;
|
|
316
320
|
exports.EIP712_SIGN_REQUEST_KIND = EIP712_SIGN_REQUEST_KIND;
|
|
317
321
|
exports.PAYLOAD_SIGN_ED25519_REQUEST_KIND = PAYLOAD_SIGN_ED25519_REQUEST_KIND;
|
|
318
|
-
exports.
|
|
322
|
+
exports.buildEip712Multisign = buildEip712Multisign;
|
|
319
323
|
exports.buildPayloadSignEd25519MultisignBody = buildPayloadSignEd25519MultisignBody;
|
|
320
324
|
exports.coreChainCategoryModule = coreChainCategoryModule;
|
|
321
325
|
exports.defiMultisignExpiryUnixSeconds = defiMultisignExpiryUnixSeconds;
|