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

Key Pair Claim


The keyPair claim instructs the user's wallet to generate a new cryptographic key pair for a specific purpose. This is a powerful feature for creating new decentralized identifiers (DIDs) on behalf of the user, scoped to your application. Common uses include creating application-specific accounts, performing key rotations for security, or generating temporary session keys.

Upon successful generation, the wallet securely transmits the new secret key back to your application, allowing you to act on behalf of this new identity.

Use Cases#

  • Application-Specific Accounts: Generate a dedicated DID for each user within your application, isolating their identity and data from their primary wallet account.
  • Key Rotation: Enhance security by allowing users to generate a new key pair and migrate their permissions or assets from an old one.
  • Session Keys: Create temporary keys for specific, time-limited sessions without compromising the user's main wallet keys.

Parameters#

The keyPair claim is configured with the following parameters:

Parameter

Type

Description

type

string

Required. Must be 'keyPair'.

description

string

Required. A clear message displayed to the user in their wallet explaining why a new key pair is needed.

moniker

string

Required. A user-friendly name for the new key pair, which will be visible in the user's wallet (e.g., test-application, my-blog-key).

declare

boolean

Optional. If true, the wallet will attempt to declare the new DID on the blockchain. Defaults to true.

migrateFrom

string

Optional. The DID of an existing account to migrate from. This is used for key rotation workflows, where the new key pair will replace the old one.

targetType

object

Optional. An object that specifies the cryptographic properties of the key pair to be generated.

targetType Properties#

The targetType object allows you to define the exact specifications for the new key pair.

Parameter

Type

Default

Description

role

string

'account'

The role of the new key, such as account, application, node, etc.

key

string

'ed25519'

The cryptographic key algorithm to use (e.g., ed25519, secp256k1).

hash

string

'sha3'

The hash algorithm to use for generating the DID (e.g., sha3, sha2).

encoding

string

'base58'

The encoding format for the keys (e.g., base58, base64).

Example: Generating a New Application Account#

This example demonstrates how to request a new application key pair from the user's wallet and how to handle the response to store the new credentials securely.

1. Requesting the Key Pair#

First, define the keyPair claim in your handler. This configuration specifies the details of the key you need, including a custom description and an application-specific role.

// From a DID Connect handler file

module.exports = {
action: 'derive-key-pair',
claims: {
// Request a new key pair from the wallet
keyPair: async ({ extraParams }) => {
const { sessionDid, rotate, declare } = extraParams;
// In a real application, you would fetch user data to determine rotation logic
// const user = await User.ensureOne({ did: sessionDid });
let migrateFrom = '';
if (rotate) {
// Example: migrateFrom = user.generatedApps[0].address;
console.log('Key rotation requested for user:', sessionDid);
}

return {
mfa: true, // Require multi-factor authentication for this sensitive operation
description: 'Please generate a new key-pair for our application.',
moniker: 'test-application',
declare: typeof declare === 'undefined' ? true : !!JSON.parse(declare),
migrateFrom,
targetType: {
role: 'application',
hash: 'sha3',
key: 'ed25519',
encoding: 'base58',
},
};
},
},

// ... onAuth callback defined below
};

2. Handling the Wallet's Response#

After the user approves the request in their wallet, the onAuth callback receives the newly generated key pair, including the secret key. It is critical to handle this secret key securely.

The following onAuth function demonstrates how to reconstruct the wallet from the secret key and store its credentials after encrypting a sensitive piece of information.

// Continuing from the handler file above

const { types, Hasher } = require('@ocap/mcrypto');
const AES = require('@ocap/mcrypto/lib/crypter/aes').default;
const { fromSecretKey } = require('@ocap/wallet');
const { fromBase58, toBase58 } = require('@ocap/util');

// ...

module.exports = {
// ... claims definition

onAuth: async ({ claims, extraParams }) => {
const keyPairClaim = claims.find(x => x.type === 'keyPair');

if (!keyPairClaim || !keyPairClaim.secret) {
throw new Error('Key pair generation failed or was declined.');
}

// Reconstruct the application wallet from the secret key provided by the user's wallet
const appWallet = fromSecretKey(fromBase58(keyPairClaim.secret), {
role: types.RoleType.ROLE_APPLICATION,
});

console.log('New application DID generated:', appWallet.address);
console.log('Paired with user DID:', keyPairClaim.userDid);

// IMPORTANT: Securely handle the new key pair.
// Here, we derive a password and use it to encrypt a message.
// In a real application, you would encrypt and store the secret key itself.
const password = Hasher.SHA3.hash256(Buffer.concat([fromBase58(keyPairClaim.secret), fromBase58(appWallet.address)]));
const encryptedData = AES.encrypt('some secret data', password);

// Store the new app's public details and encrypted data in your database
// For example:
// const user = await User.ensureOne({ did: extraParams.sessionDid });
// user.generatedApps = [
// { address: appWallet.address, publicKey: toBase58(appWallet.publicKey), encrypted: encryptedData },
// ];
// await User.update(user);

return {
successMessage: `You have generated a new app DID: ${appWallet.address}`,
};
},
};

Wallet Response Payload#

When the onAuth callback is invoked, the claims array will contain an object with the following structure for the keyPair claim:

{
"type": "keyPair",
"description": "Please generate a new key-pair for our application.",
"moniker": "test-application",
"userDid": "zNKpCN82hT5yDm3xw1T5s7z39v2jea2tiW6o",
"secret": "zsk2hS5nRHG8j2W9fT8o5bE7f...",
"publicKey": "zpub2hS5nRHG8j2W9fT8o5bE7f...",
"targetType": {
"role": "application",
"hash": "sha3",
"key": "ed25519",
"encoding": "base58"
},
"meta": {}
}

Security Warning: The secret field contains the private key for the new DID. This is highly sensitive information. Always handle it with extreme care, encrypt it at rest, and never expose it in client-side code or logs.

After successfully generating a key pair, you might need to derive a symmetric key for data encryption. Proceed to the Encryption Key Claim documentation to learn more.