ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

FinceptTerminal 钱包页第三方 JS 库的 vendoring 策略:@solana/web3.js 的离线供应链管理与刷新指南

FinceptTerminal 钱包页第三方 JS 库的 vendoring 策略:@solana/web3.js 的离线供应链管理与刷新指南 FinceptTerminal 钱包页第三方 JS 库的 vendoring 策略solana/web3.js 的离线供应链管理与刷新指南【免费下载链接】FinceptTerminalFinceptTerminal is a modern finance application offering advanced market analytics, investment research, and economic data tools, designed for interactive exploration and>项目地址: https://gitcode.com/GitHub_Trending/fi/FinceptTerminalFinceptTerminal 的 Solana 钱包功能连接钱包、签名交易以 HTML 页面形式运行在 Qt 的QWebEngineView中而 fincept-qt/resources/wallet/vendor/README.md 正是这份依赖管理的供应契约——它规定了第三方 JavaScript 库必须以内置vendored方式随仓库提交、从qrc://资源系统加载、绝不在运行时联网获取。读完本文你将掌握 FinceptTerminal 钱包页的 CSP 安全模型、web3.js bundle 的来源与版本要求、完整的刷新与校验流程以及这些约定在connect.html/swap.html两个钱包页面中的实际落地方式。目录定位钱包页离线依赖的唯一入口在 FinceptTerminal 仓库中钱包相关资源统一放在 fincept-qt/resources/wallet/ 下当前包含两个页面与一个依赖目录路径作用fincept-qt/resources/wallet/connect.html连接钱包页检测 Phantom / Solflare / Backpack / Glow 等浏览器钱包扩展请求授权并完成挑战签名fincept-qt/resources/wallet/swap.html交易签名页从本地 bridge 拉取待签交易体交给用户钱包签名并回传结果fincept-qt/resources/wallet/vendor/README.md本文档vendored 第三方库的管理约定vendor/目录的职责由 README 明确界定它存放钱包 HTML 页面在加载时嵌入的第三方 JavaScript bundle所有文件逐字节verbatim提交进仓库通过 Qt 资源系统qrc://提供运行期永不发起外部网络请求。为什么必须 vendored严格 CSP 下的必然选择README 给出了核心设计约束——钱包页面运行在QWebEngineView内并施加了严格的内容安全策略CSP其中connect-src self意味着页面只能向自身源发起连接类请求。在这一约束下若引入一个需要运行时从网络加载的库只有两条路放宽 CSP允许加载外域脚本——这会直接扩大攻击面让页面暴露给任意 CDN 或中间人篡改的风险自建 loader 代理在本地起一个转发服务替页面取资源——同样引入了额外的网络组件与信任边界。README 明确评价这两种方案都会enlarge the attack surface因此选择了第三条路把我们要交付的精确字节the exact bytes we ship直接打进仓库。离线加载意味着页面在无网络环境下依然可用且供应链上只有我们提交的这份文件这一个可信点。从实际页面看这一约定确实被执行swap.html 头部直接以script srcvendor/web3.js/script引用本地 bundle而 connect.html 的 CSP 声明为default-src self; script-src self unsafe-inline; style-src self unsafe-inline; connect-src self http://127.0.0.1:* http://localhost:*; img-src self data:;可以推断connect-src额外放行本机回环地址127.0.0.1/localhost任意端口是为了让页面能够与本机钱包 bridge 服务/log、/callback、/tx、/result等接口通信但脚本与样式资源依然只允许来自自身源——vendored 机制正是为了在不放开script-src的前提下满足这一安全模型。必需文件web3.jssolana/web3.js UMD bundleREADME 规定了vendor/目录当前唯一必需的第三方文件项目约定值文件名web3.js来源solana/web3.js官方 UMD 构建solana-labs/solana-web3.js releases 页面版本预期1.95.xPhase 2 计划中的最新 1.x 稳定版体积约 150 KBminified模块暴露方式UMD 构建在全局定义window.solanaWeb3这是钱包 HTML 的调用入口UMDUniversal Module Definition构建之所以被选中是因为它不依赖打包器、直接以全局变量暴露 API与页面内联脚本直接使用的架构完全契合。需要说明的是从当前仓库快照的文件列表看vendor/目录下只包含这份 READMEweb3.js文件本身需要按下文流程补充swap.html 已预留了vendor/web3.js的引用与缺失时的降级路径。web3.js 在页面中的实际用途swap.html 展示了这个全局入口的核心消费方式——交易签名流程// 首选路径通过 vendored web3.js 反序列化 VersionedTransaction再交给钱包签名 if (window.solanaWeb3 window.solanaWeb3.VersionedTransaction) { const tx window.solanaWeb3.VersionedTransaction.deserialize(txBytes); if (typeof provider.signAndSendTransaction function) { const r await provider.signAndSendTransaction(tx); signature (r r.signature) ? r.signature : r; } else if (typeof provider.signTransaction function) { // 部分钱包只暴露 signTransaction——签名后的字节回传给调用方转发 RPC const signed await provider.signTransaction(tx); const serialised signed.serialize(); signature BYTES: bytesToBase64(serialised); } }这里的VersionedTransaction.deserialize()来自window.solanaWeb3即 vendored 的 web3.js。若该文件缺失页面会退化为base64 直通路径provider.signAndSendTransactionRaw并在失败时提示 vendored solana/web3.js missing — see resources/wallet/vendor/README.md——这条错误信息直接把用户引导回本文档可见 README 是这一供应链机制的权威说明。如何刷新 bundle四步官方流程README 给出了刷新 web3.js 的完整操作步骤这是维护者升级依赖时的标准动作下载官方 UMD 发布物从 solana-web3.js 的 GitHub releases 页面下载对应版本的 IIFE 构建例如https://github.com/solana-labs/solana-web3.js/releases/download/v1.95.X/solana-web3.iife.js拷贝入目录将该文件复制到vendor/目录命名为web3.js校验并记录执行sha256sum web3.js将哈希值、版本号、日期记录到下方版本日志表中然后才提交复查 CSP如果新版本需要新增任何网络源正常不应发生——bundle 是自包含的则同步更新钱包 HTML 的 CSP。其中第 3 步是安全关键环节sha256sum的哈希核对保证了进入仓库的文件与上游发布物逐字节一致杜绝了传输过程被篡改的可能而先记录后提交则让每一次依赖变动都可审计、可回溯。版本日志每一次依赖变动的审计痕迹README 内嵌的版本日志表是供应链管理的账本每次刷新 bundle 都必须追加一行Dateweb3.js versionsha2562026-04-281.95.8 (IIFE minified, via unpkg)a759deca1b65df140e8dda5ad8645c19579536bf822e5c0c7e4adb7793a5bd08从表格可见当前锁定版本为1.95.8获取渠道为 unpkg 上的 IIFE minified 构建其 SHA-256 为上述 64 位十六进制字符串。任何升级都应新增一行而非覆盖旧行从而保留完整的依赖演进历史。边界约束这个目录不是什么README 以反例方式划定了vendor/目录的职责边界这三条约定对保持 Qt 项目构建纯净至关重要不是运行时 CDN绝不允许页面在运行时从 CDN 拉取库文件与connect-src self的 CSP 模型冲突不是 npm 项目绝不在该目录运行npm install——Qt 的 CMake 构建体系中不应引入 Node 依赖不是 TypeScript 编译输出这里只托管预构建pre-builtbundle不存放编译中间产物。此外 README 还留下一条治理规则如果需要引入某个不提供可直接手工构建的 UMD bundle的库必须先与 wallet-bridge 的负责人沟通——因为给 Qt 项目增加一个 Node 构建依赖是serious decision。这从侧面说明vendored 策略不仅是安全选择也是构建架构的刻意取舍。供应链约定背后的钱包交互全景虽然本文聚焦于vendor/的依赖管理但把 README 与两个页面源码对照阅读可以更完整地理解这套离线机制的服务对象。钱包连接与签名采用挑战-响应 本地 bridge 回环通信的模式connect.html 通过resolveProvider()按约定探测各钱包注入的全局对象window.phantom.solana、window.solflare、window.backpack、window.glowSolana及通用的window.solana向用户展示detected / not installed状态连接后页面要求钱包对Fincept Terminal wallet-connect challenge. Nonce: nonce消息签名把pubkey、Base58 编码的 64 字节签名、钱包 label 通过POST /callback?token...回传本地 bridge页面内置了一套零依赖的 Base58 编码器注释明确说明参考 bitcoin core / bs58 包转写避免输入含前导零字节时朴素实现的Invalid array length溢出因此 challenge 签名验证流程本身不依赖 web3.js——web3.js 只服务swap.html的 VersionedTransaction 反序列化。C 侧的钱包能力则由services/wallet/下的 WalletService.h被 CryptoCenterScreen.cpp 等大量界面组件引用提供HTML 页面通过回环 HTTP 与其协作共同构成私钥永不出钱包、终端只读取公钥与余额的安全边界。小结FinceptTerminal 用一份 49 行的 README把钱包页第三方依赖这一高风险区域约束成了清晰可执行的工程规范vendored 是手段离线、逐字节、可哈希校验严格 CSP 是动机不放松connect-src self不引入 loader 代理版本日志是纪律每次刷新留痕。对于任何在嵌入式 WebView 中集成区块链钱包能力的桌面应用这套预构建 UMD sha256 校验 版本台账 明确目录边界的供应链管理模式都是一份可以直接借鉴的样板。【免费下载链接】FinceptTerminalFinceptTerminal is a modern finance application offering advanced market analytics, investment research, and economic data tools, designed for interactive exploration and>项目地址: https://gitcode.com/GitHub_Trending/fi/FinceptTerminal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进