签名声明是一种多功能工具,用于请求用户使用与其 DID 关联的私钥对任意数据进行签名。此加密签名作为用户已查看并批准该数据的不可否认的证明,有效地展示了对其数字身份的控制权。常见用例包括签署消息、授权交易或确认委托。
对于更复杂的支付场景,其中钱包需要为交易提供输入,请考虑使用 Prepare Transaction Claim。
工作原理
应用程序构造一个 signature 声明,详细说明需要签署的内容。这包括数据本身(作为原始字符串或预计算的摘要)、数据类型(帮助钱包正确显示)和哈希方法。DID Wallet 接收此请求,向用户呈现信息以供确认,并在批准后对数据进行签名,并将签名返回给应用程序进行验证。
参数
signature 声明对象接受以下参数:
| Parameter | Type | Description |
|---|---|---|
typeUrl | string | 必需。 指定数据类型。这有助于钱包正确解释和显示内容。常见值包括 mime:text/plain、mime:text/html、fg:t:transaction(用于 Forge 编码的交易)或特定的交易类型,如 TransferV2Tx。 |
origin | string | 要签名的原始数据,编码为 Base58 字符串。当您希望钱包查看并哈希完整数据时使用此参数。您应提供 origin 或 digest 之一。 |
digest | string | 数据的预计算哈希。当原始数据太大无法发送,或者您不需要钱包查看原始内容时使用此参数。 |
method | string | 钱包在签名之前应对 origin 数据应用的哈希算法。默认为 sha3。如果设置为 'none',钱包将直接对 origin 数据进行签名,而不会先进行哈希处理。 |
display | string | 一个 JSON 字符串,用于在钱包中提供丰富的显示,例如显示格式化的消息或链接。示例:JSON.stringify({ type: 'url', content: 'https://www.arcblock.io' })。 |
description | string | 一个用户友好的消息,解释要求用户签署的内容。默认为 '请签署此交易或消息以继续操作。'。 |
requirement | object | 一个可选对象,指定用户必须满足的代币或资产要求才能提供签名。 |
nonce | string | 一个可选的随机字符串,用于防止重放攻击。 |
使用示例
以下是几个请求不同类型签名的示例。
1. 签署纯文本消息
这是最简单的用例,您要求用户签署一个简单的文本字符串。
请求文本签名
const claims = {
signature: {
typeUrl: 'mime:text/plain',
description: '请签署此消息以验证您的身份。',
data: '我同意条款和条件。',
},
};
// 在您的处理程序中
const { authInfo } = await authenticator.sign({
claims,
// ... 其他参数
});在此示例中,data 字符串将被转换为 Buffer,以 Base58 编码,并作为 origin 字段发送到钱包。
2. 签署交易(来自原始数据)
对于链上操作,您可以要求用户签署交易。您可以提供原始交易对象,DID Connect 将为您处理编码。这需要在您的 WalletAuthenticator 实例中配置 chainInfo。
请求交易签名
const claims = {
signature: {
// 这是 @ocap/client 已知的特定交易类型
type: 'TransferV2Tx',
description: '请签名以确认转移 100 TBA。',
display: JSON.stringify({ type: 'html', content: '<div>将 <b>100 TBA</b> 转移给接收方</div>' }),
// 原始交易数据对象
data: {
itx: {
to: 'z123...',
tokens: [
{
address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt',
value: '100',
},
],
},
},
// 可选:为钱包指定代币要求
requirement: {
tokens: [
{
address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt',
value: '100',
},
],
},
},
};在后台,WalletAuthenticator 将使用 @ocap/client 将 data 对象编码为交易缓冲区。发送到钱包的 typeUrl 将自动设置为 fg:t:transaction,origin 将是 Base58 编码的缓冲区。
3. 签署交易(预编码)
如果您已经在服务器上对交易缓冲区进行了编码,可以直接发送它。在这种情况下,您必须将 typeUrl 设置为 fg:t:transaction。
签署预编码的交易
const { Client } = require('@ocap/client');
const { toBase58 } = require('@ocap/util');
// 假设 client 是 @ocap/client 的一个实例
const { buffer: txBuffer } = await client.encodeTransferV2Tx({
// ... 交易参数
});
const claims = {
signature: {
typeUrl: 'fg:t:transaction',
description: '请确认此预编码的交易。',
// `data` 是 base58 编码的缓冲区
data: toBase58(txBuffer),
},
};这种方法为您提供了更多的控制权,但需要您自己处理交易编码。
通过利用签名声明,您可以与用户建立安全且可验证的交互。下一节将介绍一种用于支付场景的特殊类型的交易声明。
下一步:准备交易声明
了解如何请求钱包完成并签署部分构造的交易。