Moss 新手教程:从零跑通第一个链上模拟

这份教程带你把 Moss 真正跑起来,用两个官方示例模拟真实的 Monad 链上交易——不需要私钥、不需要有钱包、不需要懂 Solidity。所有命令输出均来自真实运行。


一、Moss 在做一件什么事?

Moss 是一个把 Monad 链上协议封装成”Agent 可调用的能力(Capability)“的框架。它最大的特点是:只构建和模拟交易,绝不签名、绝不发送。

先看它在系统里的位置:

AI Agent
意图发起方
discover → load →
action → simulate
Moss
翻译与预演
未签名交易
+ Receipt 证据
Monad 链
状态与执行

Moss 站在 Agent 和链之间:把”人话意图”翻译成”可验证的未签名交易”,模拟后产出 Receipt,但永远不签名、不发送

一句话:Agent 负责”想做什么”,Moss 负责”翻译成链能懂的话并预演”,钱包负责”真正签字”。 三者分离,Agent 碰不到你的资金。


二、环境准备

Moss 是 TypeScript monorepo,需要两个工具:

工具版本检查命令
Node.js≥ 22node --version
pnpm≥ 11pnpm --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 步 loaddiscover 多了两样东西:

  • 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: 0xd0e30db0deposit() 的 selector
  • value: 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 可成功执行。


五、四步流程逐层图解

把第四节的真实行为抽象成管线,每个阶段输入什么、产出什么:

① discover

问”有哪些协议 / 操作?”

{“verb”:“wrap”}

→ 返回坐标:wmon.wrap + 摘要

② load

加载意图、风险标签、参数契约

{“items”:[{“protocol”:“wmon”,“method”:“wrap”}]}

→ Stub:含 risk / params

③ action

构建未签名交易 + Capability 树

amount: “1.5”

→ 未签名 tx(不发送)

④ simulate

在链上 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”
Moss
discover → load
action → simulate
Receipt
约 0.0215 USDC
滑点 50 bps

Agent 拿到 Receipt 后,比对”用户请求”和”模拟结果”是否一致,一致才交钱包签名。Moss 本身不持有任何签名能力。


七、想参与开源贡献?从这里开始

Moss 欢迎文档和协议包贡献。新人最友好的三个入口:

  1. 写文档 / FAQ:仓库 Issue 区常征集文档需求,中文资料尤其稀缺
  2. 接新协议:读 docs/protocol-onboarding.md,照着 protocol-kuru 的例子写一个 protocol-*
  3. 提交 PR:Fork 自己的副本 → 开分支 → 改 → gh pr create

贡献流程与”跑通示例”相互独立:你可以先跑通、理解项目,再决定从哪里切入。


八、常见坑

问题解决
pnpm: command not foundnpm install -g pnpm
pnpm install 后示例找不到包必须在仓库根目录用 workspace 安装,不要在 examples/ 里单独装
RPC 连不上示例只读主网状态做模拟,不需要私钥;检查 MOSS_RPC_URL 是否可达
想发真实交易Moss 不支持——它只模拟。签名发送由你的钱包层完成
simulatereverted: true说明在当前链上状态这笔交易会失败,不要签名;先排查参数(滑点、金额、地址)

九、下一步学什么

  • Getting Started 逐层重建四步流程
  • MCP Tools 理解 4 个工具的输入输出契约
  • Protocol Onboarding 自己写一个协议包
  • examples/simple-flow/src/wmon-wrap.tskuru-swap.ts 两个文件,是理解 Moss 最直观的入口

注意: Moss 是未经审计的 alpha 软件,请勿用于生产资金。它适合学习、原型和研究。

参考链接