Getting Started
This guide provides the fastest way to set up a basic DID authentication flow in a Node.js application. You will install the necessary packages, configure the authenticator, and create a minimal, runnable Express.js server.
By the end, you'll have a working server that generates a DID Connect QR code for users to sign in.
The Authentication Flow#
Before diving in, it's helpful to see the high-level interaction between the user's wallet and your application server. The code you are about to write will enable this entire sequence.
Step 1: Install Dependencies#
First, you need to install did-auth, an Express.js-compatible server, a wallet library, and an in-memory storage module for session tokens.
npm install express @arcblock/did-auth @ocap/wallet @arcblock/did-auth-storage-memoryStep 2: Initialize Express and Create an App Wallet#
Create an index.js file. In this file, you'll set up a basic Express server and generate a new wallet for your application. This wallet represents your application's identity.
const express = require('express');
const { fromRandom, WalletType } = require('@ocap/wallet');
const Mcrypto = require('@ocap/mcrypto');
// Create an Express app
const app = express();
const port = 3000;
// Define a wallet type for your application
const appWalletType = WalletType({
role: Mcrypto.types.RoleType.ROLE_APPLICATION,
pk: Mcrypto.types.KeyType.ED25519,
hash: Mcrypto.types.HashType.SHA3,
});
// Create a new wallet for your application and convert it to a manageable JSON object
const appWallet = fromRandom(appWalletType);
console.log('Application DID:', appWallet.address);Step 3: Configure the Authenticator#
The WalletAuthenticator is responsible for generating and verifying the cryptographic messages exchanged with the DID Wallet. You need to provide it with your application's wallet and information about your app and the blockchain it interacts with.
// ... require statements and appWallet setup from Step 2
const { WalletAuthenticator } = require('@arcblock/did-auth');
const authenticator = new WalletAuthenticator({
wallet: appWallet.toJSON(),
appInfo: {
name: 'DID Auth Demo',
description: 'A simple demo for @arcblock/did-auth',
icon: 'https://arcblock.oss-cn-beijing.aliyuncs.com/images/wallet-round.png',
link: `http://localhost:${port}`,
},
chainInfo: {
host: 'https://beta.abtnetwork.io/api',
id: 'beta',
},
});Step 4: Configure the Handlers#
The WalletHandlers class provides a set of Express middleware that manage the entire authentication lifecycle, from generating tokens to handling wallet responses.
// ... setup from previous steps
const { WalletHandlers } = require('@arcblock/did-auth');
const MemoryAuthStorage = require('@arcblock/did-auth-storage-memory');
const tokenStorage = new MemoryAuthStorage();
const handlers = new WalletHandlers({
authenticator,
tokenStorage,
});Step 5: Attach Authentication Routes#
Now, attach the handlers to your Express app. This single attach call creates several standard endpoints (e.g., /api/did/login/token, /api/did/login/auth) required for the DID Connect protocol.
Parameter | Description |
|---|---|
| Your Express application instance. |
| A unique name for this auth flow, which becomes part of the URL (e.g., 'login'). |
| The information you want to request from the user, such as their profile. |
| A callback function that executes after the user successfully authenticates with their wallet. |
// ... setup from previous steps
handlers.attach({
app: app,
action: 'login',
claims: {
profile: () => ({
fields: ['fullName', 'email'],
description: 'Please provide your name and email to continue.',
}),
},
onAuth: async ({ claims, userDid }) => {
const profile = claims.find((x) => x.type === 'profile');
console.log('Authentication successful for user:', userDid);
console.log('User profile:', profile);
return { successMessage: 'Login successful!' };
},
});
app.listen(port, () => {
console.log(`DID Auth demo server started on http://localhost:${port}`);
console.log(`Open http://localhost:${port}/api/did/login/token in your browser to get a QR code URL.`);
});Putting It All Together#
Here is the complete index.js file. Save it and run node index.js from your terminal.
/* eslint-disable import/no-extraneous-dependencies */
const express = require('express');
const { fromRandom, WalletType } = require('@ocap/wallet');
const Mcrypto = require('@ocap/mcrypto');
const { WalletAuthenticator, WalletHandlers } = require('@arcblock/did-auth');
const MemoryAuthStorage = require('@arcblock/did-auth-storage-memory');
// 1. Initialize Express App
const app = express();
const port = 3000;
// 2. Create a wallet for the application
const appWalletType = WalletType({
role: Mcrypto.types.RoleType.ROLE_APPLICATION,
pk: Mcrypto.types.KeyType.ED25519,
hash: Mcrypto.types.HashType.SHA3,
});
const appWallet = fromRandom(appWalletType);
console.log('Application DID:', appWallet.address);
// 3. Configure the Authenticator
const authenticator = new WalletAuthenticator({
wallet: appWallet.toJSON(),
appInfo: {
name: 'DID Auth Demo',
description: 'A simple demo for @arcblock/did-auth',
icon: 'https://arcblock.oss-cn-beijing.aliyuncs.com/images/wallet-round.png',
link: `http://localhost:${port}`,
},
chainInfo: {
host: 'https://beta.abtnetwork.io/api',
id: 'beta',
},
});
// 4. Configure Handlers with in-memory token storage
const tokenStorage = new MemoryAuthStorage();
const handlers = new WalletHandlers({
authenticator,
tokenStorage,
});
// 5. Attach the authentication routes to Express
handlers.attach({
app: app,
action: 'login',
claims: {
profile: () => ({
fields: ['fullName', 'email'],
description: 'Please provide your name and email to continue.',
}),
},
onAuth: async ({ claims, userDid }) => {
const profile = claims.find((x) => x.type === 'profile');
console.log('Authentication successful for user:', userDid);
console.log('User profile:', profile);
// In a real app, you would typically create a session or issue a JWT here.
return { successMessage: 'Login successful!' };
},
});
// Start the server
app.listen(port, () => {
console.log(`DID Auth demo server started on http://localhost:${port}`);
console.log(`To test, open http://localhost:${port}/api/did/login/token in your browser.`);
console.log('This will return a URL. To generate a QR code, append that URL to: https://abtwallet.io/i/?uri=`);
});Next Steps#
You have now successfully created a server that handles DID authentication. To fully understand the mechanics behind this process, you should explore the detailed authentication flow.
- Understand the process: Dive deeper into the Authentication Flow.
- Explore more use cases: See practical recipes in the How-to Guides, such as requesting a signature.
- Review the API: Get detailed information on the classes and methods in the API Reference.