无链键库公用事业
该图书馆提供课程,用于整合来自 跟踪键盘进入 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
发展收益有三种方式之一:
-
B. 拟订《公约》
@caravan/wallets图书馆本身. -
实施互动,支持新的密钥托.
-
添加或修改所支持的现有互动 键盘.
有关(1)的工作应该随着时间推移而放慢,因为图书馆已经到了 成熟的灵活性状态.
应认真考虑(2)方面的工作。 如果一个新的键盘不 支持此库中大多数现有的 API, 然后整合可能 回报率比预期要低.
关于(3)的工作应以公平的方式进行。 我们最想要的 键盘之间相互兼容。 实施特征 增加复杂性并减少相互兼容性 沮丧.
与另一个应用程序(例如:. 车队(中文(简体) )
如果您想在当地开发 @caravan/ wallets, 同时开发一个依赖于 @caravan/ wallets的应用程序, 您需要做几个步骤:
- 变动
"main": "lib/index.js"在包。 json 到"main": "src/index.ts"这一步骤是临时性的,而我们则将这一一揽子措施转化为无害环境管理. - 在这个项目的根部运行
npm link - 依赖于此软件包运行的项目根
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!:(注:!- 生成amajor递增.
提交前缀也可以包括 范围 以指定变化区域.
这个例子结合了爆炸和瞄准镜:
feat(ledger)!: add registration support
请注意,承诺信件预计将是小写,尽管范围可以有不同的外壳和大写字符(例如: PR)只要他们不开始承诺信息,就可以出现.
任何没有预设的有效前缀的约定,在尝试执行您的代码时都会被拒绝 .
让你的誓言可以辨认
然后,这些预设的承诺将被用来自动构建一个与发布相关的有用更改日志。 这意味着你的承诺不仅应该遵循上述规则,而且应该 可辨别和提供资料来啊!
提交和释放
当一个分支被合并成主机时,会读取其承诺,并解析其承诺林特前缀,以确定变化的 semver 意义(无更改,补丁,小补丁,主机)并生成一个新的更改日志文件. 脚本然后按下库版,自动更新 CHANGELOG.md 基于承诺消息的文件。 这个新的版本承诺 被推 立即掌握 之后将软件包 建造到我们的Nexus注册.