ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linera Playground:面向 Linera 应用的浏览器内 GraphQL 调试台

Linera Playground:面向 Linera 应用的浏览器内 GraphQL 调试台 Linera Playground面向 Linera 应用的浏览器内 GraphQL 调试台【免费下载链接】linera-protocolMain repository for the Linera protocol项目地址: https://gitcode.com/GitHub_Trending/li/linera-protocol导读Linera Playground 是 Linera 协议仓库中一个纯浏览器端的 GraphQL 调试工具只需填入 faucet URL、链 IDChain ID与应用 IDApplication ID即可对已部署的 Linera 应用执行 GraphQL 查询与变更无需自行搭建前端、也无需在本地运行linera service节点。其核心技术思路是借助linera/client的 WASM 包把完整的客户端逻辑搬进浏览器——从 faucet 引导网络配置、创建Client与ChainClient、向验证者同步链状态到调用应用的 GraphQL 服务变更操作则走同一路径并由已连接的签名者签名。读完本文你将掌握 Playground 的安装运行、读写操作流程、签名者接入机制、Docker 化部署方式以及一条可在本地网络完成的端到端冒烟测试链路。1. 工具定位为什么需要 Playground依据 linera-playground/DESIGN.md 中的动机说明开发者在构建 Linera 应用时通常需要一个快速手段对已部署的应用执行 GraphQL 查询与变更而不必先定制前端或拉起本地linera service节点。linera service内置的 GraphiQL 界面通过 HTTP 与节点进程通信而 Playground 的差异在于整个客户端都运行在浏览器里通过linera/client的 WASM 包实现服务端无需安装任何额外组件。它的工作方式linera-playground/README.md输入 faucet URL、链 ID 与应用 ID输入 GraphQL 查询并运行。底层流程是在浏览器内启动一个Client为所选链创建ChainClient从验证者处同步该链再查询应用的 GraphQL 服务变更操作走同一条路径并由已连接的签名者完成签名。2. 架构与设计决策DESIGN.md 记录了关键设计决策理解这些决策有助于正确使用与二次开发 Playground网络配置以 faucet URL 输入框作为入口。Faucet.createWallet()引导出网络/创世配置genesis config之后可查询该网络上的任意链。身份与签名者用户粘贴私钥十六进制或助记词或连接 MetaMask。两者都是 EVM secp256k1 签名者owner 身份即 EVM 地址。未连接签名者时Playground 使用临时随机密钥保证只读查询可用此时变更操作自然会在验证者端被拒绝该 owner 不拥有任何链。技术栈Playground 位于顶层目录linera-playground/采用 React 18 Vite 7 TypeScript将linera/client与linera/metamask作为 workspace 包消费自带pnpm-workspace.yaml与examples/的模式一致。编辑器直接使用现成的graphiqlReact 组件配以自定义fetcher将所有操作包括驱动文档浏览器与自动补全的 introspection 查询都路由到 WASM 客户端的Application.query()。客户端生命周期每个 (faucet URL, signer) 组合保留一个常驻Clientmemoized在其上缓存Chain与Application句柄只有 faucet URL 或签名者变化时才重建。链同步linera/client原本未暴露独立的同步方法只读的query_application仅读取本地节点因此 Playground 为linera/client增加了Chain.synchronize()方法synchronize_from_validatorsupdate_wallet并在每次查询前调用。变更操作本身会在apply_client_command内部通过prepare_chain同步但只读查询需要该补充。2.1 整体架构图DESIGN.md 给出的架构示意如下React app (linera-playground/) ConfigBar SignerControls GraphiQL (graphiql pkg) faucet URL paste key / MetaMask query editor docs explorer chain id shows active owner run - response pane application id \ | | fetcher(params) \___________________|__________________________| v LineraClientManager ---- makeFetcher(manager, getTarget) (plain TS, no React) ensureClient(faucetUrl, signer) - memoized Client ensureChain(chainId, owner) - memoized Chain ensureApp(chainId, appId) - memoized Application query(target, request): chain.synchronize(); JSON.parse(app.query(JSON(request))) | linera/client (WASM) linera/metamask v Faucet - Wallet - Client - ChainClient - synchronize - Application.query - (mutation) sign propose block3. 环境要求Requirements依据 linera-playground/README.md本地开发需要Node.js 与pnpm仓库使用 pnpm workspaces。linera/client与linera/metamask位于 web/ 下的 workspace 包pnpm install会按需构建它们。这需要编译 WASM 客户端因此要求 web/rust-toolchain.toml 指定的 Rust 工具链可用。linera-playground/package.json展示了其依赖全景linera/client、linera/metamask均以workspace:*引入、graphiql^3.8.3、graphql^16.9.0、react/react-dom^18.2.0开发依赖为vitejs/plugin-react、typescript^5.5.0与vite^7.1.7。4. 安装与运行Install and run在 linera-playground/ 目录内执行cd linera-playground pnpm install pnpm dev打开终端打印的 URL默认 http://localhost:5173。package.json还提供了pnpm buildtsc vite build类型检查并打包与pnpm preview预览生产构建。需要留意 vite.config.ts 中的两项关键配置跨源隔离响应头WASM 客户端以多线程方式运行依赖SharedArrayBuffer因此 dev server 与 preview 都注入了Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin两个头缺少它们客户端将无法在浏览器中启动。fs.allowVite 需要允许从../web即 web读取 workspace 链接的linera/*包及其预编译 WASM。5. 使用指南Using it依据 linera-playground/README.md核心使用流程为Faucet URL——指定要连接的网络提供创世配置与验证者信息。对本地网络而言即由linera net up --with-faucet启动的 faucet详见第 7 节。Chain ID 与 Application ID——指定要查询的应用。点击Apply将应用的 GraphQL schema 载入编辑器支撑文档浏览器与自动补全。在切换目标后使用编辑器的 refresh-schema 按钮或再次点击Apply。输入查询用 ▶ 按钮运行。三个输入框的实现见 src/components/ConfigBar.tsxFaucet URL占位符http://localhost:8079、Chain ID、Application ID三者都填好后Apply按钮才可用。输入会持久化到localStorage键名linera-playground.config见 src/App.tsx 的loadConfig/saveConfig刷新页面后自动恢复。在 src/App.tsx 中GraphiQL 通过key{schemaToken}挂载点击Apply会自增schemaToken强制重挂载 GraphiQL从而对新的应用 schema 重新执行 introspection。6. 查询与变更Reads Mutations6.1 只读查询无需连接签名者只读查询不连接任何签名者即可执行Playground 使用一次性随机密钥ephemeral key。该逻辑在 src/linera/signers.ts 的ephemeralSigner()中实现它调用linera.signer.PrivateKey.createRandom()生成临时密钥owner为null界面上的签名者区域会显示read-only状态见 src/components/SignerControls.tsx。6.2 变更操作必须连接链的 owner要运行 mutation必须连接拥有目标链的签名者。两种方式Use key——粘贴私钥hex或助记词。privateKeySigner(secret)依据内容是否含空白字符自动判断含空白视为助记词走PrivateKey.fromMnemonic否则按 hex 构造new PrivateKey(trimmed)owner即signer.address()小写 hex作为客户端缓存的键。Connect MetaMask——通过 MetaMask 扩展签名。metaMaskSigner()先调用wallet_requestPermissions参数[{ eth_accounts: {} }]请求账户权限该调用总是弹出 MetaMask 账户选择器即使站点已授权使连接/切换账户过程显式可见随后构造linera/metamask的Signer并取地址作为 owner。mutation 的流程是构建区块并用已连接签名者签名然后提交给验证者若连接的 owner 不是该链的 owner验证者会拒绝该区块linera-playground/README.md。6.3 切换与断开签名者src/App.tsx 的useKey/useMetaMask在成功后调用manager.setSigner(active)并更新界面上的 owner 显示disconnect()则把签名者切回临时密钥owner 置为null。签名失败如 MetaMask 不可用、密钥无效时错误信息会显示在签名者区域SignerControls的error字段。7. 手动端到端测试本地网络linera-playground/README.md 给出了完整的本地冒烟测试步骤。首先在仓库根目录启动带 faucet 的本地网络并部署一个示例应用此处以 counter 为例export PATH$PWD/target/debug:$PATH eval $(linera net helper 2/dev/null) LINERA_FAUCET_PORT8079 export LINERA_FAUCET_URLhttp://localhost:$LINERA_FAUCET_PORT linera_spawn linera net up --with-faucet --faucet-port $LINERA_FAUCET_PORT # 在另一个 shell 中从 faucet 建立钱包并部署 counter 应用 # 参考 examples/counter/README.md。记录得到的 CHAIN ID 与 APPLICATION ID。然后在 Playground 中Faucet URL 填入http://localhost:8079Chain ID / Application ID 填入部署时得到的值点击Apply运行query { value }——应返回 counter 的当前值用Use key填入链 owner 的密钥然后运行mutation { increment(value: 1) }再重新运行query { value }即可看到值发生变化。counter 示例应用位于 examples/counter/其部署细节与 GraphQL 接口见 examples/counter/README.md。这一链路完整覆盖了「从 faucet 引导网络 → 同步链 → 只读查询 → 签名变更」的 Playground 核心路径。8. Docker 化部署Playground 提供自包含的 Docker 镜像从源码构建 WASM 客户端并以 nginx 提供静态站点含客户端所需的跨源隔离头。在仓库根目录构建docker build -f docker/Dockerfile.playground -t linera-playground .依据 docker/Dockerfile.playground首次构建会编译整个 workspace 到 WASM因此较慢约 15–30 分钟且需要联网获取工具链与 crates。构建要点包括使用rust:1.86-bookworm基础镜像安装protobuf-compiler供 linera-rpc 的 protobuf 代码生成、libprotobuf-dev提供 protoc 解析的 google/protobuf 头文件、clang把 secp256k1 的 C 源码编译到 wasm32、jq供linera/client的 build.bash 使用以及 Node.js 22 与 pnpm。安装与 wasm-bindgen crate 版本匹配的wasm-bindgen-cli0.2.100并下载wasm-split用于剥离 WASM否则--keep-debug构建产物约大 10 倍。按web/rust-toolchain.toml预装 nightly 工具链pnpm install --frozen-lockfile会触发linera/client的preparebuild.bash编译 WASM。构建产物dist/中的 wasm/js/css/html/svg 会以 gzip 预压缩便于 nginx 用gzip_static直接服务避免按请求实时压缩大体积 WASM 的 CPU 开销。运行docker run --rm -p 8080:80 linera-playground打开 http://localhost:8080 并在界面中设置 faucet URL、chain ID 与应用 ID。注意faucet URL 必须能被浏览器访问——可以是公共测试网 faucet也可以是暴露到宿主机的本地 faucet。生产站点由 docker/nginx.playground.conf 配置监听 80 端口、gzip_static on服务预压缩资源并注入Cross-Origin-Embedder-Policy: require-corp与Cross-Origin-Opener-Policy: same-origin头——这是多线程linera/clientWASM依赖 SharedArrayBuffer在浏览器中启动的前提。9. 底层数据流一次查询是如何跑完的点击 GraphiQL 的 ▶ 按钮会调用fetcher({ query, variables, operationName })src/linera/fetcher.ts数据流如下依据 DESIGN.md 与 src/linera/clientManager.ts目标完整性检查若 faucet URL / chain ID / application ID 未全部填齐返回友好的 GraphQL 错误Set the faucet URL, chain ID, and application ID, then run your query.避免 GraphiQL 挂载时的自动 introspection 报错刷屏。manager.query(target, request)src/linera/clientManager.ts 的LineraClientManagerensureClient以${faucetUrl}|${signer.id}为键缓存未命中时先teardown()释放旧资源再执行new Faucet(url)→createWallet()→new Client(wallet, signer)ensureChain以${chainId}|${owner}为键缓存有 owner 时调用client.chain(chainId, { owner })只读模式owner 为 null调用client.chain(chainId)chain.synchronize()——从验证者拉取最新证书synchronize_from_validatorsupdate_wallet保证查询基于最新状态ensureAppchain.application(appId)以${chainId}|${appId}缓存JSON.parse(await app.query(JSON.stringify(request)))返回响应。Application.query()针对同步后的本地状态运行应用的 GraphQL service若操作是 mutationWASM 客户端会构建、签名通过已连接签名者并提议区块后再返回。错误映射抛出的 WASM 错误faucet 无效、同步失败、验证者拒绝未授权 mutation 等统一映射为{ errors: [...] }在响应面板中渲染而非使应用崩溃src/linera/fetcher.ts 的makeFetcher。9.1 客户端生命周期与资源释放LineraClientManager的setSigner会触发teardown()依次free()所有缓存的Application与Chain句柄再对Client调用asyncDispose()释放 IndexedDB 钱包锁之后才构建新客户端失败时按 best-effort 处理不阻塞后续构建。query()中的同步耗时与查询耗时都会以[linera-playground]前缀输出到 console便于调试定位。10. 组件结构一览DESIGN.md 将代码划分为几个可独立理解的模块文件职责src/linera/clientManager.tsLineraClientManager掌管 WASM 生命周期与 memoizationsetSigner、query、内部ensureClient/Chain/App与teardownsrc/linera/signers.tsephemeralSigner()、privateKeySigner(secret)、metaMaskSigner()均返回{ id, signer, owner }src/linera/fetcher.tsmakeFetcher(manager, getTarget)把 WASM 查询适配为 GraphiQL 的 fetcher 契约并映射错误src/App.tsx持有配置与活动签名者状态把工具栏接入 manager承载GraphiQL输入持久化到localStoragesrc/components/ConfigBar.tsx / SignerControls.tsx顶部工具栏目标输入与签名者控制11. 范围与非目标依据 DESIGN.md 的明确界定范围内类型化的链 应用 查询、只读查询、自动签名的变更、私钥与 MetaMask 两种签名者、基于 introspection 的文档浏览器。范围外非目标GraphQL 订阅WASM 的Application.query()仅支持请求/响应、钱包/链管理界面、已保存查询库、多网络标签页。12. 测试现状按 DESIGN.md 的说明Playground 目前没有自动化测试手动验证linera-playground/README.md 记录了针对本地linera net up --with-faucet的端到端冒烟测试流程即第 7 节。上手建议先跑通本地网络 counter 的完整链路再用自己的应用 ID 替换即可开始调试自己的 GraphQL 服务。【免费下载链接】linera-protocolMain repository for the Linera protocol项目地址: https://gitcode.com/GitHub_Trending/li/linera-protocol创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表