Authenticate
ComponentInteractive demo for passkey authentication and message signing.
import { Authenticate } from '@1auth/sdk'Live Demo
Authentication & Message Signing
Connects to passkey app at https://passkey.1auth.box
Overview
This demo showcases two core SDK features:
- Authentication - Connect a user with their passkey using
authWithModal() - Message Signing - Sign arbitrary messages using
signMessage() - Verification - Verify signatures using
verifyMessageHash()
Authentication
Open a modal for users to sign in or create an account:
const client = new PasskeyProviderClient({
providerUrl: 'https://auth.example.com',
clientId: 'my-app',
});
const result = await client.authWithModal();
if (result.success) {
console.log('Connected as:', result.username);
}Message Signing
After authentication, sign arbitrary messages for verification:
const result = await client.signMessage({
username: 'alice',
message: `Sign in to MyApp\nTimestamp: ${Date.now()}`,
description: 'Verify your identity',
});
if (result.success) {
console.log('Signature:', result.signature);
console.log('Signed Hash:', result.signedHash);
}Signature Verification
Messages are signed with a domain separator to prevent replay attacks. Use the SDK's verification utilities to confirm the hash matches:
import { verifyMessageHash, hashMessage } from '@1auth/sdk';
const message = 'Sign in to MyApp';
const result = await client.signMessage({ username: 'alice', message });
if (result.success) {
// Verify the signedHash matches what we expect
const isValid = verifyMessageHash(message, result.signedHash);
console.log('Hash verified:', isValid);
// Or compute the expected hash manually
const expectedHash = hashMessage(message);
console.log('Expected:', expectedHash);
console.log('Received:', result.signedHash);
}The domain separator format is: keccak256("\x19Passkey Signed Message:\n" + len + message)
This ensures message signatures cannot be replayed for transaction signing.
SignMessageOptions
| Property | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Username of the signer |
message | string | Yes | Human-readable message to sign |
description | string | No | Description shown in dialog |
metadata | Record<string, unknown> | No | Additional data to display |
theme | ThemeConfig | No | Theme override |
SignMessageResult
| Property | Type | Description |
|---|---|---|
success | boolean | Whether signing succeeded |
signature | WebAuthnSignature | The WebAuthn signature |
signedMessage | string | Echo of the signed message |
signedHash | 0x${string} | The hash that was signed (with domain separator) |
passkey | PasskeyCredentials | Passkey used for signing |
error | { code, message } | Error details if failed |
Use Cases
- Login verification - Sign a challenge to prove identity
- Terms acceptance - Sign acknowledgment of terms/conditions
- Off-chain signatures - Any scenario requiring proof of ownership
Security
The message is hashed with a domain separator before signing, which:
- Prevents signature replay attacks across different apps
- Ensures message signatures cannot be used for transaction signing
- Follows a similar pattern to EIP-191 personal sign