Signature Claim


The Signature Claim is a versatile tool used to request a user to sign arbitrary data using the private key associated with their DID. This cryptographic signature serves as undeniable proof that the user has seen and approved the data, effectively demonstrating control over their digital identity. Common use cases include signing messages, authorizing transactions, or confirming delegations.

For more complex payment scenarios where the wallet needs to contribute inputs to a transaction, consider using the Prepare Transaction Claim.

How It Works#

The application constructs a signature claim detailing what needs to be signed. This includes the data itself (as a raw string or a pre-computed digest), the type of data (which helps the wallet display it correctly), and a hashing method. DID Wallet receives this request, presents the information to the user for confirmation, and upon approval, signs the data and returns the signature to the application for verification.

Parameters#

The signature claim object accepts the following parameters:

Parameter

Type

Description

typeUrl

string

Required. Specifies the data type. This helps the wallet interpret and display the content correctly. Common values include mime:text/plain, mime:text/html, fg:t:transaction (for a Forge-encoded transaction), or a specific transaction type like TransferV2Tx.

origin

string

The raw data to be signed, encoded as a Base58 string. This is used when you want the wallet to see and hash the full data. You should provide either origin or digest.

digest

string

A pre-computed hash of the data. Use this when the original data is too large to send or when you don't need the wallet to see the raw content.

method

string

The hashing algorithm the wallet should apply to the origin data before signing. Defaults to sha3. If set to 'none', the wallet will sign the origin data directly without hashing it first.

display

string

A JSON string for providing a rich display in the wallet, such as showing a formatted message or a link. Example: JSON.stringify({ type: 'url', content: 'https://www.arcblock.io' }).

description

string

A user-friendly message explaining what the user is being asked to sign. Defaults to 'Sign this transaction or message to continue.'.

requirement

object

An optional object specifying token or asset requirements that the user must meet to be able to provide the signature.

nonce

string

An optional random string used to prevent replay attacks.

Usage Examples#

Here are a few examples of how to request different types of signatures.

1. Signing a Plain Text Message#

This is the simplest use case, where you ask the user to sign a simple string of text.

Requesting a Text Signature

const claims = {
  signature: {
    typeUrl: 'mime:text/plain',
    description: 'Please sign this message to verify your identity.',
    data: 'I agree to the terms and conditions.',
  },
};

// In your handler
const { authInfo } = await authenticator.sign({
  claims,
  // ... other params
});

In this example, the data string will be converted to a Buffer, encoded in Base58, and sent to the wallet as the origin field.

2. Signing a Transaction (from Raw Data)#

For on-chain operations, you can ask the user to sign a transaction. You can provide the raw transaction object, and DID Connect will handle the encoding for you. This requires configuring chainInfo in your WalletAuthenticator instance.

Requesting a Transaction Signature

const claims = {
  signature: {
    // This is a specific transaction type known by @ocap/client
    type: 'TransferV2Tx',
    description: 'Please sign to confirm the transfer of 100 TBA.',
    display: JSON.stringify({ type: 'html', content: '<div>Transfer <b>100 TBA</b> to recipient</div>' }),
    // The raw transaction data object
    data: {
      itx: {
        to: 'z123...',
        tokens: [
          {
            address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt',
            value: '100',
          },
        ],
      },
    },
    // Optional: specify token requirements for the wallet
    requirement: {
      tokens: [
        {
          address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt',
          value: '100',
        },

See all 4 lines

Behind the scenes, WalletAuthenticator will use @ocap/client to encode the data object into a transaction buffer. The typeUrl sent to the wallet will automatically be set to fg:t:transaction, and the origin will be the Base58-encoded buffer.

3. Signing a Transaction (Pre-Encoded)#

If you have already encoded the transaction buffer on your server, you can send it directly. In this case, you must set typeUrl to fg:t:transaction.

Signing a Pre-Encoded Transaction

const { Client } = require('@ocap/client');
const { toBase58 } = require('@ocap/util');

// Assume client is an instance of @ocap/client
const { buffer: txBuffer } = await client.encodeTransferV2Tx({
  // ... tx params
});

const claims = {
  signature: {
    typeUrl: 'fg:t:transaction',
    description: 'Please confirm this pre-encoded transaction.',
    // The `data` is the base58-encoded buffer
    data: toBase58(txBuffer),
  },
};

This approach gives you more control but requires you to handle the transaction encoding yourself.


By leveraging the Signature Claim, you can build secure and verifiable interactions with your users. The next section covers a specialized type of transaction claim for payment scenarios.