dApp Docs/MSG链智能合约与DApp开发分析
Development reference. Not independently verified for production.

MSG Chain 智能合约与 DApp 开发完全指南

数据来源:MSG Chain 代码库核实

主网状态: No-Go — 当前 MSGChain 主网裁决为 No-Go,以下内容反映代码实际状态,不代表生产可用。


一、MSG Chain 技术全景速览

1.1 区块链核心参数

参数 值
共识算法 Round-Robin + DAR(去中心化自主轮次)
签名算法 Dilithium-5(后量子密码学 PQC)
出块时间 5 秒
最大活跃验证者 100
DAR 滞回区间 104 / 96
结算模型 双池结算
Gas 分配 40/30/20/10(验证者/开发者/燃烧/基金会金库)
重放保护 ChainID=1
智能合约引擎 CosmWasm(WASM 虚拟机)
状态存储 BadgerDB
跨链 bridge_adapter_v1(P1 规划)

1.2 技术架构分层

AI Agent / dApp 应用层
──────────────────────────────
Agent API (REST)  |  MCP Server
JSON-RPC 2.0      |  gRPC
──────────────────────────────
CosmWasm Smart Contracts
genesis_registry | dao | treasury | agent | micropayment
──────────────────────────────
MSG Chain Node (Round-Robin + DAR)
Dilithium-5 PQC  |  BadgerDB  |  libp2p

1.3 已实现的系统合约(10个)

合约 Canonical Key 核心能力
genesis_registry_v1 genesis_registry 创世注册中心、canonical key 寻址、合约地址查询
dao_governance_v1 dao_governance DAO 治理:提案创建/投票/执行、配置/计票查询
foundation_treasury_v2 foundation_treasury 金库多签:创建/签名/执行、阈值查询
gas_fee_distribution_v2 gas_fee_distribution Gas 费用分配、开发者注册、重分配
candidate_node_staking_v2 candidate_node_staking 节点质押/解质押/奖励、DAR 窗口
validator_qualification_v2 validator_qualification 验证者注册/资格/作恶报告
msg_token_cw20 — CW20 标准代币
dar_rating_v1 — DAR 评分系统
block_time_schedule_v1 block_time_schedule 出块时间调度
emission_schedule_v2 emission_schedule 代币发行计划

1.4 已实现的业务合约(5个)

合约 类别 核心能力
agent_payment_v1 AI/支付 支付意图提交、授权、执行、结算、冻结、挑战
agent_registry_v1 AI/身份 Agent 注册、按能力发现、列表查询
ai_agent_constitution_v1 AI/治理 Agent 宪章查询、策略更新、暂停/撤销
aidid_did_registry_v1 身份 DID 注册/解析/更新/停用、PQ 验证
micropayment_session_v1 支付 微支付会话创建、按秒扣费、关闭结算

1.5 当前阶段边界

  1. 无公开 testnet — 开发环境为本地沙箱(local-first, fail-closed)
  2. SDK 未正式发布 — @msg-chain/sdk 为 alpha 候选状态
  3. 部分写路径为 stub — DeFi、bridge、registry register 标记 X-MSG-Stub=true
  4. 所有合约 production_ready = false — 需 signed schema release + public E2E trace
  5. 资金/部署/治理操作必须人工审批 — 不能绕过 DAO/金库多签门禁
  6. ChainID=1 replay protection — 所有交易带 chainID
  7. Dilithium-5 后量子签名 — 公钥体系基于 PQC
  8. Native BankMsg / Gov / Staking / IBC / Stargate 为 fail-closed

二、DApp 完整类型目录(全部含现成参照物)

2.1 AI Agent 经济体

子类型 参照物 MSG 已有能力 需额外开发
A2A 任务市场 OKX AI (okx.ai) Agent 身份/注册/支付/宪章 任务发布/竞标/争议仲裁合约 + 前端
Agent 技能市场 OKX Skills Marketplace Agent 注册、能力列表 技能安装/验证/定价合约 + 前端
Agent 支付网关 OKX Agentic Payment agent_payment_v1、micropayment_session_v1 前端支付面板
Agent 声誉系统 Upwork 链上版 DID 身份锚定 评分/评价/徽章合约 + 前端

2.2 治理与 DAO

子类型 参照物 MSG 已有能力 需额外开发
DAO 治理前台 Tally.xyz / Snapshot dao_governance_v1 提案/投票/执行 前端 UI
金库多签管理 Gnosis Safe / Multis foundation_treasury_v2 多签/阈值 前端 UI
治理分析 DeepDAO / Boardroom dao_governance_v1 查询接口 数据聚合+图表
Gas 分配看板 — gas_fee_distribution_v2 前端 UI

2.3 区块浏览器与数据

子类型 参照物 MSG 已有能力 需额外开发
区块浏览器 Etherscan / Mintscan /api/v1/blocks/txs/receipts、Indexer API 前端+数据库
链上数据分析 Dune Analytics / Covalent Indexer 数据平面、RPC 查询 SQL 查询引擎+前端
合约验证器 Sourcify / Blockscout /api/v1/contracts 元数据 验证服务+UI

2.4 支付与金融

子类型 参照物 MSG 已有能力 需额外开发
微支付平台 SatoshiPay / Coil micropayment_session_v1 按秒计费 前端付费墙
流式支付 Superfluid / Sablier micropayment_session_v1 前端仪表盘
托管支付 OKX AI Escrow agent_payment_v1 支付意图+结算 争议处理前端
Staking 面板 Lido / Stader / Figment candidate_node_staking_v2 前端 UI
AMM DEX Uniswap V2/V3 CosmWasm 合约引擎 AMM 合约+前端

2.5 去中心化身份

子类型 参照物 MSG 已有能力 需额外开发
DID 面板 ENS App / SpruceID aidid_did_registry_v1 前端 UI
可验证凭证 Verite / Ceramic DID + PQ 签名 VC 颁发/验证合约+前端
身份聚合 Disco / Litentry agent_registry_v1 跨 DID 聚合

2.6 AI Agent 自治

子类型 参照物 MSG 已有能力 需额外开发
Agent 宪章合规 World ID + 规则引擎 ai_agent_constitution_v1 合规审计前端
Agent 自动化 Chainlink Keepers Agent API 事件订阅 触发合约
Agent 沙箱 Autonolas agent_sandbox_v1(P0 规划) 执行环境

2.7 基础设施工具

子类型 参照物 MSG 已有能力 需额外开发
钱包仪表盘 Zapper / Zerion Agent API 余额/交易查询 前端组合面板
多签管理 Gnosis Safe / Multis foundation_treasury_v2 前端
代币浏览器 DeBank msg_token_cw20 + RPC 前端
验证者面板 — validator_qualification_v2 前端

三、完整开发手册

3.0 通用开发环境准备

3.0.1 项目初始化

# 前端项目(适用于所有 dApp)
mkdir my-dapp && cd my-dapp
npm create vite@latest . -- --template react-ts
npm install @cosmjs/cosmwasm-stargate @cosmjs/proto-signing @cosmjs/encoding @cosmjs/stargate
npm install @tanstack/react-query wagmi viem
npm install tailwindcss @shadcn/ui lucide-react recharts
npx tailwindcss init -p

3.0.2 cosmjs 客户端封装

// src/lib/cosmos.ts
import { CosmWasmClient, SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";

const RPC_ENDPOINT = "http://localhost:26657"; // 本地沙箱
const CHAIN_ID = "msgchain-1";

let cosmWasmClient: CosmWasmClient | null = null;
let signingClient: SigningCosmWasmClient | null = null;

export async function getQueryClient(): Promise<CosmWasmClient> {
  if (!cosmWasmClient) {
    cosmWasmClient = await CosmWasmClient.connect(RPC_ENDPOINT);
  }
  return cosmWasmClient;
}

export async function getSigningClient(mnemonic: string): Promise<SigningCosmWasmClient> {
  const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
    prefix: "msg",
    gasPrice: GasPrice.fromString("1000000000attoMSG"),
  });
  signingClient = await SigningCosmWasmClient.connectWithSigner(RPC_ENDPOINT, wallet);
  return signingClient;
}

// 通过 genesis_registry_v1 查询合约地址(推荐方式)
export async function resolveContractAddress(canonicalKey: string): Promise<string> {
  const client = await getQueryClient();
  const registryAddr = "msg1registry..."; // genesis_registry_v1 固定地址
  const result = await client.queryContractSmart(registryAddr, {
    resolve_contract_address: { canonical_key: canonicalKey },
  });
  return result.contract_address;
}

3.0.3 Agent API 客户端

// src/lib/agent-api.ts
// 适用于 AI Agent 通过 REST API 查询链状态

const AGENT_API_BASE = "http://localhost:8080";
const AGENT_API_KEY = process.env.VITE_AGENT_API_KEY;

export class AgentAPIClient {
  private baseUrl: string;
  private apiKey: string;

  constructor(baseUrl = AGENT_API_BASE, apiKey = AGENT_API_KEY || "") {
    this.baseUrl = baseUrl;
    this.apiKey = apiKey;
  }

  private async fetch(path: string, options?: RequestInit) {
    const headers: Record<string, string> = {
      "Content-Type": "application/json",
    };
    if (this.apiKey) headers["X-API-Key"] = this.apiKey;
    const res = await fetch(`${this.baseUrl}${path}`, { ...options, headers });
    if (!res.ok) throw new Error(`Agent API error: ${res.status}`);
    return res.json();
  }

  // 公开只读查询(无需 API Key)
  async getBalance(address: string) {
    return this.fetch(`/agent/v1/query/balance/${address}`);
  }
  async getBlock(height: number) {
    return this.fetch(`/agent/v1/query/block/${height}`);
  }
  async getTx(hash: string) {
    return this.fetch(`/agent/v1/query/tx/${hash}`);
  }

  // 受保护写路径(需 API Key)
  async walletTransfer(walletId: string, to: string, amount: string, asset: string) {
    return this.fetch(`/agent/v1/wallet/transfer`, {
      method: "POST",
      body: JSON.stringify({ wallet_id: walletId, to, amount, asset }),
    });
  }
}

export const agentApi = new AgentAPIClient();

3.0.4 React Hook 基础模式

// src/hooks/useCosmWasm.ts
import { useQuery } from "@tanstack/react-query";
import { getQueryClient } from "../lib/cosmos";

export function useContractQuery<T>(
  contractAddress: string,
  queryMsg: Record<string, unknown>,
  enabled = true
) {
  return useQuery<T>({
    queryKey: ["contractQuery", contractAddress, queryMsg],
    queryFn: async () => {
      const client = await getQueryClient();
      return client.queryContractSmart(contractAddress, queryMsg);
    },
    enabled,
  });
}

// src/hooks/useAgentAPI.ts
import { useQuery } from "@tanstack/react-query";
import { agentApi } from "../lib/agent-api";

export function useAgentBalance(address: string) {
  return useQuery({
    queryKey: ["agentBalance", address],
    queryFn: () => agentApi.getBalance(address),
    enabled: !!address,
  });
}

3.1 DAO 治理前台(参考 Tally.xyz)

合约交互封装

// src/contracts/dao.ts
import { resolveContractAddress, getSigningClient, getQueryClient } from "../lib/cosmos";

export interface Proposal {
  id: number;
  title: string;
  description: string;
  status: "pending" | "active" | "passed" | "rejected" | "executed";
  for_votes: string;
  against_votes: string;
  abstain_votes: string;
  start_height: number;
  end_height: number;
  proposer: string;
}

export interface ProposalList {
  proposals: Proposal[];
}

export class DAOContract {
  private contractAddress: string;
  constructor(address: string) { this.contractAddress = address; }

  static async create() {
    const addr = await resolveContractAddress("dao_governance");
    return new DAOContract(addr);
  }

  // 查询
  async getProposal(id: number): Promise<Proposal> {
    const client = await getQueryClient();
    return client.queryContractSmart(this.contractAddress, { proposal: { proposal_id: id } });
  }

  async listProposals(limit = 20, startAfter?: number): Promise<ProposalList> {
    const client = await getQueryClient();
    return client.queryContractSmart(this.contractAddress, {
      list_proposals: { limit, start_after: startAfter },
    });
  }

  async getConfig() {
    const client = await getQueryClient();
    return client.queryContractSmart(this.contractAddress, { config: {} });
  }

  async getVotingPower(address: string): Promise<string> {
    const client = await getQueryClient();
    const result = await client.queryContractSmart(this.contractAddress, {
      voting_power: { address },
    });
    return result.power;
  }

  // 写操作
  async propose(mnemonic: string, sender: string, title: string, desc: string, msgs: any[], deposit: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.contractAddress, {
      propose: { title, description: desc, msgs, deposit },
    }, "auto");
  }

  async vote(mnemonic: string, sender: string, proposalId: number, vote: "yes" | "no" | "abstain" | "veto") {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.contractAddress, {
      vote: { proposal_id: proposalId, vote },
    }, "auto");
  }

  async execute(mnemonic: string, sender: string, proposalId: number) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.contractAddress, {
      execute: { proposal_id: proposalId },
    }, "auto");
  }
}

前端页面实现

// src/pages/ProposalsPage.tsx
import { useQuery } from "@tanstack/react-query";
import { ProposalCard } from "../components/dao/ProposalCard";
import { DAOContract } from "../contracts/dao";
import { useWallet } from "../hooks/useWallet";

export function ProposalsPage() {
  const { data: dao } = useQuery({
    queryKey: ["dao"],
    queryFn: () => DAOContract.create(),
  });

  const { data: proposals } = useQuery({
    queryKey: ["proposals"],
    queryFn: () => dao?.listProposals(50),
    enabled: !!dao,
  });

  return (
    <div className="container mx-auto p-6">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-3xl font-bold">Governance</h1>
        <button
          onClick={() => window.location.href = "/proposals/create"}
          className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700"
        >
          + New Proposal
        </button>
      </div>

      <div className="grid gap-4">
        {proposals?.proposals.map((p) => (
          <ProposalCard key={p.id} proposal={p} />
        ))}
      </div>
    </div>
  );
}
// src/components/dao/ProposalCard.tsx
import type { Proposal } from "../../contracts/dao";

interface Props { proposal: Proposal }

export function ProposalCard({ proposal }: Props) {
  const statusColors: Record<string, string> = {
    active: "bg-green-100 text-green-800",
    passed: "bg-blue-100 text-blue-800",
    rejected: "bg-red-100 text-red-800",
    executed: "bg-gray-100 text-gray-800",
  };

  const totalVotes = BigInt(proposal.for_votes)
    + BigInt(proposal.against_votes)
    + BigInt(proposal.abstain_votes);

  const forPercent = totalVotes > 0
    ? (Number(BigInt(proposal.for_votes) * 100n / totalVotes)).toFixed(1)
    : "0";

  return (
    <div className="border rounded-lg p-4 hover:shadow-md transition-shadow">
      <div className="flex justify-between items-start mb-3">
        <div>
          <h3 className="font-semibold text-lg">
            <a href={`/proposals/${proposal.id}`} className="hover:text-blue-600">
              #{proposal.id} {proposal.title}
            </a>
          </h3>
          <p className="text-sm text-gray-500 mt-1">
            by {proposal.proposer.slice(0, 10)}...{proposal.proposer.slice(-6)}
          </p>
        </div>
        <span className={`px-2 py-1 rounded text-xs font-medium ${statusColors[proposal.status]}`}>
          {proposal.status.toUpperCase()}
        </span>
      </div>

      <div className="w-full bg-gray-200 rounded-full h-2.5 mb-2">
        <div
          className="bg-green-600 h-2.5 rounded-full"
          style={{ width: `${forPercent}%` }}
        />
      </div>

      <div className="flex gap-4 text-sm text-gray-600">
        <span className="text-green-600">For: {proposal.for_votes}</span>
        <span className="text-red-600">Against: {proposal.against_votes}</span>
        <span className="text-gray-400">Abstain: {proposal.abstain_votes}</span>
      </div>
    </div>
  );
}

页面路由

// src/App.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ProposalsPage } from "./pages/ProposalsPage";
import { ProposalDetailPage } from "./pages/ProposalDetailPage";
import { CreateProposalPage } from "./pages/CreateProposalPage";

const queryClient = new QueryClient();

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <BrowserRouter>
        <Routes>
          <Route path="/proposals" element={<ProposalsPage />} />
          <Route path="/proposals/:id" element={<ProposalDetailPage />} />
          <Route path="/proposals/create" element={<CreateProposalPage />} />
        </Routes>
      </BrowserRouter>
    </QueryClientProvider>
  );
}

3.2 区块浏览器(参考 Etherscan / Mintscan)

后端数据服务

// explorer-backend/src/index.ts
import express from "express";
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { Pool } from "pg";

const app = express();
const client = await CosmWasmClient.connect("http://localhost:26657");
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

// 区块列表
app.get("/api/blocks", async (req, res) => {
  const { minHeight, maxHeight } = req.query;
  const latest = await client.getHeight();
  const from = Number(minHeight) || Math.max(0, latest - 100);
  const to = Number(maxHeight) || latest;

  const blocks = [];
  for (let h = from; h <= to; h++) {
    const block = await client.getBlock(h);
    blocks.push({
      height: block.header.height,
      time: block.header.time,
      num_txs: block.txs.length,
      proposer: block.header.proposerAddress,
    });
  }
  res.json({ blocks, latest });
});

// 交易详情
app.get("/api/tx/:hash", async (req, res) => {
  const tx = await client.getTx(req.params.hash);
  res.json({
    hash: tx.hash,
    height: tx.height,
    code: tx.code,
    gas_used: tx.gasUsed,
    raw_log: tx.rawLog,
  });
});

// 合约列表(通过 genesis_registry_v1)
app.get("/api/contracts", async (req, res) => {
  const registryAddr = "msg1registry...";
  const contracts = await client.queryContractSmart(registryAddr, {
    list_contracts: { limit: 50 },
  });
  res.json(contracts);
});

app.listen(3001, () => console.log("Explorer API on :3001"));

前端数据面板

// src/pages/ExplorerPage.tsx
import { useQuery } from "@tanstack/react-query";

interface Block {
  height: number;
  time: string;
  num_txs: number;
  proposer: string;
}

export function ExplorerPage() {
  const { data } = useQuery<{ blocks: Block[]; latest: number }>({
    queryKey: ["blocks"],
    queryFn: () => fetch("/api/blocks").then((r) => r.json()),
    refetchInterval: 5000, // 每 5 秒刷新
  });

  return (
    <div className="container mx-auto p-6">
      <h1 className="text-3xl font-bold mb-2">MSG Chain Explorer</h1>
      <p className="text-gray-500 mb-6">Latest Block: {data?.latest}</p>

      <div className="bg-white rounded-lg shadow overflow-hidden">
        <table className="min-w-full">
          <thead className="bg-gray-50">
            <tr>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Block</th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Age</th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Txs</th>
              <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Proposer</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200">
            {data?.blocks.map((block) => (
              <tr key={block.height} className="hover:bg-gray-50">
                <td className="px-6 py-4">
                  <a href={`/block/${block.height}`} className="text-blue-600 hover:underline font-mono">
                    {block.height}
                  </a>
                </td>
                <td className="px-6 py-4 text-gray-500">{formatDistance(block.time)}</td>
                <td className="px-6 py-4">{block.num_txs}</td>
                <td className="px-6 py-4 font-mono text-sm">{truncate(block.proposer)}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function formatDistance(time: string) {
  const seconds = Math.floor((Date.now() - new Date(time).getTime()) / 1000);
  if (seconds < 60) return `${seconds}s ago`;
  return `${Math.floor(seconds / 60)}m ago`;
}

function truncate(addr: string) {
  return `${addr.slice(0, 8)}...${addr.slice(-6)}`;
}

Indexer 数据平面查询

// 通过 MSG Indexer API 获取链上数据
export async function queryIndexer(path: string) {
  const res = await fetch(`http://localhost:8080/api/v1/indexer${path}`);
  if (!res.ok && res.status === 503) {
    throw new Error("Indexer data stale or unavailable (503 fail-closed)");
  }
  return res.json();
}

// 查询能力
const capabilities = await queryIndexer("/capabilities");
// 查询 retention proof
const retention = await queryIndexer("/retention/proof");
// 搜索交易/区块
const search = await queryIndexer("/memos/search?q=tx_hash");

3.3 微支付平台(参考 SatoshiPay / Superfluid)

合约交互

// src/contracts/micropayment.ts
import { resolveContractAddress, getSigningClient, getQueryClient } from "../lib/cosmos";

export interface MicropaymentSession {
  session_id: string;
  payer: string;
  payee: string;
  balance: number;
  rate_per_sec: number;
  status: "active" | "closed";
  charged_total: number;
}

export class MicropaymentContract {
  private address: string;
  constructor(addr: string) { this.address = addr; }

  static async create() {
    const addr = await resolveContractAddress("micropayment_session_v1");
    return new MicropaymentContract(addr);
  }

  // 创建微支付会话
  async createSession(
    mnemonic: string, sender: string,
    sessionId: string, payee: string, balance: number, ratePerSec: number
  ) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      create_session: {
        session_id: sessionId,
        payer: sender,
        payee,
        balance,
        rate_per_sec: ratePerSec,
        terms_hash: `terms_${sessionId}`,
      },
    }, "auto");
  }

  // 按秒扣费
  async chargeSession(mnemonic: string, sender: string, sessionId: string, elapsedSecs: number) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      charge_session: {
        session_id: sessionId,
        payer: sender,
        elapsed_secs: elapsedSecs,
        charge_receipt_hash: `receipt_${sessionId}_${Date.now()}`,
      },
    }, "auto");
  }

  // 关闭并结算
  async closeSession(mnemonic: string, sender: string, sessionId: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      close_session: {
        session_id: sessionId,
        payer: sender,
        close_receipt_hash: `close_${sessionId}`,
      },
    }, "auto");
  }

  // 查询会话
  async getSession(sessionId: string): Promise<MicropaymentSession> {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { get_session: { session_id: sessionId } });
  }
}

前端实时计费看板

// src/pages/MicropaymentDashboard.tsx
import { useState, useEffect } from "react";
import { MicropaymentContract } from "../contracts/micropayment";

export function MicropaymentDashboard() {
  const [session, setSession] = useState<any>(null);
  const [cost, setCost] = useState(0);

  // 模拟实时计费
  useEffect(() => {
    if (!session) return;
    const interval = setInterval(() => {
      setCost((c) => c + session.rate_per_sec);
    }, 1000);
    return () => clearInterval(interval);
  }, [session]);

  return (
    <div className="container mx-auto p-6">
      <h1 className="text-3xl font-bold mb-6">Micropayment Dashboard</h1>

      <div className="grid grid-cols-2 gap-6">
        <div className="bg-white p-6 rounded-lg shadow">
          <h2 className="text-xl font-semibold mb-4">Active Session</h2>
          {session ? (
            <div>
              <p className="text-4xl font-bold text-blue-600">{cost.toFixed(2)} MSG</p>
              <p className="text-gray-500 mt-2">Rate: {session.rate_per_sec} MSG/sec</p>
              <p className="text-gray-500">Payee: {session.payee}</p>
              <p className="text-gray-500">Balance: {session.balance}</p>
            </div>
          ) : (
            <p className="text-gray-400">No active session</p>
          )}
        </div>

        <div className="bg-white p-6 rounded-lg shadow">
          <h2 className="text-xl font-semibold mb-4">Create Session</h2>
          <form className="space-y-4">
            <input placeholder="Payee Address" className="w-full p-2 border rounded" />
            <input type="number" placeholder="Balance" className="w-full p-2 border rounded" />
            <input type="number" placeholder="Rate (MSG/sec)" className="w-full p-2 border rounded" />
            <button className="bg-blue-600 text-white px-4 py-2 rounded w-full">
              Start Session
            </button>
          </form>
        </div>
      </div>
    </div>
  );
}

3.4 AI Agent 支付网关(参考 OKX AI Agentic Payment)

Agent 支付流程

// src/contracts/agent-payment.ts
// 基于 agent_payment_v1 合约

export class AgentPaymentContract {
  private address: string;
  constructor(addr: string) { this.address = addr; }

  static async create() {
    const addr = await resolveContractAddress("agent_payment_v1");
    return new AgentPaymentContract(addr);
  }

  // AI Agent 提交支付意图
  async submitIntent(
    mnemonic: string, sender: string,
    intent: {
      payment_id: string;
      payer: string;
      payee: string;
      amount: string;
      agent_id: string;
      aidid: string;
      service_id: string;
      intent_hash: string;
    }
  ) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      submit_intent: {
        payment_id: intent.payment_id,
        payer: intent.payer,
        payee: intent.payee,
        amount: intent.amount,
        agent_id: intent.agent_id,
        aidid: intent.aidid,
        service_id: intent.service_id,
        intent_hash: intent.intent_hash,
        idempotency_key: `ip_${intent.payment_id}`,
        action: "agent_service_payment",
        budget_id: `budget_${intent.agent_id}`,
        constitution_hash: "current",
        constitution_version: "1",
        expiry_unix: Math.floor(Date.now() / 1000) + 3600,
        local_guard_hash: "guard_placeholder",
        payment_terms_hash: `terms_${intent.payment_id}`,
        policy_decision_hash: `decision_${intent.payment_id}`,
        policy_id: "default_agent_policy",
        remote_signer_id: sender,
        runtime_hash: `runtime_${Date.now()}`,
      },
    }, "auto");
  }

  // 结算支付
  async settle(mnemonic: string, sender: string, paymentId: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      settle_payment: {
        payment_id: paymentId,
        settler: sender,
        settlement_hash: `settle_${paymentId}`,
        settlement_receipt_hash: `receipt_${paymentId}`,
      },
    }, "auto");
  }
}

Agent API 集成

// src/lib/agent-payment-integration.ts
// AI Agent 通过 Agent API 自主执行支付

import { agentApi } from "./agent-api";

export async function agentToAgentPayment(
  fromAgentId: string,
  toAgentId: string,
  amount: string,
  serviceId: string
) {
  // 1. Agent 通过 Agent API 查询自身余额
  const balance = await agentApi.getBalance(`agent:${fromAgentId}`);
  if (BigInt(balance.balance) < BigInt(amount)) {
    throw new Error("Insufficient balance");
  }

  // 2. Agent 发起支付(受保护写路径,需 API Key)
  const result = await agentApi.walletTransfer(
    `wallet_${fromAgentId}`,
    `agent:${toAgentId}`,
    amount,
    "umsg"
  );

  return result;
}

3.5 Staking 仪表盘(参考 Lido / Stader)

合约交互

// src/contracts/staking.ts
export class StakingContract {
  private address: string;
  constructor(addr: string) { this.address = addr; }

  static async create() {
    const addr = await resolveContractAddress("candidate_node_staking");
    return new StakingContract(addr);
  }

  // 查询验证者列表
  async listCandidates() {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { list_candidates: {} });
  }

  // 查询质押详情
  async getStaker(address: string) {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { staker: { address } });
  }

  // 质押
  async stake(mnemonic: string, sender: string, candidate: string, amount: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      stake: { candidate, amount },
    }, "auto");
  }

  // 领取奖励
  async claimRewards(mnemonic: string, sender: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, { claim_rewards: {} }, "auto");
  }
}

3.6 DID 身份管理(参考 ENS App / SpruceID)

合约交互

// src/contracts/did.ts
export class DIDContract {
  private address: string;
  constructor(addr: string) { this.address = addr; }

  static async create() {
    const addr = await resolveContractAddress("aidid_did_registry_v1");
    return new DIDContract(addr);
  }

  async registerDID(mnemonic: string, sender: string, did: string, publicKey: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      register_did: { did, public_key: publicKey },
    }, "auto");
  }

  async resolveDID(did: string) {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { resolve_did: { did } });
  }

  async updateDID(mnemonic: string, sender: string, did: string, newPublicKey: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, {
      update_did: { did, new_public_key: newPublicKey },
    }, "auto");
  }
}

3.7 AI Agent 宪章合规面板

// src/contracts/constitution.ts
export class ConstitutionContract {
  private address: string;
  constructor(addr: string) { this.address = addr; }

  static async create() {
    const addr = await resolveContractAddress("ai_agent_constitution_v1");
    return new ConstitutionContract(addr);
  }

  // 查询 Agent 宪章状态
  async getActiveConstitution() {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { active_constitution: {} });
  }

  // 查询 Agent 是否合规
  async checkActionPolicy(agentId: string, action: string) {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, {
      check_action_policy: { agent_id: agentId, action },
    });
  }

  // 暂停 Agent(admin only)
  async pauseAgent(mnemonic: string, sender: string, agentId: string) {
    const client = await getSigningClient(mnemonic);
    return client.execute(sender, this.address, { agent_pause: { agent_id: agentId } }, "auto");
  }
}

3.8 Genesis Registry 合约地址查询

// src/lib/registry.ts
// genesis_registry_v1 是所有合约寻址的统一入口

export class RegistryContract {
  private address = "msg1genesis..."; // genesis_registry_v1 固定地址

  async resolveCanonicalKey(key: string) {
    const client = await getQueryClient();
    const result = await client.queryContractSmart(this.address, {
      get_contract_by_canonical_key: { canonical_key: key },
    });

    if (result.status === "reserved") {
      throw new Error(`Canonical key ${key} is reserved (not yet deployed)`);
    }
    return {
      address: result.contract_address,
      name: result.contract_name,
      status: result.status,
    };
  }

  async listAllMappings() {
    const client = await getQueryClient();
    return client.queryContractSmart(this.address, { list_canonical_mappings: {} });
  }

  // 快捷获取所有系统合约地址
  async getSystemContracts() {
    const keys = [
      "dao_governance", "foundation_treasury", "gas_fee_distribution",
      "candidate_node_staking", "emission_schedule", "block_time_schedule",
    ];
    const results = await Promise.all(
      keys.map((key) => this.resolveCanonicalKey(key).catch(() => null))
    );
    return Object.fromEntries(keys.map((k, i) => [k, results[i]]));
  }
}

四、DApp 开发路线图

4.1 按难度分类

难度 dApp 类型 预估工时
⭐ Agent API 简单查询面板 1-2 天
⭐ MSG 代币余额浏览器 1-2 天
⭐⭐ DAO 治理前台 3-5 天
⭐⭐ Staking 仪表盘 3-5 天
⭐⭐ DID 管理面板 2-4 天
⭐⭐⭐ 区块浏览器 1-2 周
⭐⭐⭐ 微支付平台 1-2 周
⭐⭐⭐ AI Agent 支付网关 1-2 周
⭐⭐⭐⭐ AMM DEX 2-4 周
⭐⭐⭐⭐ Agent 任务市场 2-4 周
⭐⭐⭐⭐⭐ 完整 OKX AI 复刻 8-12 周

4.2 推荐学习路径

第一步:基础查询 dApp(1-2 天)
  → 学习 cosmjs 查询
  → 实现余额/区块查询面板
  → 使用 Agent API 只读端点

第二步:链上写操作 dApp(3-5 天)
  → 实现 DAO 治理前台
  → 学习 SigningCosmWasmClient
  → 使用 genesis_registry_v1 寻址

第三步:AI Agent 集成(1-2 周)
  → 学习 Agent API 受保护写路径
  → 实现 agent_payment_v1 集成
  → 实现 ai_agent_constitution_v1 合规检查

第四步:复杂业务 dApp(2-4 周)
  → 实现任务市场/AMM/借贷等
  → 前端实时数据刷新
  → 多合约组合调用

4.3 通用开发检查清单

前置条件:
  ☐ MSG Chain 本地节点运行中(local sandbox)
  ☐ cosmjs 安装完成
  ☐ 钱包助记词已生成(BIP39/Dilithium-5)

合约地址获取(通过 genesis_registry_v1):
  ☐ 查询 canonical key 获取合约地址
  ☐ 地址不为 null(非 reserved 状态)

查询功能:
  ☐ CosmWasmClient.connect 成功
  ☐ contract query 返回正确格式
  ☐ 错误处理(合约不存在/参数错误)

写功能:
  ☐ SigningCosmWasmClient.connectWithSigner 成功
  ☐ gas 估算正常
  ☐ 交易广播成功
  ☐ receipt/tx_hash 可查

前端:
  ☐ 钱包连接(msg prefix)
  ☐ 链状态实时刷新
  ☐ 交易状态展示
  ☐ 错误状态处理

边界检查:
  ☐ 处理 reserved 状态的合约
  ☐ 处理 stub 接口(X-MSG-Stub=true)
  ☐ 处理 fail-closed(HTTP 503)
  ☐ 资金操作保留人工审批

五、AI Agent 开发入口与资源

5.1 主要 AI 入口

资源 链接
AI 控制平面(中心入口) https://msgchain.org/whitepaper/modules/ai_control_plane.html
AI Agent 接入 https://msgchain.org/whitepaper/modules/ai_agent.html
AI Task L2 https://msgchain.org/whitepaper/modules/ai_task_l2.html
AI 权限控制面 https://msgchain.org/whitepaper/modules/ai_policy_capability.html
AI 钱包 https://msgchain.org/whitepaper/modules/ai_wallet.html
Agent API 表面 https://msgchain.org/whitepaper/modules/agent_api_surface.html
合约引擎 https://msgchain.org/whitepaper/modules/contract.html
RPC 接口 https://msgchain.org/whitepaper/modules/rpc.html
创世注册中心 https://msgchain.org/whitepaper/modules/registry.html
SDK 表面 https://msgchain.org/whitepaper/modules/sdk_dev_surface.html
Indexer 数据平面 https://msgchain.org/whitepaper/modules/indexer_data_plane.html
区块浏览器 https://msgchain.org/whitepaper/modules/explorer.html

5.2 机器可读入口(适合 AI/RAG 对接)

资源 链接
Agent Entry https://msgchain.org/whitepaper/agent_entry.json
Developer Entry https://msgchain.org/whitepaper/developer_entry.json
外部 AI Agent 引导提示词 https://msgchain.org/whitepaper/integration_examples/external_ai_agent_bootstrap_prompt.md
RAG 接入流程 https://msgchain.org/whitepaper/integration_examples/rag_ingest_flow.json
Agent API OpenAPI 规范 https://msgchain.org/whitepaper/api_specs/openapi/agent_surface.yaml
合约 Reference 索引 https://msgchain.org/whitepaper/contract_reference/core_contracts.json
业务示例目录 https://msgchain.org/whitepaper/examples/business_examples/catalog.json
合约公开查询 OpenAPI https://msgchain.org/whitepaper/api_specs/openapi/public_query.yaml
合约表面 OpenAPI https://msgchain.org/whitepaper/api_specs/openapi/contract_surface.yaml
快速开始合约/dApp https://msgchain.org/whitepaper/quickstart/contract_and_dapp_minimal.json

5.3 合约 Schema 参考

每个合约公开 Cargo.toml、msg.rs 和 Schema(JSON):

https://msgchain.org/whitepaper/contract_reference/contracts/{合约名}/
├── Cargo.toml
├── src/msg.rs
└── schema/
    ├── execute_msg.json
    ├── instantiate_msg.json
    ├── query_msg.json
    └── migrate_msg.json

已有公开 Schema 的合约:

5.4 Agent API 端点完整列表

公开只读(无需 Key):

端点 功能
/agent/v1/query/account/{addr} 查询账户信息
/agent/v1/query/balance/{addr} 查询余额
/agent/v1/query/balances 查询所有余额
/agent/v1/query/tx/{hash} 查询交易
/agent/v1/query/block/{height} 查询区块
/agent/v1/query/blocks/range 查询区块范围
/agent/v1/events/history 事件历史
/agent/v1/events/subscribe WebSocket 事件订阅
/agent/v1/oracle/price 预言机价格

受保护写路径(需 API Key):

端点 功能
/agent/v1/wallet/* 钱包操作
/agent/v1/mpc/sign MPC 签名编排
/agent/v1/payment/session 支付会话

5.5 RPC/API 端点

端点族 功能 状态
/broadcast_tx_commit / sync / async 交易广播 已实现
/abci_query ABCI 查询 已实现
/tx / /block / /blockchain 链数据查询 已实现
/api/v1/blocks / txs / receipts 浏览器查询 已实现
/api/v1/contracts/deploy / instantiate / execute 合约操作 已实现
/api/v1/tx/transfer / delegate / undelegate 服务器签名的交易 已实现
/api/v1/bank/balances / staking/validators Cosmos 风格 REST 已实现
/api/v1/search?q=tx_hash_or_block_hash 哈希搜索(committed index) 已实现(503 fail-closed)
/api/v1/indexer/capabilities Indexer 能力 已实现
/api/v1/indexer/retention/proof Retention 证明 已实现

六、AI Agent 开发提示词模板

将此模板输入到任何 AI coding agent(Claude Code / Cursor / OpenClaw),可立即开始 MSG Chain dApp 开发:

你是一个 AI 开发代理,在 MSG Chain 区块链上开发 dApp。

## 链信息
- 合约引擎: CosmWasm(Rust)
- 签名: Dilithium-5(后量子)
- 地址前缀: "msg"
- ChainID: 1
- RPC: http://localhost:26657
- Agent API: http://localhost:8080/agent/v1

## 合约地址获取
通过 genesis_registry_v1 查询 canonical key:
- dao_governance → DAO 治理
- foundation_treasury → 金库多签
- gas_fee_distribution → Gas 分配
- candidate_node_staking → 质押
- agent_payment_v1 → Agent 支付
- agent_registry_v1 → Agent 注册
- aidid_did_registry_v1 → DID 身份
- ai_agent_constitution_v1 → Agent 宪章
- micropayment_session_v1 → 微支付

## 开发资源
- Developer Entry: https://msgchain.org/whitepaper/developer_entry.json
- 合约 Schema: https://msgchain.org/whitepaper/contract_reference/contracts/{合约名}/
- Agent API OpenAPI: https://msgchain.org/whitepaper/api_specs/openapi/agent_surface.yaml
- 外部 AI Agent 引导: https://msgchain.org/whitepaper/integration_examples/external_ai_agent_bootstrap_prompt.md

## 可用工具
- cosmjs: CosmWasmClient(查询)/ SigningCosmWasmClient(写)
- Agent API: /agent/v1/query/*(只读)/ /agent/v1/wallet/*(需 Key)
- Indexer API: /api/v1/indexer/*

## 实现原则
1. 优先使用 genesis_registry_v1 解析合约地址(而非硬编码)
2. 处理 reserved 状态(合约未部署时抛出明确错误)
3. 处理 stub 接口(检查 X-MSG-Stub header)
4. 处理 fail-closed(HTTP 503 时 graceful degradation)
5. 资金操作保留人工审批
6. 所有交易携带 ChainID=1 防止重放

七、DApp 类型速查表

类型 参照项目 核心合约 前端复杂度 AI 可开发性
DAO 治理 Tally.xyz dao_governance_v1 ⭐⭐ 高
金库多签 Gnosis Safe foundation_treasury_v2 ⭐⭐ 高
区块浏览器 Etherscan RPC + Indexer API ⭐⭐⭐ 中
微支付 SatoshiPay micropayment_session_v1 ⭐⭐ 高
Agent 支付 OKX AI agent_payment_v1 ⭐⭐⭐ 高
Agent 市场 OKX AI agent_registry_v1 ⭐⭐⭐ 中
DID 身份 ENS aidid_did_registry_v1 ⭐⭐ 高
Agent 宪章 — ai_agent_constitution_v1 ⭐⭐ 高
Staking Lido candidate_node_staking_v2 ⭐⭐ 高
验证者面板 — validator_qualification_v2 ⭐ 高
Gas 看板 — gas_fee_distribution_v2 ⭐ 高
代币浏览器 DeBank msg_token_cw20 ⭐ 高
AMM DEX Uniswap CosmWasm 新合约 ⭐⭐⭐⭐ 中
A2A 任务市场 OKX AI 新合约 + agent_* ⭐⭐⭐⭐ 中
数据分析 Dune Indexer API ⭐⭐⭐ 中

八、推荐开发路径

从 developer_entry.json 开始

developer_entry.json
  → recommended_dapp_bootstrap_order
    → 钱包集成(keplr / cosmjs)
    → Agent API Query 适配器
    → 回执追踪
    → 受限发布审核

快速上手顺序

第1天: 余额查询面板(Agent API /agent/v1/query/balance)
第2天: DAO 治理前台(dao_governance_v1)
第3天: Staking 仪表盘(candidate_node_staking_v2)
第4天: Agent 注册查询(agent_registry_v1)
第5天: 微支付 demo(micropayment_session_v1)
第2周: Agent 支付网关(agent_payment_v1)
第3周: 区块浏览器(RPC + Indexer API)
第4周: A2A 任务市场(新合约 + 前端)