@chainrender /客户端
ChainRender的off-chain钩子层。它做两件事:
- 渲染 一个链上组件通过free
eth_call(没有钱包,没有汽油)。 - 绑定 组件的数据绑定 槽 实时值(余额、ENS名称、网络、 tx状况)。
它的核心是框架无关和无依赖的(它直接使用JSON-RPC) 手工完成所需的少量ABI编码/解码)。一个React适配器作为 单独的入口点。这反映了Scaffold-ETH是如何将wagmi -薄的、输入的帮助程序包裹在 下面的东西-除了“下面的东西”是ChainRender的链上解释器。
快速入门
安装:
npm install @chainrender/client viem
在10行左右的时间内将链上组件渲染为HTML -没有钱包,没有gas,只是一个免费的 eth_call:
import { renderComponent, bindSlots, staticResolvers, makeProviderResolvers } from "@chainrender/client";
import { createPublicClient, http } from "viem";
import { sepolia } from "viem/chains";
const deployment = {
rpc: "https://ethereum-sepolia-rpc.publicnode.com",
router: "0x0322b911900cb42694899eb06469c786f52e064c", // RenderRouter
registry: "0x36a443515b96b992ee397dfd9a533de72b70c3c9", // ComponentRegistry
};
// 1. render the component (by its content hash) to an escaped HTML string
const html = await renderComponent(deployment, "0x…componentHash");
// 2. mount it in an isolated shadow root
const shadow = document.getElementById("app").attachShadow({ mode: "open" });
shadow.innerHTML = html;
// 3. fill any live data-binding slots (balances, ENS, tx status)
const publicClient = createPublicClient({ chain: sepolia, transport: http(deployment.rpc) });
await bindSlots(shadow, { ...staticResolvers, ...makeProviderResolvers(publicClient) });
这就是整个循环: 链上渲染→挂载→绑定实时数据。 viem 是一个对等依赖(任何兼容的提供商都可以工作);React和Farcaster迷你应用适配器是可选的入口点(见下文)。要发现组件散列,请对注册表的散列建立索引 ComponentRegistered 事件,或使用 enumerate(deployment) 获取一个快速的概念验证列表。
为什么槽
ChainRender组件是不可变的,内容寻址的,并且存储在链上,所以是实时数据 (每个区块都会改变的余额,通过CCIP-Read解析的ENS名称)无法被纳入 他们。相反,链上解释器发出 槽 -一个转义的占位符,如:
<span class="cr-slot cr-slot-balance" data-cr-bind="balance" data-cr-arg="0x…">—</span>
占位符呈现其回退,直到此库填充它为止。ENS和balance绑定 本质上是客户端,因为合约不能执行CCIP-Read HTTP 需求;这就是链下层与链上解析器钩子一起存在的全部原因。
核心用法(任何框架)
import { renderComponent, bindSlots, staticResolvers, makeProviderResolvers } from "@chainrender/client";
const deployment = { rpc: "https://…", router: "0x…", registry: "0x…" };
// 1. render on-chain -> escaped HTML string
const html = await renderComponent(deployment, componentHash);
// 2. mount into an isolated container (shadow root recommended)
const host = document.createElement("div");
const shadow = host.attachShadow({ mode: "open" });
shadow.innerHTML = html;
// 3. fill the slots with live data (pass a viem PublicClient, or any compatible provider)
await bindSlots(shadow, { ...staticResolvers, ...makeProviderResolvers(publicClient) });
enumerate(deployment) 列出已注册的组件(链上的概念验证枚举
生产应用程序应该索引注册表 ComponentRegistered 事件相反)。
反应的使用
import { ChainRenderView, useChainRenderComponent } from "@chainrender/client/react";
import { staticResolvers, makeProviderResolvers } from "@chainrender/client/resolvers";
const resolvers = { ...staticResolvers, ...makeProviderResolvers(publicClient) };
<ChainRenderView deployment={deployment} hash={hash} resolvers={resolvers} styleSheet={themeCss} />
styleSheet 接受从ChainRender Explorer导出的off-chain主题样式表,因此
该组件选择你的颜色和字体比例。 react 是一个可选的对等依赖;这个
核心入口没有框架依赖。
内置槽位绑定
staticResolvers 覆盖不需要链访问的绑定(address, networkName,
avatar 占位符, txStatus 回退)。 makeProviderResolvers(provider) 添加活的
(balance, ensName, ensNameOrAddress, avatar, networkName),使用兼容的浏览器
提供者。通过扩展解析器映射来添加您自己的映射-键是插槽的 data-cr-bind
种类。
第一方链上解析器类型
与上面的客户端运行时解析器(填充浏览器中的槽)不同,有些槽
绑定到 链上 解析器 种类. ChainRender提供了一个大型的第一方集合- DeFi, oracle,
凭据、ENS、认证、RWA、声誉、CCIP、消息传递、结算、跨链证明等等
中列出的 RESOLVER_KINDS 和 vocabulary().resolverKinds (类型、参数、数据边缘、能力、注释)和暴露
每个家庭 kinds,用他们的 KIND_* 常量和参数编码器,例如:
kinds.oracle- oracle feeds (KIND_FEED,encodeFeedArgs)。kinds.credential/kinds.credentialBound-选择性披露和绑定一次性凭证。kinds.ens- - - - - -encodeAddrArgs(node),encodeTextArgs(node, key),encodeNameArgs(address),encodeV2Args(resolver, inner, isText)与v2AddrCall/v2TextCall.
对插槽进行编码 arg 正如它的描述所言: abi.encode 时的原始字节
描述符有 argsEncoding: "packed" (ensName 正好占用20个地址字节)。完整的名单在
https://chainrender.org/docs/reference/resolver-kinds.html. 解析器类型有 第一方但可扩展 -你可以部署你的
自己的解析器服务于一种新的类型;这是一组ChainRender船只,而不是一个封闭的词汇表。
在编译树之前检查它
compile() 静默地丢弃它不读取的任何东西——未知字段、不在字典中的枚举值
(role: "note"),图像上的所有字段; args 在批处理成员上。 checkNode(tree) 报告每个路径
并强制节点/深度/大小限制; nodeJsonSchema() 与AI工具的严格JSON模式规则相同。
import { checkNode, nodeJsonSchema } from "@chainrender/client";
const r = checkNode(tree); // { ok, issues: [{ path, code, message }], nodeCount, depth }
安全
bindSlots 集合 textContent,因此解析后的值将作为文本插入,而不会被解析为
超文本标记语言。解释器的输出已经被转义了。渲染成一个阴影根或沙盒
框架下严格的内容安全策略,而不是天真的 innerHTML 有特权的人
页面。
安装和网络
npm install @chainrender/client viem
viem 是一个对等依赖。包裹是 chain-agnostic -它没有地址,没有
chainId,没有RPC。从部署中注入客户机/RPC和契约地址,因此
同样的包可以在Sepolia, mainnet或任何L2上工作:
import { createPublicClient, http } from "viem";
import { sepolia } from "viem/chains";
const client = createPublicClient({ chain: sepolia, transport: http(RPC_URL) });
// point renders/binds at the addresses from your deployment's addresses.json
Sepolia注释(数据,而不是代码):使用Sepolia部署的地址;如果组件绑定了Chainlink feed,使用Sepolia feed地址(或部署的模拟)——一个主网feed地址在Sepolia上返回;和 ENS可以机械地进行解析,但塞波利亚的注册名称要少得多。
构建
npm run build # tsc -p tsconfig.build.json → self-contained dist/
构建过程将客户端与控件一起编译 chainc/ 镜像分为 dist/,所以出版了
包中没有可以转义它的导入。 prepublishOnly 在之前自动运行 npm publish.
发行方式:Farcaster迷你应用/标准网页应用
@chainrender/client/miniapp 是一个薄的,失败封闭的包装,呈现一个ChainRender应用程序作为一个
Farcaster迷你应用程序 和 一个普通的标准web应用程序。链上渲染是底层的工作
独立的;迷你应用层(嵌入标签,FID / Sign In With Farcaster,通知,钱包)是
渐进式增强,在Farcaster主机外无操作。
import { buildManifest, buildEmbedMetaTags, capabilitiesForEnvelope } from "@chainrender/client/miniapp";
import { mountChainRenderApp, signInWithFarcaster } from "@chainrender/client/miniapp";
// build /.well-known/farcaster.json (add the account association from the Farcaster dev tools)
const manifest = buildManifest({
name: "My Component", homeUrl: "https://my.app", iconUrl: "https://my.app/icon.png",
requiredChains: ["eip155:11155111"], // Sepolia
requiredCapabilities: capabilitiesForEnvelope(envelope), // carries the ChainRender capability honesty
});
// in the page: render the on-chain floor, then signal the host
await mountChainRenderApp(async () => { /* inject the eth_call HTML into the DOM */ });
@farcaster/miniapp-sdk 是一个 可选 对等依赖,惰性加载-适配器构建和
运行没有它(标准的web应用程序模式)。看到 examples/miniapp-wrapper.html 对于一个完整的页面
是一款网页应用,也是一款迷你应用。