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

WalletHandlers


The WalletHandlers class is the core component for integrating DID authentication into an Express.js application. It provides a set of handlers that manage the entire authentication lifecycle, from generating a session and presenting a QR code to processing claims from the user's wallet.

This class extends BaseHandler and works in tandem with an instance of WalletAuthenticator to create and verify the cryptographic messages that underpin the protocol. For details on how to configure the signing and verification component, see the WalletAuthenticator API Reference.

Authentication Flow#

The WalletHandlers.attach() method sets up several endpoints on your server. The following diagram illustrates how a web application, your server (backend), and a DID Wallet interact during a typical authentication flow.

DID WalletYour Server (Backend)Web Application (Frontend)DID WalletYour Server (Backend)Web Application (Frontend)Display QR code from urlUser reviews and approves/declines requestloop[8. Poll for status]1. Request token (GET /api/did/{action}/token)2. Respond with { token, url }3. Scan QR Code4. Fetch auth request (GET /api/did/{action}/auth)5. Respond with signed claim request6. Submit signed auth response (POST /api/did/{action}/auth)7. Respond with next step or successGET /api/did/{action}/statusSession Status (e.g., scanned, succeed)

Class: WalletHandlers#

Extends EventEmitter to provide hooks into the authentication lifecycle.

new WalletHandlers(config)#

Creates an instance of the DID Auth handlers. This instance orchestrates the authentication process by managing session state and handling communication with the wallet.

Parameters

Name

Type

Description

config

object

The configuration object.

config.tokenStorage

object

A storage instance for managing session tokens. Must conform to the expected storage interface.

config.authenticator

object

An instance of WalletAuthenticator used to sign and verify JWTs.

config.pathTransformer

function

(Optional) A function to transform the callback URL pathname. Defaults to an identity function.

config.onConnect

function

(Optional) A global callback invoked when the wallet connects. It can be used for permission checks before proceeding. Throwing an error will halt the process.

config.options

object

(Optional) Custom options to configure the handlers.

config.options.prefix

string

(Optional) URL prefix for the endpoints. Defaults to '/api/did'.

config.options.cleanupDelay

number

(Optional) How long (in milliseconds) to wait before cleaning up a completed session. Defaults to 60000.

config.options.tokenKey

string

(Optional) The query parameter key for the session token. Defaults to '_t_'.

config.options.encKey

string

(Optional) The query parameter key for the wallet's public encryption key. Defaults to '_ek_'.

config.options.versionKey

string

(Optional) The query parameter key for the wallet protocol version. Defaults to '_v_'.

Example

const { WalletHandlers } = require('@arcblock/did-auth');
const Authenticator = require('./path/to/authenticator-instance'); // Your configured WalletAuthenticator
const TokenStorage = require('./path/to/token-storage-instance'); // Your token storage

const handlers = new WalletHandlers({
authenticator: Authenticator,
tokenStorage: TokenStorage,
});

attach(config)#

Attaches the DID authentication routes to an Express app instance for a specific action (e.g., 'login', 'claim'). This is the main method for making the authentication flow operational.

It registers the following routes under /{prefix}/{action}:

  • GET /token: Creates a new session token and auth URL.
  • GET /status: Checks the current status of a session token.
  • GET /timeout: Manually expires a session token.
  • GET /auth: Called by the wallet to fetch the authentication request (claims).
  • POST /auth: Called by the wallet to submit the signed authentication response.

Parameters

Name

Type

Default

Description

config.app

object


The Express app instance.

config.action

string


A unique name for this group of routes (e.g., 'login').

config.claims

object

undefined

(Optional) An array of claims to request from the user.

config.onStart

function

noop

(Optional) Callback executed when a new session starts (token is generated).

config.onConnect

function

noop

(Optional) Action-specific callback when a wallet connects. Can return dynamic claims.

config.onAuth

function

Required

Callback executed on each successful authentication step from the wallet.

config.onDecline

function

noop

(Optional) Callback executed when the user declines the request in their wallet.

config.onComplete

function

noop

(Optional) Callback executed when the entire authentication flow is successfully completed.

config.onExpire

function

noop

(Optional) Callback executed when a session token expires.

config.onError

function

console.error

(Optional) Callback for handling errors during the process.

config.authPrincipal

boolean | string | did

true

(Optional) Specifies if an authPrincipal claim is required. If true, a default claim is prepended.

config.persistentDynamicClaims

boolean

false

(Optional) If true, dynamic claims returned from onConnect will be persisted in the session.

Example: Attaching a Login Handler

const express = require('express');
// Assuming 'handlers' is an initialized WalletHandlers instance

const app = express();

const onAuthSuccess = async ({ userDid, userPk, claims }) => {
console.log('User authenticated:', { userDid, userPk });
// Find or create user in your database
// The final result object can be returned to the wallet.
return { successMessage: 'Login successful!' };
};

handlers.attach({
app,
action: 'login',
claims: [
{ type: 'profile', fields: ['fullName', 'email'], description: 'Please provide your profile for registration' },
{ type: 'signature', description: 'Please sign this message to confirm your identity' }
],
onAuth: onAuthSuccess,
onComplete: ({ userDid }) => {
console.log(`Session for ${userDid} is complete and will be cleaned up.`);
}
});

app.listen(3000, () => {
console.log('DID Auth server running on http://localhost:3000');
});

Events#

WalletHandlers inherits from EventEmitter and emits events based on the underlying token storage operations. You can listen to these events to monitor session activity.

  • created: Emitted when a new session token is created.
    • Payload: { token, ... } - The initial data of the created session.
  • updated: Emitted whenever a session's data is updated (e.g., status change from created to scanned).
    • Payload: An object containing the updated fields of the session, excluding internal protected keys.
  • deleted: Emitted when a session token is destroyed (e.g., after completion or timeout).
    • Payload: { token } - The token of the deleted session.

Example: Listening to Events

// Assuming 'handlers' is an initialized WalletHandlers instance

handlers.on('updated', (sessionData) => {
if (sessionData.status === 'scanned') {
console.log(`Token ${sessionData.token} was scanned by wallet.`);
}
if (sessionData.status === 'succeed') {
console.log(`Authentication for token ${sessionData.token} succeeded.`);
}
});

handlers.on('deleted', ({ token }) => {
console.log(`Session for token ${token} was deleted.`);
});


Now that you understand how to configure WalletHandlers, see a practical example in the Set up with Express.js guide or dive into the data structures in the Schemas reference.