@caravan/wallets

中文文档
1.0.3发布于 2026/11/10MITTypeScriptESM + CJS构建来源已验证近 30 天下载 2047

无链首都HWI图书馆

中文使用文档
文档目录14 节
  1. 安装
  2. 使用量
  3. API 密码
  4. 应用程序
  5. 更多关于信件的内容
  6. 开发者
  7. 设置
  8. 与另一个应用程序(例如:. 车队 (中文(简体) )
  9. 开发与本地的Trezor连接
  10. 直接交互类
  11. 间接互动类
  12. 测试
  13. 字体
  14. 捐款

无链键库公用事业

Build Status

该图书馆提供课程,用于整合来自 跟踪键盘进入 JavaScript 应用程序 :

  • Trezor 硬件钱包( 型号: 1, T)
  • 编目硬件钱包(型号:Nano)
  • 隐士

完整的 API 文档可见于 @ caravan/ 钱包。 。 。 .

这间图书馆是建造和维护的 无链。 。 。 .

安装

@caravan/wallets 作为国家防范机制一揽子计划分发。 把它加进你的 应用程序的依赖性 :

$ npm install --save @caravan/wallets

使用量

此库提供课程,旨在包罗交互 应用程序和密钥,例如 - 在 a 中导出公钥 某些从Trezor型号T.的BIP32路径.

类别设计为无国籍;所有键盘交互 状态(我们目前是和Trezor说话吗?)是打算被存储的 由调用应用程序.

这些课也会向合适的开发者提供消息 用于在用户界面中显示。 所有错误也会被过滤 到开发者处理他们认为合适的.

API 密码

以下顶级功能是此API的切入点:

  • GetMetadata({keystore}) - 获取设备的元数据
  • ExportPublicKey({keystore, network, bip32Path}) - 导出一个 HD 公钥
  • ExportExtendedPublicKey({keystore, network, bip32Path}) - 输出一个扩展的HD公钥
  • SignMultisigTransaction({keystore, network, inputs, outputs, bip32Paths}) - 用一些多相码输入签名交易
  • ConfirmMultisigAddress({keystore, network, bip32Path, multisig}) - 确认一个多西格地址

不是每个密钥都由这个库支持 执行其中的每个 互动.

每一次互动都需要不同的论据。 见 API 密码 文档 详细情况.

应用程序

以下最小反应示例显示应用程序开发者如何 将使用 ExportPublicKey 此库的 API 函数导出 一个来自Trezor硬件钱包的公钥.

// This is a React example but a similar
// pattern would work for other frameworks.
import React from "react";
import PropTypes from "prop-types";

// The `@caravan/bitcoin` library is used by `@caravan/wallets`.
import { MAINNET } from "@caravan/bitcoin";

import {
  // This is the interaction we are implementing.
  ExportPublicKey,

  // These are the keystores we want to support.  They both
  // work identically as far as this minimal UI is concerned.
  // Other keystores are supported but they would require a
  // different UI.
  TREZOR,
  LEDGER,

  // These are  possible states our keystore could be in.
  PENDING,
  ACTIVE,
  UNSUPPORTED,
} from "@caravan/wallets";

export class HardwareWalletPublicKeyImporter extends React.Component {
  // For this example, the required arguments are
  // passed into this component via `props`.
  //
  // A more realistic example would provide a UI for
  // entering this or pull it from somewhere else.
  static propTypes = {
    network: PropTypes.string.isRequired,
    bip32Path: PropTypes.string.isRequired,
    keystore: PropTypes.string.isRequired,
  };

  // The interaction is stateless so can be instantiated
  // on the fly as needed, with appropriate arguments.
  interaction() {
    const { keystore, network, bip32Path } = this.props;
    return ExportPublicKey({ keystore, network, bip32Path });
  }

  constructor(props) {
    super(props);
    // Keystore state is kept in the React component
    // and passed to the library.
    this.state = {
      keystoreState: this.interaction().isSupported() ? PENDING : UNSUPPORTED,
      publicKey: "",
      error: "",
    };
    this.importPublicKey = this.importPublicKey.bind(this);
  }

  render() {
    const { keystoreState, publicKey, error } = this.state;
    const { bip32Path } = this.props;
    if (publicKey) {
      return (
        <div>
          <p>Public key for BIP32 path {bip32Path}:</p>
          <p>
            <code>{publicKey}</code>
          </p>
        </div>
      );
    } else {
      return (
        <div>
          <p>Click here to import public key for BIP32 path {bip32Path}.</p>
          <button
            disabled={keystoreState !== PENDING}
            onClick={this.importPublicKey}
          >
            Import Public Key
          </button>
          {this.renderMessages()}
          {error && <p>{error}</p>}
        </div>
      );
    }
  }

  renderMessages() {
    const { keystoreState } = this.state;
    // Here we grab just the messages relevant for the
    // current keystore state, but more complex filtering is possible...
    const messages = this.interaction().messagesFor({ state: keystoreState });
    return <ul>{messages.map(this.renderMessage)}</ul>;
  }

  renderMessage(message, i) {
    // The `message` object will always have a `text` property
    // but may have additional properties useful for display.
    return <li key={i}>{message.text}</li>;
  }

  async importPublicKey() {
    this.setState({ keystoreState: ACTIVE });
    try {
      // This is where we actually talk to the hardware wallet.
      const publicKey = await this.interaction().run();
      // If we succeed, reset the keystore state
      // and store the imported public key.
      this.setState({ keystoreState: PENDING, publicKey });
    } catch (e) {
      // Something went wrong; revert the keystore
      // state and track the error message.
      this.setState({ keystoreState: PENDING, error: e.message });
    }
  }
}

这个简单的例子说明了几个有用的模式:

  • 这个 interaction() 方法从 相关参数, bip32Path 财务报告和审定财务报表 network。在这个中 这些参数通过 props 但是他们可以 由用户或服务器应用程序指定。 互动 对象没有内部状态, 并且可以便宜地创建, 从而构建它 "新鲜"每次需要都很好 实际上是首选 办法.

  • 这个 keystoreState 由反应存储并控制 组件。 单位 importPublicKey 组件明确处理 更改为 keystoreState内 renderMessages 构成部分 查询信件的交互关系,在当前中传递 keystoreState 作为过滤器.

  • 这个 messagesFor 财务报告和审定财务报表 renderMessages 方法不管怎样都会起作用 数值 network, (中文(简体) ), bip32Path,或 keystore。如果用户 允许更改这些输入值、适当的警告和 将为每个密钥发送信息信息 参数。 这使得处理键盘店之间的“边缘案例”变得非常多 用于开发者.

更多关于信件的内容

与键盘的互动通过执行对象进行调解 页:1 Interaction API (英语). 此 API 可通过 页:1 messages() 以及相关方法.

这个 messages() 方法返回关于 互动。 应用程序调用 messages() 预计将 在密钥上通过 state,以及其他过滤属性.

一个消息在 messages() 数组是一个对象,其对象如下: 键 :

  • code -- 描述信件的点分隔字符串( 例如 ) device.connect(中文(简体) )
  • state -- 密钥显示信件的用途( 例如 --) pending, (中文(简体) ), active,或 unsupported(中文(简体) )
  • level --消息的级别(例如 --) info, (中文(简体) ), warning,或 error(中文(简体) )
  • text -- 信息文本(例如 --) Make sure your Trezor hardware wallet is plugged in.(中文(简体) )
  • version -- (可选)描述此消息适用于哪个版本的密钥的版本字符串或范围/规格
  • image --(可选)对象 label, (中文(简体) ), mimeType,和基数64编码 data 图像
  • steps -- (可选) 此消息的一系列子消息 . code, (中文(简体) ), state,以及 level 为子消息可选.

信件是分级和结构良好的,允许应用程序到 显示它们.

几种方法,如: hasMessage, (中文(简体) ), messageTextFor(), & c. 是 可用于过滤和提取信件中的数据.

见 API 密码 文档 详细信息.

开发者

关于类型问题的简短说明

此库已移植到 TypeScript 上 。 这个过程发现了不少 输入不良病例。 在许多情况下,这种类型的结合可能是其他的复杂结合 类型。 目前,这些类型的定义是: any但请注意: 使用 any 并不是最佳做法,今后应取消。 这个 需要重构类型 .

设置

想要在此库工作的开发者应该克隆源代码 代码和安装依赖性 :

$ git clone https://github.com/caravan-bitcoin/caravan/packages/caravan-wallets`
...
$ cd @caravan/wallets
$ npm install

发展收益有三种方式之一:

  1. B. 拟订《公约》 @caravan/wallets 图书馆本身.

  2. 实施互动,支持新的密钥托.

  3. 添加或修改所支持的现有互动 键盘.

有关(1)的工作应该随着时间推移而放慢,因为图书馆已经到了 成熟的灵活性状态.

应认真考虑(2)方面的工作。 如果一个新的键盘不 支持此库中大多数现有的 API, 然后整合可能 回报率比预期要低.

关于(3)的工作应以公平的方式进行。 我们最想要的 键盘之间相互兼容。 实施特征 增加复杂性并减少相互兼容性 沮丧.

与另一个应用程序(例如:. 车队(中文(简体) )

如果您想在当地开发 @caravan/ wallets, 同时开发一个依赖于 @caravan/ wallets的应用程序, 您需要做几个步骤:

  1. 变动 "main": "lib/index.js" 在包。 json 到 "main": "src/index.ts" 这一步骤是临时性的,而我们则将这一一揽子措施转化为无害环境管理.
  2. 在这个项目的根部运行 npm link
  3. 依赖于此软件包运行的项目根 npm link @caravan/wallets

当你开始你的应用程序时, 无论你使用什么组合器(Vite,Webpack等), 都应该编译这个软件包.

开发与本地的Trezor连接

如果你出于某种原因需要使用 trezor 连接的本地实例 @ caravan/ 钱包用于连接的模块需要初始化 带有自定义 connectSrc 选项。 要自动启用, 请确定 启动 @caravan/ wallets 正在运行的进程 TREZOR_DEV 环境变量设置为 true (例如:. TREZOR_DEV=true npm run start) (中文(简体) ).

目前, 这将让 Trezor 交互器在 https://localhost:8088 这是默认。 自定义端口目前不支持 .

直接交互类

一些设备(如Trezor)支持"直接"交互- JavaScript代码可以直接从设备中获取响应.

实施此类互动的开发者应分级 DirectInteraction 并提供一个 async run() 执行的方法 键盘和返回所需数据.

间接互动类

一些设备(例如基于QR编码的空加式笔记本电脑)支持 "间接"交互 - JavaScript 代码不能直接获得 由设备响应。 用户必须手动转发请求和 然后分别输入一个响应.

实施此类互动的开发者应分级 IndirectInteraction 并提供两种方法:

  • request() 返回请求中的适当数据
  • parse(response) 用于解析响应

测试

单位测试在Vitest进行,可通过

$ npm test

字体

这个库最初是使用 JavaScript 建造的,并用 Babel 转接.

移动到Typescript中有一些明显的好处,因此从那时起 我们开始逐渐迁移到这个 是一个Typescript项目.

在可行的情况下,今后所有贡献都应扩大使用Typescript,作为 尽可能. .js 文件应转换为 .ts 和错误 有必要.

为了方便逐渐迁移, bayl 仍然用于转接 时 tsc 负责类型检查和建立申报文件。 见 这里 更多信息.

由于这一决定对建设过程的一些限制, 也就是说 孤立的摩多尔中,“全球”类型按 types/ 目录 而不是其他一些更常见的模式.

我们可能尽可能改变建设过程,以完全依靠 tsc 那时,一些 可以改变配置以及类型申报的管理.

捐款

解链欢迎错误报告,新功能,以及此库更好的文档.

如果您正在修复错误或添加特性, 请先检查 GitHub 问题页面 以了解是否对此进行过任何讨论.

为了作出贡献,在 GitHub 上创建一个拉动请求(PR),以对抗 @ caravan/ wallets 的无链叉。 。 。 .

在提交公关前,确保更新并运行测试套房!

提交折叠

在此寄存器中的提交将自动用 常规武器委员会 规则。 这有助于代码清晰度,自动生成一个有用的更改日志,并更改语义发布版本,以说明打破更改的原因.

以下前缀将生成版本凸起 :

  • fix: - 产生一个 patch 在 lib 版本中递增.
  • feat: - 产生一个 minor 在 lib 版本中递增.
  • feat!:, (中文(简体) ), fix!:,以及 refactor!: (注: !- 生成a major 递增.

提交前缀也可以包括 范围 以指定变化区域.

这个例子结合了爆炸和瞄准镜:

feat(ledger)!: add registration support

请注意,承诺信件预计将是小写,尽管范围可以有不同的外壳和大写字符(例如: PR)只要他们不开始承诺信息,就可以出现.

任何没有预设的有效前缀的约定,在尝试执行您的代码时都会被拒绝 .

让你的誓言可以辨认

然后,这些预设的承诺将被用来自动构建一个与发布相关的有用更改日志。 这意味着你的承诺不仅应该遵循上述规则,而且应该 可辨别和提供资料来啊!

提交和释放

当一个分支被合并成主机时,会读取其承诺,并解析其承诺林特前缀,以确定变化的 semver 意义(无更改,补丁,小补丁,主机)并生成一个新的更改日志文件. 脚本然后按下库版,自动更新 CHANGELOG.md 基于承诺消息的文件。 这个新的版本承诺 被推 立即掌握 之后将软件包 建造到我们的Nexus注册.

版本与发布记录

@caravan/wallets 共发布 40 个版本,首次发布于 2024/02/13;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.3latest2026/11/10今天
1.0.22026/11/072 天前
1.0.12026/11/036 天前
1.0.02026/11/019 天前
0.11.02026/08/222 个月前
0.10.12026/07/213 个月前

关于 @caravan/wallets 的常见问题

@caravan/wallets 是什么?

无链首都HWI图书馆

如何安装 @caravan/wallets?

在项目目录运行 npm install @caravan/wallets,或使用 pnpm add / yarn add / bun add。

@caravan/wallets 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@caravan/wallets 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@caravan/wallets 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@caravan/wallets 可以商用吗?

@caravan/wallets 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@caravan/wallets 的下载量有多少?

根据 npm 官方下载统计,@caravan/wallets 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,047 次,日均约 68 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@caravan/wallets 还在维护吗?

最新版本 1.0.3 发布于 2026/11/10(今天);至今共发布 40 个版本,其中过去 12 个月发布了 12 个;首次发布于 2024/02/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。