关于 initia-appchain-dev
initia-appchain-dev 是面向 Initia 全栈开发的技能,涵盖合约、前端集成和应用链运维。它先收集 VM、网络及链配置等关键信息,并提供环境搭建、实现约束与验证流程。
主要功能
- 01开发前收集链与 VM 信息
- 02提供 MOVE、EVM、WASM 环境配置流程
- 03涵盖合约、前端和应用链运维
- 04包含 Initia 前端集成约束
- 05提供工具与 VM 二进制验证步骤
适用场景
- 01为指定 VM 配置开发环境
- 02基于 Initia 链参数集成前端
- 03启动或排查现有应用链
- 04检查部署与交易相关实现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ initia-labs/ agent-skills --skill initia-appchain-dev安装后在 Claude Code 中输入/initia-appchain-dev确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/common-tasks.mdcontracts.mde2e-recipes.mdfrontend-evm-rpc.mdfrontend-interwovenkit.mdruntime-discovery.mdtroubleshooting.mdweave-commands.mdweave-config-schema.mdscripts/bech32_utils.pycheck-provider-setup.shconvert-address.pyfund-user.shgenerate-system-keys.pyinstall-tools.shlint-tags.shrequirements.txtscaffold-contract.shscaffold-frontend.shto_hex.pyverify-appchain.sh详细介绍
Initia 应用链开发
为全栈 Initia 开发提供实用指导,涵盖合约、前端集成和应用链运维。
此文件中的命令示例假定工作目录为 skill/;请相应使用 scripts/... 路径。
信息收集问题(先询问)
实施前,先收集缺失的输入信息:
- 需要使用哪个 VM(
evm、move、wasm)? - 目标网络是哪个(
testnet还是mainnet)? - 这是全新启动 Rollup,还是对现有 Rollup 进行运维/调试?
- 对于前端工作,这是 EVM JSON-RPC 应用,还是 InterwovenKit 钱包/桥接应用?
- 已知哪些特定于链的值(
chain_id、RPC URL、已部署合约地址、denom)?
如果缺少关键值,请先提出简洁的后续问题,再生成最终代码/配置。
如果缺少 chain_id/端点/VM,请先按照 references/runtime-discovery.md 中的流程进行发现,不要擅自假定默认值。
如果已安装 weave,但因 shell 层面的错误而无法运行,请改用 ~/.minitia/artifacts/config.json 和直接的 minitiad 命令继续发现,不要因此中断流程。
然后询问针对具体情境的确认问题:
- 前端任务:“我发现了本地 Rollup 配置/运行时。前端集成要使用此 Rollup 吗?”
- 非前端任务:“我发现了本地运行时值(VM、链 ID、端点)。此任务要使用这些值吗?”
环境设置工作流(单次提示词设置)
当用户要求“为 [Track] track 设置我的环境”(步骤 5)时,执行以下流程:
1. 确定 Track 要求和前置条件
- [MOVE] Track:
minimove仓库 ->minitiad。需要go。 - [EVM] Track:
minievm仓库 ->minitiad。需要go、foundry。 - [WASM] Track:
miniwasm仓库 ->minitiad。需要go、rust/cargo。
2. 检查系统前置条件
根据所选 Track 检查前置条件(始终检查 docker,以确保工具安装程序兼容):
- [MOVE] Track:
go、docker - [EVM] Track:
go、docker、foundry - [WASM] Track:
go、docker、cargo
对于所选 Track 所需的每个工具:
- 如果缺失:告知用户,并建议安装命令(例如:“我发现你缺少 Cargo。要我使用
rustup为你安装吗?”)。 - 如果已存在:直接继续,无需提示。
3. 安装 Initia 核心工具
运行 scripts/install-tools.sh,以安装 jq、weave 和 initiad(L1)。
- 安全性: 如果脚本需要
sudo,请在运行前向用户说明。 - 如果所需工具已存在,优先验证版本,而不是重新安装。固定的安装程序版本可能落后于机器上已安装的版本。
4. 构建 VM 专用二进制文件(minitiad)
从源代码克隆、构建并清理相关 VM。
请直接在仓库目录中运行构建。不要依赖 shell 链式 cd ... && make install 示例,因为执行环境可能会分别管理工作目录。
- [MOVE]:
git clone --depth 1 https://github.com/initia-labs/minimove.git /tmp/minimove cd /tmp/minimove make install rm -rf /tmp/minimove - [EVM]:
git clone --depth 1 https://github.com/initia-labs/minievm.git /tmp/minievm cd /tmp/minievm make install rm -rf /tmp/minievm - [WASM]:
git clone --depth 1 https://github.com/initia-labs/miniwasm.git /tmp/miniwasm cd /tmp/miniwasm make install rm -rf /tmp/miniwasm
5. 配置 PATH
- 确保用户的
PATH中包含~/go/bin。 - 检查 shell 配置文件(
.zshrc、.bashrc),如果缺少则建议添加export命令。 - 更新 shell 配置后,告知用户运行
source ~/.zshrc(或打开新的终端),以便在当前 shell 中应用更改。 - 验证时,可以在单条命令中运行
zsh -lc 'source ~/.zshrc && <command>';这不会在不同的助手命令之间持久生效。
6. 最终验证
运行:
weave versioninitiad versionminitiad version --long | rg '^(name|server_name|version|commit):'
所需 VM 匹配项:
- [EVM] track:
name: minievm - [MOVE] track:
name: minimove - [WASM] track: 验证报告的
name与构建的 Wasm VM 相符
不要仅凭 minitiad version 命令成功运行,就认定验证已完成。PATH 中的二进制文件仍可能来自不同的 VM track。
约定默认值
| 区域 | 默认值 | 说明 |
|---|---|---|
| VM | evm | 仅在用户要求时使用 move/wasm |
| Move 版本 | 2.1 | 使用 minitiad move build。除非特定编译器版本有要求,否则建议从 Move.toml 中省略 edition。 |
| 网络 | testnet | 仅在用户明确要求时使用 mainnet |
| 前端(EVM VM) | wagmi + viem JSON-RPC | 纯 EVM 应用的默认选项 |
| 前端(Move/Wasm) | @initia/interwovenkit-react | 需要 InterwovenKit 功能时使用 |
| Tx 体验 | requestTxBlock | 优先采用确认体验;使用 requestTxSync 可提升本地开发的稳定性。 |
| Provider 顺序 | Wagmi -> Query -> InterwovenKit | Initia SDK 的稳定路径 |
| Rollup DA | INITIA | 仅在明确需要时优先使用 Celestia |
| 密钥与密钥环 | gas-station / test | 黑客松工具的默认密钥和 --keyring-backend test |
| Denom | GAS(EVM)/ umin(Move) | 测试/内部 Rollup 的常见默认值 |
严格约束(绝不违反)
标签规范
- VM 专属指导使用 VM 优先标签:
[EVM]、[MOVE]、[WASM]、[ALL-VM]。 - VM 标签后可添加上下文标签:
[CLI]、[DEV]、[REST]、[RPC]、[FRONTEND]、[INTERWOVENKIT]、[BUILD]、[TEST]。 - 优先使用叠加标签(例如
[EVM][CLI]),而不是组合标签(例如避免使用[EVM CLI])。 - 编辑任何技能 Markdown 文件时必须遵循以下工作流:修改前运行
scripts/lint-tags.sh,交付前再次运行。
Initia 用户名(严格按需启用)
- 除非用户明确要求(例如“添加用户名支持”),否则绝不能在任何脚手架、组件或代码片段中实现用户名支持。
- 用户提出要求时,仅使用
useInterwovenKit().username获取已连接钱包自己的显示名称。 - 模式:
{username ? username : shortenAddress(initiaAddress)} - 要解析任意钱包地址的用户名(例如 MemoBoard 的发送者行),请使用
useUsernameQuery(address?)并传入发送者地址;这要求@initia/interwovenkit-react版本为2.4.6或更高。 - 对于信息流、留言板或任何渲染消息/账户列表的界面,请在子行组件(例如
MessageRow)中解析发送者用户名,并在该组件内调用useUsernameQuery(address)。不要直接在父组件的.map()回调或条件循环体中调用 hooks。 - 除非基于 hook 的解析无法满足需求,否则不要通过 REST 解析。
useUsernameQuery的行为:- 不带参数:解析已连接的钱包地址(回退到
useAddress())。 - 带参数:解析传入的地址。
- 不带参数:解析已连接的钱包地址(回退到
工作区规范(关键)
- 任务完成后,绝不能在项目目录中留下临时文件或元数据 JSON 文件(例如
store_tx.json、tx.json、.bin)。 - 完成前删除用于部署的二进制文件。
InterwovenKit 本地应用链(关键)
- 为本地应用链配置前端时,必须同时在
InterwovenKitProvider中使用customChain和customChains: [customChain]属性。 - 用法示例:
<InterwovenKitProvider {...TESTNET} customChain={customChain} customChains={[customChain]} > <App /> </InterwovenKitProvider> - 桥接支持:为确保桥接能够解析公共链(如
initiation-2),始终将{...TESTNET}预设(从@initia/interwovenkit-react导入)展开到InterwovenKitProvider中:<InterwovenKitProvider {...TESTNET} ... />。 - 地址前缀:
customChain必须包含顶层bech32_prefix字符串(例如bech32_prefix: "init")。所有应用链类型都必须设置此项。 - 元数据完整性:为避免出现“Chain not found”错误,
customChain对象必须包含network_type: 'testnet'、staking、fees(其中low/average/high_gas_price: 0)以及native_assets数组。 - API 要求:
apis对象必须包含rpc、rest和indexer(必要时使用占位符),以满足 kit 的发现逻辑。 - 桥接支持(openBridge):使用
openBridge时,只指定srcChainId和srcDenom(例如initiation-2和uinit)。不要指定本地dstChainId,否则如果本地链尚未被索引,可能会导致解析错误。 customChain结构示例:const customChain = { chain_id: '<INSERT_APPCHAIN_ID_HERE>', chain_name: '<INSERT_APP_NAME_HERE>', network_type: 'testnet', // MANDATORY bech32_prefix: 'init', apis: { rpc: [{ address: 'http://localhost:26657' }], rest: [{ address: 'http://localhost:1317' }], indexer: [{ address: 'http://localhost:8080' }], // MANDATORY 'json-rpc': [{ address: 'http://localhost:8545' }], }, fees: { fee_tokens: [{ denom: 'umin', fixed_min_gas_price: 0, low_gas_price: 0, average_gas_price: 0, high_gas_price: 0 }] }, staking: { staking_tokens: [{ denom: 'umin' }] }, native_assets: [{ denom: 'umin', name: 'Token', symbol: 'TKN', decimals: 6 }], metadata: { is_l1: false, minitia: { type: 'minimove' } } }
前端要求(关键)
- 占位符同步:搭建前端后,必须立即将
main.jsx中的所有占位符(如<INSERT_APPCHAIN_ID_HERE>、<INSERT_NATIVE_DENOM_HERE>等)替换为研究阶段发现的实际值(例如bank-1、GAS、minievm)。 - 运行时配置同步:如果前端依赖已部署合约的地址,必须将解析出的实际地址接入运行时配置(例如
.env/VITE_*),而不是只保留占位符或示例。对于特定于 Move 的 API 和代码,在需要区分时保留术语module address。如果为正在运行的 Vite 应用添加或修改.env值,请告知用户重启开发服务器。 - Hook 导出项:
useInterwovenKit导出initiaAddress、address、username、openConnect、openWallet、openBridge、requestTxBlock、requestTxSync和autoSign。 - 交易前置检查:调用
requestTxBlock或requestTxSync之前,必须确认initiaAddress已定义。 - [ALL-VM] 发送方地址:在 Initia 中,所有消息类型(
MsgCall、MsgExecute、MsgExecuteContract)的sender字段都必须是 Bech32 地址。请在此字段中使用initiaAddress,以确保与 EVM、Move 和 Wasm 应用链兼容。在 EVM 链的 Cosmos 风格消息中,将十六进制address用作sender字段会导致“empty address string”或“decoding bech32 failed”错误。
安全与密钥保护(严格执行)
- 绝不能从密钥环导出原始私钥。
- [MOVE][DEV] 开发(构建以供发布):发布前,必须使用预期部署者的 Hex 地址重新构建模块:
minitiad move build --named-addresses <name>=0x<hex_addr>。 - [MOVE][DEV][BUILD] 命名地址重新赋值:如果
Move.toml中的[addresses].<name>是硬编码的(例如0x42),而你传入了不同的--named-addresses <name>=0x...,编译会因命名地址重新赋值错误而失败。建议在[addresses]中使用"<name>" = "_",并在[dev-addresses]中保留本地测试默认值。 - [MOVE][DEV] 依赖解析:如果
InitiaStdlib无法解析,请使用:{ git = "https://github.com/initia-labs/movevm.git", subdir = "precompile/modules/initia_stdlib", rev = "main" }。 - [MOVE][DEV] 软件包脚手架:
minitiad move new <NAME>可能会将软件包写入当前工作目录,而不是创建同级目录。如果用户需要blockforge/这样的特定文件夹,请先创建并进入该文件夹,再运行minitiad move new。 - [MOVE][DEV] 清理(非交互式 Shell):
minitiad move clean可能会提示确认,并在没有 TTY 的情况下发生 panic。在自动化工作流中,如果需要干净地重新构建,请直接移除软件包的build/目录。 - [MOVE][CLI] 部署语义:Move 模块没有单独的实例化交易。“实例化”通常指首次调用会更改状态的入口函数(例如,首次调用
mint_shard时创建每位玩家的资源)。 - [EVM][CLI] 部署:部署 EVM 时,使用
minitiad tx evm create并传入--from。 - [EVM][CLI] 字节码提取:使用
jq从 Foundry 构建产物中提取字节码;确保.bin文件没有0x前缀,也没有尾随换行符。 - [EVM][DEV][CLI]
tx evm create输入格式:minitiad tx evm create的位置参数是字节码文件路径。如果要直接传入原始字节码,请使用--input 0x...。将原始十六进制字符串作为位置参数传入可能会报错file name too long。 - [ALL-VM][SECURITY] 私钥处理:如果工具需要私钥,请使用 Initia CLI 或
InterwovenKit寻找替代工作流。
前端要求(附加)
- Polyfill:在
vite.config.js中使用vite-plugin-node-polyfills,并设置globals: { Buffer: true, process: true }。同时将resolve.dedupe设置为['react', 'react-dom', 'wagmi', '@tanstack/react-query', 'viem'],以避免 Vite 中的 provider 上下文分裂。如果使用手动 polyfill,请在main.jsx的最顶部定义Buffer和process全局 polyfill。import { Buffer } from "buffer"; window.Buffer = Buffer; window.process = { env: {} }; - 样式:
- 导入 CSS:
import "@initia/interwovenkit-react/styles.css"。 - 导入样式数据:
import InterwovenKitStyles from "@initia/interwovenkit-react/styles.js"。 - 导入注入函数:
import { injectStyles } from "@initia/interwovenkit-react"。 - 注入样式:
injectStyles(InterwovenKitStyles)。 - 注意:
InterwovenKitStyles是 styles 子路径的 DEFAULT 导出,而injectStyles是主包的 NAMED 导出。
- 导入 CSS:
- Provider 顺序:
WagmiProvider->QueryClientProvider->InterwovenKitProvider。 - 钱包弹窗:
- 使用
openConnect(而不是openModal)打开连接弹窗(v2.4.0+)。 - 已连接状态(关键):当存在
initiaAddress时,始终提供可点击的 UI 元素(例如显示缩短地址的按钮),并调用openWallet,以便用户管理连接或断开连接。
- 使用
- 自动签名实现(严格选择启用):
- 除非用户明确要求(例如“添加自动签名支持”),否则不得在任何脚手架、provider 或组件中实现自动签名支持。
- 用户提出要求时:
- Provider:向
InterwovenKitProvider传入enableAutoSign={true}。 - Hook:从
useInterwovenKit解构出autoSign对象(而不是函数)。 - 安全性:使用可选链(
autoSign?.),并通过autoSign?.isEnabledByChain[chainId]检查状态。 - 操作:
await autoSign?.enable(chainId)和await autoSign?.disable(chainId)都是异步操作。 - 权限(关键):为确保会话密钥能够签署特定消息类型,必须在
autoSign.enable中始终明确指定权限:await autoSign.enable(chainId, { permissions: ["/initia.move.v1.MsgExecute"] }) - 错误处理:如果
autoSign.disable因 "authorization not found" 失败,请调用带有所需权限的autoSign.enable来重置会话。
- Provider:向
- REST 客户端:手动从
@initia/initia.js实例化RESTClient;它不会从 hook 导出。- 关键:不要尝试从
useInterwovenKit解构networks或rest。这些对象在 hook 中不可用。始终手动定义 REST/RPC 端点,或通过自己的配置定义。
- 关键:不要尝试从
交易消息流(关键)
- [WASM][INTERWOVENKIT] 交易信封:始终包含
chainId。优先使用requestTxSync。- [WASM][INTERWOVENKIT] 负载编码:
MsgExecuteContract要求msg字段为字节(Uint8Array)。使用new TextEncoder().encode(JSON.stringify(msg))。
- [WASM][INTERWOVENKIT] 负载编码:
- [ALL-VM][INTERWOVENKIT] 自动签名(无头模式):为确保自动签名的交易处于“无头”模式(不显示费用选择提示),请求中始终包含显式的
feeDenom(例如feeDenom: "umin")以及autoSign: true标志:await requestTxSync({ chainId, autoSign: true, // CRITICAL: Required for silent signing flow messages: [...] }) - [EVM] 发送方(MsgCall):在
MsgCall中,sender使用 bech32 地址,而contractAddr使用 hex 地址。- 规范化:始终将 bech32 发送方地址转换为小写,以避免出现“decoding bech32 failed”错误。
- [EVM][INTERWOVENKIT] 负载:使用带有
typeUrl: "/minievm.evm.v1.MsgCall"的普通对象。实际消息字段必须放在value键中。- 错误示例:
{ typeUrl: "...", sender: "...", contractAddr: "..." } - 正确示例:
{ typeUrl: "...", value: { sender: "...", contractAddr: "...", ... } }
- 错误示例:
- [EVM][INTERWOVENKIT]
requestTxBlock键:始终使用复数形式的messages,不要使用msgs。传入msgs可能会导致Cannot read properties of undefined (reading 'map')。 - [EVM] 字段命名:字段使用 camelCase(
contractAddr、accessList、authList),并为列表包含空数组。 - [MOVE][INTERWOVENKIT] MsgExecute 字段命名:字段使用 camelCase;
moduleAddress必须为 bech32。- [MOVE][INTERWOVENKIT] 必需数组:始终包含
typeArgs: []和args: [],即使它们为空。在 Move 执行消息中省略这些字段,会导致前端在 Amino 转换过程中出现TypeError(Cannot read properties of undefined reading 'length')。
- [MOVE][INTERWOVENKIT] 必需数组:始终包含
Wasm REST 查询(关键)
- [WASM][REST] 查询编码:使用
RESTClient查询 Wasm 合约状态时(例如rest.wasm.smartContractState),查询消息必须是 Base64 编码的字符串。 - 查询 JSON 和执行 JSON 必须与合约的 Rust 消息架构完全匹配。不要假设名称为
all_messages,也不要假设字段名为text或message;例如,MemoBoard 变体通常使用get_messages,并采用post_message: { message: ... },而其他合约可能使用不同的字段名。 - 实现示例:
const queryData = Buffer.from(JSON.stringify({ get_messages: {} })).toString("base64"); const res = await rest.wasm.smartContractState(CONTRACT_ADDR, queryData); - [WASM][REST] 响应结构:
smartContractState通常会直接返回解码后的负载(例如res.messages),而不是将其嵌套在res.data下。除非已确认具体的响应结构,否则不要假设存在.data包装层。 - [WASM][REST] 方法名称:始终使用
smartContractState。queryContractSmart等方法在 InitiaRESTClient中不可用。 - [WASM][CLI] 后备方案:如果
minitiad query wasm contract-state smart <CONTRACT_ADDRESS> ...因 Bech32 校验和错误而失败,即使该地址来自实例化事件或list-contract-by-code,也应将链上发出的地址视为权威来源。使用minitiad query wasm list-contract-by-code <CODE_ID>验证该地址,并改用 REST 端点路径或RESTClient,而不是被 CLI 解析器阻塞。
Wasm Rust 测试(关键)
- [WASM][TEST] 地址比较:为 Wasm 合约编写单元测试时,与字符串字面量或
String比较cosmwasm_std::Addr时,始终使用.as_str()。Addr不会直接实现PartialEq<&str>或PartialEq<String>。 - 错误示例:
assert_eq!("user1", value.sender); - 正确示例:
assert_eq!("user1", value.sender.as_str());
代币精度与资金划转(仅适用于 EVM)
- [EVM] 精度:假设 EVM 应用链上的所有原生代币都采用标准 EVM 精度($10^{18}$ 个基础单位),例如
GAS。 - [EVM] 资金划转请求:当用户在 EVM 链上请求「N 个代币」时:
- 前端:乘以 $10^{18}$(例如,
parseUnits(amount, 18))。 - CLI:必须手动换算数值。对于「100 个代币」,在
bank send命令中使用100000000000000000000GAS(100 后面加 18 个零)。
- 前端:乘以 $10^{18}$(例如,
- [EVM][FRONTEND] 易读的 UI:显示 EVM 余额时,始终使用
viem中的formatUnits(balance, 18)。切勿在 UI 中显示基础单位的原始数值。 - [EVM][FRONTEND][DEV]
parseEther/formatEther的用法:只有当链上代币的小数位数恰好为 18 时,parseEther和formatEther才是有效的简写。如果小数位数可能变化,请使用运行时配置中的parseUnits(amount, decimals)和formatUnits(balance, decimals)。
EVM 查询与交易(重要)
- [EVM][FRONTEND] ABI 同步:以编译后的 ABI/函数名称为准。不要假设函数名称为
getMyBalance等;在接入前端的encodeFunctionData调用前,请先从生成的构建产物(例如out/<Contract>.sol/<Contract>.json)中确认名称和签名。 - [EVM][RPC] 状态查询:EVM 状态查询优先使用标准 JSON-RPC
eth_call,而不是RESTClient,以避免属性未定义错误。 - [EVM][FRONTEND][RPC] 读取路径的 Provider:对于只读 EVM 查询(
eth_call),请使用已配置的 JSON-RPC 端点(例如VITE_JSON_RPC_URL),而不要依赖注入的钱包 Provider(window.ethereum)。这样可避免未注入 EVM 扩展时出现「未找到 EVM 钱包 Provider」的错误。 - [EVM][RPC] 地址转换:查询 EVM 状态时(例如
eth_call),始终使用AccAddress.toHex(addr)将 bech32 地址转换为十六进制,并确保十六进制地址全部为小写。 - [EVM][CLI] 发送方格式:
minitiad query evm call的第一个参数必须是 bech32 格式的发送方地址(init1...)。 - [EVM][CLI] 查询输出字段:
minitiad query evm call -o json会在.response下返回调用结果(十六进制字符串)。 - [EVM][CLI] 交易查询时机:广播后立即运行
minitiad query tx <hash>,可能会短暂返回tx not found;失败前请短暂重试。 - [EVM][CLI] Calldata 编码:
- [EVM][FRONTEND] 首选方式:优先使用
viem(例如encodeFunctionData)生成合约input十六进制数据。 - [EVM][CLI] 首选方式:始终使用
cast calldata(例如,$(cast calldata "func(type)" arg))生成合约input十六进制数据。手动编码(例如printf)容易出错,必须避免。 - [EVM][CLI] 手动填充:如果无法避免手动编码,请确保将
BigInt值转换为十六进制,并将uint256参数填充至恰好 64 个字符。
- [EVM][FRONTEND] 首选方式:优先使用
Move REST 查询(关键)
- [MOVE][REST] 模块地址格式:使用
RESTClient查询 Move 合约状态时(例如rest.move.view),模块地址必须采用 bech32 格式。 - [MOVE][REST] 结构体标签地址格式:使用
rest.move.resource查询 Move 资源时,资源所有者仍使用 bech32 格式,但结构体标签中的模块地址必须采用 hex 格式(0x...::module::Struct)。不要使用 bech32 模块地址构建结构体标签。 - [MOVE][REST] 地址参数:
args中的地址参数必须转换为 hex,去掉0x,填充至 64 个字符(32 字节),然后进行 Base64 编码。 - 实现示例:
const b64Addr = Buffer.from( AccAddress.toHex(addr).replace('0x', '').padStart(64, '0'), 'hex' ).toString('base64'); const res = await rest.move.view(mod_bech32, mod_name, func_name, [], [b64Addr]); - 资源查询示例:
const structTag = `${AccAddress.toHex(moduleBech32)}::items::Inventory`; const res = await rest.move.resource(walletBech32, structTag); - [MOVE][REST] 响应解析:
rest.move.view的响应是一个ViewResponse对象;必须解析JSON.parse(res.data)才能访问实际值。 - [MOVE][REST] 缺失资源处理:对于库存等首次使用时的状态,资源可能尚不存在。将
rest.move.resource返回的“未找到”响应视为有效的零值/默认状态,而不是将其作为硬性失败报出。 - [MOVE][REST] 故障排查(400 Bad Request):如果
rest.move.view返回 400 错误,几乎总是因为:- 模块地址不是 bech32 格式。
args中的地址参数未正确进行 hex 填充并经 Base64 编码。
- [MOVE][INTERWOVENKIT] 自动签名(未配置消息类型):如果
autoSign.enable因“未配置消息类型”而失败,请确保:metadata.minitia.type设置正确(例如minimove、minievm)。InterwovenKitProvider中的defaultChainId与customChain.chain_id相匹配。customChain顶层存在bech32_prefix。
操作流程(如何执行任务)
- 分类层级:合约、前端、Appchain 运维或集成。
- 环境检查:确认工具(
cargo、forge、minitiad)已加入 PATH。如有需要,使用绝对路径。 - 工作区检查:搭建脚手架前,检查是否已有
Move.toml或package.json。使用提供的脚本进行非交互式搭建。 - 部署前检查清单(CLI):通过 CLI 部署合约或发送代币前,确认实际环境(通过运行时发现设置
RPC_ENDPOINT):- 链 ID:
curl -s "${RPC_ENDPOINT}/status" | jq -r '.result.node_info.network' - 原生面额:
minitiad q bank total --node "${RPC_ENDPOINT}" - 余额:确保
from账户有足够的实际原生面额。
- 链 ID:
- 清理脚手架内容:搭建脚手架后,删除占位模块/合约。
- Appchain 健康状态:如果 RPC 不可用,尝试运行
weave rollup start -d,并使用scripts/verify-appchain.sh验证。 - [MOVE][DEV] Acquires 注解:每个访问全局存储的函数(使用
borrow_global、borrow_global_mut、move_from,或调用执行这些操作的函数)都必须包含该资源类型的acquires注解。 - [MOVE][DEV] 引用规则:除非引用作为参数传入,否则不得从函数返回由全局资源(例如通过
borrow_global_mut)派生的引用(可变或不可变)。如有需要,请将逻辑内联,或将资源作为参数传入。 - [MOVE][DEV] 语法:文档注释(
///)应放在#[view]或#[test]等属性之后。 - [MOVE][CLI] 发布:
minitiad tx move publish命令不使用--path标志。将已编译.mv文件的路径作为位置参数传入:minitiad tx move publish <path_to_file>.mv ...。 - [MOVE][DEV][CLI] 重新发布兼容性:如果从同一账户重新发布时出现
BACKWARD_INCOMPATIBLE_MODULE_UPDATE错误,请保留现有公共 API(例如,将之前的公共入口/视图函数保留为兼容性封装),或在发布前重命名模块。 - [ALL-VM][CLI] 广播模式兼容性:当前的 Initia CLI 支持
sync|async广播模式;不要假定支持block。 - [MOVE][CLI] 交易查询时机:
minitiad广播后立即运行minitiad query tx <hash>,可能会短暂返回tx not found;请轮询/重试后再判定失败。 - [WASM][BUILD] 优化:生产就绪的二进制文件必须使用 CosmWasm 优化器 Docker 镜像。
- 视觉润色:优先采用粘性玻璃拟态标题栏、居中的应用卡片布局和清晰的视觉层级。
- 卓越的 UX:信息流按最新内容优先排序;输入区应位于信息流上方;提供交互反馈(悬停/焦点)。
- [ALL-VM][INTERWOVENKIT] 桥接支持:使用
useInterwovenKit中的openBridge。本地演示的srcChainId默认设为公共测试网(例如initiation-2)。 - 验证:运行
scripts/verify-appchain.sh --gas-station --bots,并在交接前确认交易成功。
渐进式披露(按需阅读)
- 常见任务(资金、地址、精度):
references/common-tasks.md - 合约(Move/Wasm/EVM):
references/contracts.md - 前端(InterwovenKit):
references/frontend-interwovenkit.md - 前端(EVM JSON-RPC):
references/frontend-evm-rpc.md - 端到端操作指南:
references/e2e-recipes.md - 运行时发现:
references/runtime-discovery.md - Weave CLI 参考:
references/weave-commands.md - Rollup 配置架构:
references/weave-config-schema.md - 故障排除与恢复:
references/troubleshooting.md
文档备用入口
- 核心文档:
https://docs.initia.xyz - InterwovenKit 文档:
https://docs.initia.xyz/interwovenkit
脚本用法
- 脚手架:
scripts/scaffold-contract.sh、scripts/scaffold-frontend.sh - 健康检查:
scripts/verify-appchain.sh - 工具:
scripts/convert-address.py、scripts/to_hex.py、scripts/generate-system-keys.py - 设置:
scripts/install-tools.sh、scripts/fund-user.sh
预期交付内容
- 更改的确切文件。
- 设置、构建和测试命令。
- 验证步骤和输出。
- 风险说明(安全、密钥、费用)。