scaffold

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Checklist

检查清单

[ ] - Plan architecture and folder structure [ ] - Decide which components of the app will be onchain [ ] - Scaffold the project [ ] - Initialize git repo (
git init && git add -A && git commit -m "initial commit"
) [ ] - Don't build exisiting contracts from scratch, use Openzeppelin contracts where ever possible [ ] - Build smart contracts [ ] - Deploy smart contracts — fetch
wallet/
skill, then deploy via the Alchemy Agent Wallet session (CREATE2 through the canonical CreateX factory). This must happen before building the frontend because the frontend needs the deployed contract addresses. [ ] - Verify smart contracts post deployment — use the verification API to verify on all explorers with one call. [ ] - (If the app needs historical/queryable onchain data) Initialize an indexer — fetch
indexer/
skill. The indexer is initialized in an
indexer/
folder after the contract is deployed AND verified. [ ] - Build frontend using the deployed contract addresses. Use Wagmi, Next.js and Shadcn if user has no preferences [ ] - Apply known gotchas (see section below) — bump
tsconfig.json
target to ES2020 right after
create-next-app
, etc. [ ] - Create the monskills metadata file (see "Monskills metadata" section below) — do this before the final commit so it lands in git history. [ ] - Commit all changes to git (
git add -A && git commit
)
[ ] - 规划架构和文件夹结构 [ ] - 确定应用的哪些组件将部署在链上 [ ] - 初始化项目脚手架 [ ] - 初始化git仓库(
git init && git add -A && git commit -m "initial commit"
) [ ] - 不要从零开始构建现有合约,尽可能使用Openzeppelin合约 [ ] - 构建智能合约 [ ] - 部署智能合约 — 获取
wallet/
技能,然后通过Alchemy Agent Wallet会话部署(通过标准CreateX工厂实现CREATE2)。这必须在构建前端之前完成,因为前端需要已部署合约的地址。 [ ] - 部署后验证智能合约 — 使用验证API通过一次调用在所有浏览器上完成验证。 [ ] - (如果应用需要可查询的链上历史数据)初始化索引器 — 获取
indexer/
技能。索引器会在合约部署并验证后,在
indexer/
文件夹中初始化。 [ ] - 使用已部署合约的地址构建前端。如果用户没有偏好,使用Wagmi、Next.js和Shadcn [ ] - 应用已知的注意事项(见下文章节)—— 在执行
create-next-app
后立即将
tsconfig.json
的target版本升级到ES2020等。 [ ] - 创建monskills元数据文件(见下文“Monskills元数据”章节)—— 在最终提交前完成此操作,使其纳入git历史。 [ ] - 将所有更改提交到git(
git add -A && git commit

Known gotchas — apply up front

已知注意事项 — 提前应用

These are well-known paper-cuts you will hit mid-build if you skip them. Patch them when you scaffold, not after the typechecker screams.
这些是如果你跳过就会在构建过程中遇到的常见问题。在初始化脚手架时就修复它们,不要等到类型检查器报错。

Next.js default tsconfig target is too low for viem/wagmi

Next.js默认tsconfig目标版本过低,不兼容viem/wagmi

create-next-app
generates
"target": "ES2017"
. viem, wagmi, and most onchain code use BigInt literals (
0n
,
1n
) everywhere — amounts, gas, event args, block numbers — so a fresh Next.js project fails typechecking with
TS2737: BigInt literals are not available when targeting lower than ES2020
the moment you
useReadContract
or
getLogs
.
Bump the target immediately after running
npx create-next-app
:
bash
cd web
jq '.compilerOptions.target = "ES2020"' tsconfig.json > tsconfig.tmp && mv tsconfig.tmp tsconfig.json
(If
jq
isn't available, open
tsconfig.json
and change
"target": "ES2017"
to
"target": "ES2020"
.)
create-next-app
生成的配置为
"target": "ES2017"
。viem、wagmi以及大多数链上代码广泛使用BigInt字面量(
0n
1n
)—— 比如金额、gas费、事件参数、区块编号等——因此当你首次调用
useReadContract
getLogs
时,全新的Next.js项目会因
TS2737: BigInt literals are not available when targeting lower than ES2020
错误而类型检查失败。
在执行
npx create-next-app
后立即升级目标版本:
bash
cd web
jq '.compilerOptions.target = "ES2020"' tsconfig.json > tsconfig.tmp && mv tsconfig.tmp tsconfig.json
(如果没有安装
jq
,直接打开
tsconfig.json
"target": "ES2017"
改为
"target": "ES2020"
。)

Scaffolding

项目脚手架

Before jumping into writing code, use plan mode to plan the architecture of the app.
FolderComponent
web/Web app frontend, backend routes also in case of Next.js or similar app (if the user does not have a preference go with Next.js and shadcn components)
contracts/Smart contracts (could be a Foundry project, if the user does not have a preference use Foundry)
indexer/(Optional) HyperIndex indexer for querying historical onchain events. Created via
indexer/
skill after the contract is deployed and verified.
在开始编写代码之前,使用规划模式规划应用的架构。
文件夹组件
web/Web应用前端,若使用Next.js或类似框架还包含后端路由(如果用户没有偏好,选择Next.js和shadcn组件)
contracts/智能合约(可以是Foundry项目,如果用户没有偏好,使用Foundry)
indexer/(可选)用于查询链上历史事件的HyperIndex索引器。在合约部署并验证后,通过
indexer/
技能创建。

Decide what to put onchain

确定哪些内容部署在链上

Put it onchain if it involves:
  • Trustless ownership — who owns this token/NFT/position?
  • Trustless exchange — swapping, trading, lending, borrowing
  • Composability — other contracts need to call it
  • Censorship resistance — must work even if your team disappears
  • Permanent commitments — votes, attestations, proofs
Keep it offchain if it involves:
  • User profiles, preferences, settings
  • Search, filtering, sorting
  • Images, videos, metadata (store on IPFS, reference onchain)
  • Business logic that changes frequently
  • Anything that doesn't involve value transfer or trust
Judgment calls:
  • Reputation scores → offchain compute, onchain commitments (hashes or attestations)
  • Price data → offchain oracles writing onchain (Chainlink)
  • Game state → depends on stakes. Poker with real money? Onchain. Leaderboard? Offchain.
如果涉及以下情况,将其部署在链上:
  • 无需信任的所有权 — 谁拥有该代币/NFT/头寸?
  • 无需信任的交易 — 兑换、交易、借贷
  • 可组合性 — 其他合约需要调用它
  • 抗审查性 — 即使你的团队消失,它仍能正常运行
  • 永久承诺 — 投票、认证、证明
如果涉及以下情况,将其保留在链下:
  • 用户资料、偏好、设置
  • 搜索、过滤、排序
  • 图片、视频、元数据(存储在IPFS上,链上仅保存引用)
  • 频繁变更的业务逻辑
  • 任何不涉及价值转移或信任的内容
判断准则:
  • 声誉评分 → 链下计算,链上提交(哈希或认证)
  • 价格数据 → 链下预言机写入链上(Chainlink)
  • 游戏状态 → 取决于风险。涉及真实资金的扑克游戏?部署在链上。排行榜?保留在链下。

Don't try to build smart contracts from scratch

不要从零开始构建智能合约

It is very likely that depending on the usecase of the smart contract, there is an Openzeppelin smart contract available to build on top of instead of building from scratch.
For example: Don't rebuild ERC20, ERC721 and other well known token types from scratch build on top of Openzeppelin contracts since they are heavily audited.
All Openzeppelin smart contracts can be found here: https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts and you can use the below command to install it (Foundry should be already installed).
bash
undefined
根据智能合约的用例,很可能已经有Openzeppelin智能合约可供你基于其构建,无需从零开始开发。
例如:不要重新构建ERC20、ERC721等知名代币类型,基于Openzeppelin合约构建即可,因为它们经过了严格审计。
bash
undefined

--no-git avoids adding the dep as a git submodule — required when the contracts/

--no-git避免将依赖项添加为git子模块 — 当contracts/文件夹还不是独立git仓库时(这是monskills脚手架的默认情况,因为外层项目目录管理git历史),此参数是必需的。

folder is not (yet) its own git repo, which is the default in monskills scaffolds

because the outer project directory owns the git history.

forge install --no-git OpenZeppelin/openzeppelin-contracts
undefined
forge install --no-git OpenZeppelin/openzeppelin-contracts
undefined

Use Wagmi in Frontend

前端使用Wagmi

Use the wagmi v3 library for making smart contracts from Frontend.
For wallet connection and authentication use Para — embedded MPC wallets (email / passkey / social login) plus external-wallet connect. The
wallet-integration
skill walks through the
@getpara/cli
workflow (
para init
+
ParaProvider
+
para doctor
against the already-scaffolded frontend, plus the Monad-specific wagmi wiring). Don't run
para create
— scaffolding is owned by this skill.
使用wagmi v3库从前端调用智能合约。
对于钱包连接和认证,使用Para — 嵌入式MPC钱包(邮箱/密钥/社交登录)外加外部钱包连接。
wallet-integration
技能会讲解
@getpara/cli
工作流(
para init
+
ParaProvider
+
para doctor
针对已初始化的前端,以及Monad特定的wagmi配置)。不要运行
para create
— 脚手架由本技能负责。

Use useSendTransactionSync whereever it can be used

尽可能使用useSendTransactionSync

Monad supports eth_sendRawTransactionSync RPC method and useSendTransactionSync uses that RPC method to send transaction and get the receipt in the same function call, that way the UI can be much more fast.
Monad支持eth_sendRawTransactionSync RPC方法,useSendTransactionSync使用该RPC方法发送交易并在同一函数调用中获取收据,这样UI可以更快响应。

Verification (All Explorers)

验证(所有浏览器)

ALWAYS use the verification API. It verifies on all 3 explorers (MonadVision, Socialscan, Monadscan) with one call. Do NOT use
forge verify-contract
as your first choice.
务必使用验证API。 它可以通过一次调用在所有3个浏览器(MonadVision、Socialscan、Monadscan)上完成验证。不要将
forge verify-contract
作为首选方法。

Step 1: Get Verification Data

步骤1:获取验证数据

After deploying, get two pieces of data:
bash
undefined
部署完成后,获取两类数据:
bash
undefined

1. Standard JSON input (all source files)

1. 标准JSON输入(所有源文件)

forge verify-contract <ADDR> <CONTRACT>
--chain 10143
--show-standard-json-input > /tmp/standard-input.json
forge verify-contract <ADDR> <CONTRACT>
--chain 10143
--show-standard-json-input > /tmp/standard-input.json

2. Foundry metadata (from compilation output)

2. Foundry元数据(来自编译输出)

cat out/<Contract>.sol/<Contract>.json | jq '.metadata' > /tmp/metadata.json
undefined
cat out/<Contract>.sol/<Contract>.json | jq '.metadata' > /tmp/metadata.json
undefined

Step 2: Call Verification API

步骤2:调用验证API

bash
STANDARD_INPUT=$(cat /tmp/standard-input.json)
FOUNDRY_METADATA=$(cat /tmp/metadata.json)

cat > /tmp/verify.json << EOF
{
  "chainId": 10143,
  "contractAddress": "0xYOUR_CONTRACT_ADDRESS",
  "contractName": "src/MyContract.sol:MyContract",
  "compilerVersion": "v0.8.28+commit.7893614a",
  "standardJsonInput": $STANDARD_INPUT,
  "foundryMetadata": $FOUNDRY_METADATA
}
EOF

curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d @/tmp/verify.json
bash
STANDARD_INPUT=$(cat /tmp/standard-input.json)
FOUNDRY_METADATA=$(cat /tmp/metadata.json)

cat > /tmp/verify.json << EOF
{
  "chainId": 10143,
  "contractAddress": "0xYOUR_CONTRACT_ADDRESS",
  "contractName": "src/MyContract.sol:MyContract",
  "compilerVersion": "v0.8.28+commit.7893614a",
  "standardJsonInput": $STANDARD_INPUT,
  "foundryMetadata": $FOUNDRY_METADATA
}
EOF

curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d @/tmp/verify.json

With Constructor Arguments

带构造函数参数的情况

Add
constructorArgs
(ABI-encoded, WITHOUT 0x prefix).
Example:
bash
undefined
添加
constructorArgs
(ABI编码,不带0x前缀)。
示例:
bash
undefined

Get constructor args

获取构造函数参数

ARGS=$(cast abi-encode "constructor(string,string,uint256)" "MyToken" "MTK" 1000000000000000000000000)
ARGS=$(cast abi-encode "constructor(string,string,uint256)" "MyToken" "MTK" 1000000000000000000000000)

Remove 0x prefix

移除0x前缀

ARGS_NO_PREFIX=${ARGS#0x}
ARGS_NO_PREFIX=${ARGS#0x}

Add to request

添加到请求中

"constructorArgs": "$ARGS_NO_PREFIX"
undefined
"constructorArgs": "$ARGS_NO_PREFIX"
undefined

Parameters

参数说明

ParameterRequiredDescription
chainId
Yes10143 (testnet) or 143 (mainnet)
contractAddress
YesDeployed contract address
contractName
YesFormat:
path/File.sol:ContractName
compilerVersion
Yese.g.,
v0.8.28+commit.7893614a
standardJsonInput
YesFrom
forge verify-contract --show-standard-json-input
foundryMetadata
YesFrom
out/<Contract>.sol/<Contract>.json > .metadata
constructorArgs
NoABI-encoded args WITHOUT 0x prefix
参数是否必填描述
chainId
10143(测试网)或143(主网)
contractAddress
已部署合约的地址
contractName
格式:
path/File.sol:ContractName
compilerVersion
例如:
v0.8.28+commit.7893614a
standardJsonInput
来自
forge verify-contract --show-standard-json-input
foundryMetadata
来自
out/<Contract>.sol/<Contract>.json > .metadata
constructorArgs
ABI编码的参数,不带0x前缀

Manual Verification (Fallback Only)

手动验证(仅作为备选)

Only use this if the API fails.
Testnet:
bash
forge verify-contract <ADDR> <CONTRACT> --chain 10143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"
Mainnet:
bash
forge verify-contract <ADDR> <CONTRACT> --chain 143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"
仅在API失败时使用此方法。
测试网:
bash
forge verify-contract <ADDR> <CONTRACT> --chain 10143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"
主网:
bash
forge verify-contract <ADDR> <CONTRACT> --chain 143 \
  --verifier sourcify \
  --verifier-url "https://sourcify-api-monad.blockvision.org/"

Monskills metadata

Monskills元数据

Create a visible
.monskills
file in the project root before the final commit. This file records that the project was built with monskills and which Monad network the scaffold targets.
For Monad mainnet:
ini
built-with=monskills
chain=monad
For Monad testnet:
ini
built-with=monskills
chain=monad-testnet
If the target network is unclear, ask the user before creating
.monskills
. Do not add hidden metadata, mutate git commit messages, or use framework
generator
fields for monskills provenance.
在最终提交前,在项目根目录创建一个可见的
.monskills
文件。该文件记录项目是使用monskills构建的,以及脚手架针对的Monad网络。
Monad主网:
ini
built-with=monskills
chain=monad
Monad测试网:
ini
built-with=monskills
chain=monad-testnet
如果目标网络不明确,在创建
.monskills
前询问用户。不要添加隐藏元数据、修改git提交消息,或使用框架的
generator
字段记录monskills来源。

What to Fetch by Task

按任务获取对应的技能

I'm doing...Fetch these skills
Choosing a blockchain to build on
why-monad/
Writing smart contracts
addresses/
Agent wallet management, deploy smart contracts (CREATE2 via CreateX), or perform onchain actions — via Alchemy Agent Wallet sessions (
@alchemy/cli
)
wallet/
Adding wallet + auth to a frontend (embedded MPC wallets, social/email/passkey login, plus external-wallet connect — Para)
wallet-integration/
Adding a historical/activity feed or any feature that requires indexing onchain smart contract events
indexer/
Building an app from scratch (idea to production)
scaffold/
(this)
我正在做...获取这些技能
选择要构建应用的区块链
why-monad/
编写智能合约
addresses/
Agent钱包管理、部署智能合约(通过CreateX实现CREATE2),或执行链上操作 — 通过Alchemy Agent Wallet会话(
@alchemy/cli
wallet/
为前端添加钱包+认证功能(嵌入式MPC钱包、社交/邮箱/密钥登录,外加外部钱包连接 — Para)
wallet-integration/
添加历史/活动流或任何需要索引链上智能合约事件的功能
indexer/
从零开始构建应用(从想法到生产)
scaffold/
(本技能)