Moss 新手教程:从零跑通第一个链上模拟
这份教程带你把 Moss 真正跑起来,用两个官方示例模拟真实的 Monad 链上交易——不需要私钥、不需要有钱包、不需要懂 Solidity。所有命令输出均来自真实运行。
一、Moss 在做一件什么事?
Moss 是一个把 Monad 链上协议封装成”Agent 可调用的能力(Capability)“的框架。它最大的特点是:只构建和模拟交易,绝不签名、绝不发送。
先看它在系统里的位置:
意图发起方
action → simulate
翻译与预演
+ Receipt 证据
状态与执行
Moss 站在 Agent 和链之间:把”人话意图”翻译成”可验证的未签名交易”,模拟后产出 Receipt,但永远不签名、不发送。
一句话:Agent 负责”想做什么”,Moss 负责”翻译成链能懂的话并预演”,钱包负责”真正签字”。 三者分离,Agent 碰不到你的资金。
二、环境准备
Moss 是 TypeScript monorepo,需要两个工具:
| 工具 | 版本 | 检查命令 |
|---|---|---|
| Node.js | ≥ 22 | node --version |
| pnpm | ≥ 11 | pnpm --version |
安装 pnpm:
npm install -g pnpm
三、克隆与安装
git clone https://github.com/<你的用户名>/moss
cd moss
pnpm install
pnpm install 会安装所有 workspace 包(core / erc / protocols / simulator / system / mcp-server)并自动链接。
离线自测(不需要 RPC,验证工具链):
pnpm test:offline
看到测试通过,说明环境就绪。
四、核心四步:discover → load → action → simulate
Moss 的所有操作都遵循同一个工作流。我们从最关键的两个示例入手:examples/simple-flow。
4.1 示例一:WMON wrap
源码 examples/simple-flow/src/wmon-wrap.ts 的逻辑非常清晰,四步一一对应:
// 1. discover:问"有哪些 wrap 能力?"
console.log("1. discover", registry.discover({ verb: "wrap" }));
// 2. load:加载意图、风险标签、参数契约
console.log("2. load", registry.load([{ protocol: "wmon", method: "wrap" }]));
// 3. action:构建未签名交易(Capability 树)
const capability = await registry.action("wmon", "wrap", ACCOUNT, { amount: "1.5" });
// 4. simulate:在 Monad 主网上模拟执行,产出 Receipt
const outcome = await simulator.simulate(capability);
真实运行:
pnpm --filter @themoss/example-simple-flow wrap
真实输出(节选):
1. discover [
{ protocol: 'wmon', method: 'wrap', kind: 'capability',
verb: 'wrap', category: 'token', tags: [ 'wrapper' ],
summary: 'Wrap native MON into WMON' }
]
2. load [
{ protocol: 'wmon', method: 'wrap', kind: 'capability',
intent: 'Wrap native MON into WMON', verb: 'wrap',
category: 'token', risk: [ 'fundOut' ],
tags: [ 'wrapper' ], params: { amount: [Object] } }
]
注意第 2 步 load 比 discover 多了两样东西:
risk: ['fundOut']—— 这个操作会把资金转出(MON 换成 WMON),Moss 主动标注了风险标签。params: { amount: [Object] }—— 参数契约(类型与范围),Agent 据此知道要填amount。
第 3 步 action 产出真正的未签名交易。看 children 里的交易对象:
3. action {
kind: 'capability', protocol: 'wmon', method: 'wrap',
params: { amount: '1.5' },
children: [ { kind: 'transaction', transaction: [Object] } ]
}
第 4 步 simulate 拿到链上 Receipt。关键部分:
4. simulate {
"results": [{
"transaction": {
"from": "0xcccccccccccccccccccccccccccccccccccccccc",
"to": "0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A",
"data": "0xd0e30db0",
"value": "0x14d1120d7b160000"
},
"reverted": false,
"receipt": {
"outcome": { "operation": "wrap", "amount": "1500000000000000000" },
"text": "WMON wrap: 1500000000000000000 for 0xCcCC...cccC"
},
"changes": [
{ "kind": "nativeTransfer", "from": "0xcccc...cccc",
"to": "0x3bd359...5433A", "value": "1500000000000000000" }
]
}]
}
解读这笔 Receipt:
to: 0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A是 WMON 合约地址data: 0xd0e30db0是deposit()的 selectorvalue: 0x14d1120d7b160000= 1.5 MON(十六进制,换算成 wei 即 1.5 × 10¹⁸)changes是有序状态变化:原生 MON 从账户转出 1.5 个reverted: false表示模拟成功
重点:Moss 不返回一句”成功”,而是一份结构化、可验证的证据。你的 Agent(或你本人)应该比对”请求的 1.5 MON wrap”和”Receipt 里的 1.5 × 10¹⁸ wrap”是否一致,一致才交给钱包签名。这就是 Moss 的安全模型——先验证,后签名。
4.2 示例二:Kuru swap
第二个示例模拟一笔 MON → USDC 的 swap。源码 examples/simple-flow/src/kuru-swap.ts 多了一步 quote(报价):
// 先报价:询问 1 MON 能换多少 USDC
const quote = await registry.action("kuru", "quote", ACCOUNT, {
tokenIn: NATIVE, tokenOut: USDC_ADDRESS, amountIn: "1",
});
console.log("quote", quote.data);
// 再构建 swap 能力
const capability = await registry.action("kuru", "swap", ACCOUNT, {
tokenIn: NATIVE, tokenOut: USDC_ADDRESS, amountIn: "1", slippage: 50,
});
真实运行:
pnpm --filter @themoss/example-simple-flow swap
真实报价输出:
quote {
amountSide: 'amountIn',
amountIn: '1',
estimatedAmountOut: '0.021519',
minimumAmountOut: '0.021411',
path: [ 'native', '0x754704Bc059F8C67012fEd69BC8A327a5aafb603' ]
}
含义:用 1 MON 换 USDC,预估得到约 0.021519 USDC,按 50 bps 滑点容忍下限 0.021411 USDC。路径是 native → 0x7547...603(这是 Kuru 上的 USDC 池子地址)。
随后 simulate 产出 swap 的 Receipt,里面有完整的未签名 data(Kuru 的 execute selector 0xffa5210a 开头的 calldata)和有序的 token 变化记录。reverted: false 表示在 Monad 当前主网状态下这笔 swap 可成功执行。
五、四步流程逐层图解
把第四节的真实行为抽象成管线,每个阶段输入什么、产出什么:
问”有哪些协议 / 操作?”
{“verb”:“wrap”}→ 返回坐标:wmon.wrap + 摘要
加载意图、风险标签、参数契约
{“items”:[{“protocol”:“wmon”,“method”:“wrap”}]}→ Stub:含 risk / params
构建未签名交易 + Capability 树
amount: “1.5”
→ 未签名 tx(不发送)
在链上 trace 执行
reverted:false + changes[]
→ 有序 Receipt 证据
六、把它接进你的 AI Agent(MCP)
Moss 内置 MCP server,把上面四步暴露成 4 个标准工具:discover / load / action / simulate。任意支持 MCP 的客户端(Claude Desktop、Cursor 等)都能直接调用。
配置(在 MCP 客户端配置里加):
{
"mcpServers": {
"moss": {
"command": "node",
"args": ["<path-to-moss>/packages/mcp-server/dist/cli.js"],
"env": { "MOSS_RPC_URL": "https://rpc.monad.xyz" }
}
}
}
接入后,Agent 的典型工作流:
“把 1 MON 换成 USDC”
discover → load
action → simulate
约 0.0215 USDC
滑点 50 bps
Agent 拿到 Receipt 后,比对”用户请求”和”模拟结果”是否一致,一致才交钱包签名。Moss 本身不持有任何签名能力。
七、想参与开源贡献?从这里开始
Moss 欢迎文档和协议包贡献。新人最友好的三个入口:
- 写文档 / FAQ:仓库 Issue 区常征集文档需求,中文资料尤其稀缺
- 接新协议:读
docs/protocol-onboarding.md,照着protocol-kuru的例子写一个protocol-* - 提交 PR:Fork 自己的副本 → 开分支 → 改 →
gh pr create
贡献流程与”跑通示例”相互独立:你可以先跑通、理解项目,再决定从哪里切入。
八、常见坑
| 问题 | 解决 |
|---|---|
pnpm: command not found | 先 npm install -g pnpm |
pnpm install 后示例找不到包 | 必须在仓库根目录用 workspace 安装,不要在 examples/ 里单独装 |
| RPC 连不上 | 示例只读主网状态做模拟,不需要私钥;检查 MOSS_RPC_URL 是否可达 |
| 想发真实交易 | Moss 不支持——它只模拟。签名发送由你的钱包层完成 |
simulate 报 reverted: true | 说明在当前链上状态这笔交易会失败,不要签名;先排查参数(滑点、金额、地址) |
九、下一步学什么
- 读 Getting Started 逐层重建四步流程
- 读 MCP Tools 理解 4 个工具的输入输出契约
- 读 Protocol Onboarding 自己写一个协议包
- 读
examples/simple-flow/src/wmon-wrap.ts和kuru-swap.ts两个文件,是理解 Moss 最直观的入口
注意: Moss 是未经审计的 alpha 软件,请勿用于生产资金。它适合学习、原型和研究。
参考链接
- Moss 仓库:https://github.com/nishuzumi/moss
- Getting Started:https://github.com/nishuzumi/moss/blob/main/docs/getting-started.md
- MCP Tools:https://github.com/nishuzumi/moss/blob/main/docs/mcp-tools.md
- Protocol Onboarding:https://github.com/nishuzumi/moss/blob/main/docs/protocol-onboarding.md
- 示例源码:examples/simple-flow/src/wmon-wrap.ts · kuru-swap.ts