Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
How-to Guides

Request a Signature


Many applications require users to authorize actions by providing a digital signature. This could be for signing a message, consenting to terms, or approving an on-chain transaction. DID Connect provides two distinct claims to handle these scenarios: signature and prepareTx.

  • Use the signature claim when you have the complete data you want the user to sign.
  • Use the prepareTx claim when your application creates a partial transaction and needs the user's wallet to provide the remaining inputs (like funds or assets) before signing.

This guide will walk you through how to use both.

The Signing Flow#

At a high level, requesting a signature involves your application defining the claim, the SDK presenting it to the user's wallet, and your application handling the signed response.

UserUser's WalletDID Connect SDKYour ApplicationUserUser's WalletDID Connect SDKYour ApplicationDefine 'signature' or 'prepareTx' claim in handlers.attach()Generate and present signing requestPrompt user for confirmationApprove or Decline requestReturn signed data or error to onAuth callbackMake signed data available in req.did_connect.claims

Use signature for General-Purpose Signing#

Use the signature claim when the data to be signed is fully known by your application. This is ideal for signing messages, login challenges, or fully-formed transactions that just need the user's signature.

Signing a Plain Text Message#

Here's how to ask a user to sign a simple welcome message. The origin field contains the data to be signed, which must be a Base58-encoded buffer.

const { WalletHandlers } = require('@arcblock/did-connect');
const { toBase58 } = require('@ocap/util');

// ... inside your Express route setup ...

handlers.attach({
app,
action: 'sign-message',
onAuth: (req, res) => {
// The wallet's response, including the signature, is in the claims object
console.log('Signature received:', req.did_connect.claims);
// You can now verify the signature and complete the user's action
res.json({ ok: 1, message: 'Signature received!' });
},
claims: {
signature: {
typeUrl: 'mime:text/plain', // Specify the data type
description: 'Please sign this welcome message to confirm your identity.',
origin: toBase58(Buffer.from('Welcome to our dApp! Please sign to continue.')),
},
}
});

Signing a Pre-Encoded Transaction#

For on-chain operations, you can construct and encode a transaction in your backend, then pass it to the wallet for signing. This gives you full control over the transaction's contents.

You'll need a library like @ocap/client to encode the transaction according to the target chain's format. In this example, we set typeUrl to fg:t:transaction to tell the wallet it's handling a Forge-compatible transaction.

const { WalletHandlers } = require('@arcblock/did-connect');
const { toBase58 } = require('@ocap/util');
const Client = require('@ocap/client');
const { fromAddress } = require('@ocap/wallet');

// ...

const client = new Client('https://beta.abtnetwork.io/api');

handlers.attach({
app,
action: 'sign-tx',
onAuth: (req, res) => {
console.log('Transaction signed:', req.did_connect.claims);
// You can now broadcast the signed transaction
res.json({ ok: 1, message: 'Transaction signed!' });
},
claims: {
signature: async ({ userDid }) => {
// This function runs when the user connects their wallet
const { buffer: txBuffer } = await client.encodeTransferV2Tx({
tx: {
itx: {
to: 'zNKjDm4Xsoaffb19UE6QxVeevuaTaLCS1n1S', // Application's address
tokens: [
{
address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt', // Token address
value: '1000000000000000000', // 1 ABT
},
],
},
},
wallet: fromAddress(userDid), // Set the sender from the connected user
});

return {
typeUrl: 'fg:t:transaction',
description: 'Please sign to confirm the 1 ABT transfer.',
origin: toBase58(txBuffer), // The base58-encoded transaction buffer
};
},
},
});

signature Claim Parameters#

Parameter

Type

Description

typeUrl

string

Required. Specifies the type of data being signed. Common values: mime:text/plain, mime:text/html, fg:t:transaction, eth:transaction.

origin

string

The Base58-encoded data to be signed. Use this when you provide the full data.

digest

string

The pre-calculated hash (digest) of the data. Use this if you want to sign a hash instead of the full data.

method

string

The hashing algorithm the wallet should apply to origin before signing. Defaults to sha3. Set to none to sign the origin data directly without hashing.

display

string

A stringified JSON object to provide a rich display in the wallet (e.g., { "type": "url", "content": "https://..." }).

description

string

A human-readable message shown to the user in the wallet prompt.

requirement

object

An optional object specifying tokens or assets the user must own to be able to sign.

Use prepareTx for Collaborative Transactions#

Use the prepareTx claim when your application can only create a partial transaction and needs the user's wallet to supply the remaining inputs, such as payment tokens or assets. The wallet will complete the transaction, sign it, and return the result.

This is common in payment scenarios where the application knows the recipient and amount but doesn't know which specific tokens the user will pay with.

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

// Assume partialTxBuffer is a partially encoded transaction buffer from ocap/client
// It might contain the recipient and memo, but not the inputs.

handlers.attach({
app,
action: 'purchase-item',
onAuth: (req, res) => {
console.log('Transaction prepared and signed:', req.did_connect.claims);
res.json({ ok: 1, message: 'Purchase complete!' });
},
claims: {
prepareTx: {
description: 'Please complete this payment to purchase the Awesome NFT.',
partialTx: toBase58(partialTxBuffer),
requirement: {
tokens: [
{
address: 'z35nB2SA6xxBuoaiuUXUw6Gah2SNU3UzqdgEt', // ABT token address
value: '10000000000000000000', // 10 ABT
},
],
},
display: JSON.stringify({ type: 'url', content: 'https://.../item-image.png' }),
},
},
});

prepareTx Claim Parameters#

Parameter

Type

Description

partialTx

string

Required. A Base58-encoded buffer of the partially-formed transaction.

requirement

object

Required. An object specifying what the user's wallet needs to provide to complete the transaction.

requirement.tokens

array

An array of token objects, each with address and value, that the user must contribute.

requirement.assets

object

An object specifying digital assets (NFTs) the user must contribute. Can filter by address, parent, or issuer.

display

string

A stringified JSON object for rich display in the wallet.

description

string

A human-readable message explaining the action to the user.


Now you know how to request signatures for both simple messages and complex transactions. Often, a signature is just one step in a larger user journey.

To learn how to combine multiple claims into a single, seamless flow, proceed to the next guide on Chaining Multiple Workflows.