Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Sign in with 1auth

Add passkey authentication to your app with a single method call. Users authenticate with Face ID or Touch ID - no passwords, no seed phrases.

Authentication

import { OneAuthClient } from '@rhinestone/1auth';
 
const client = new OneAuthClient({
  providerUrl: 'https://passkey.1auth.app',
  clientId: 'my-app',
});
 
// Authenticate or create an account
const auth = await client.authenticate();
if (!auth.success) throw new Error(auth.error.message);
 
const accountAddress = auth.session.accountAddress; // typed `0x${string}`
console.log('Connected as:', accountAddress);

How It Works

  1. User clicks sign in — your app calls authenticate().
  2. Identity dialog opens — the user verifies email or OAuth identity.
  3. Top-level passkey prompt opens — WebAuthn runs on your app origin.
  4. Success — you receive the smart-account address.

The passkey private key never leaves the authenticator. 1auth remains authoritative for identity, credential persistence, and account derivation.

Message Signing

Request the user to sign a message for verification:

const result = await client.signMessage({
  accountAddress,
  message: `Sign in to MyApp\nTimestamp: ${Date.now()}`,
  description: 'Verify your identity',
});
 
if (result.success) {
  console.log('Signature:', result.signature);
  // Verify signature on your backend
}

SignMessageOptions

PropertyTypeRequiredDescription
accountAddressstringYesSmart account address of the signer
messagestringYesHuman-readable message to sign
descriptionstringNoDescription shown in the signing dialog
metadataRecord<string, unknown>NoAdditional data to display

AuthResult

authenticate() returns an AuthResult:

import type { AuthResult } from '@rhinestone/1auth';
 
type AuthResult =
  | {
      success: true;
      session: {
        webAuthnMode: 'app_origin' | 'experimental_cross_origin';
        accountAddress: `0x${string}`;
        signerType: 'passkey' | 'eoa';
      };
    }
  | {
      success: false;
      error: {
        code: string; // e.g. "USER_CANCELLED"
        message: string;
      };
    };

Challenge-Based Authentication

Application-message signing works in both WebAuthn modes:

const client = new OneAuthClient({
  clientId: 'my-app',
})
 
const auth = await client.authenticate();
if (!auth.success) throw new Error(auth.error.message);
 
const result = await client.signMessage({
  accountAddress: auth.session.accountAddress,
  message: `Login to MyApp\nTimestamp: ${Date.now()}\nNonce: ${crypto.randomUUID()}`,
  description: 'Verify your identity',
})

Authentication and message signing are separate operations. Compose them when your application needs a signed login challenge.

Example: Protected Route

import { useState, useEffect } from 'react';
import { OneAuthClient } from '@rhinestone/1auth';
 
const client = new OneAuthClient({
  clientId: 'my-app',
});
 
function App() {
  const [user, setUser] = useState(null);
 
  const handleSignIn = async () => {
    const result = await client.authenticate();
    if (result.success) {
      setUser({ address: result.session.accountAddress });
    }
  };
 
  if (!user) {
    return (
      <button onClick={handleSignIn}>
        Sign in with 1auth
      </button>
    );
  }
 
  return (
    <div>
      <p>Welcome!</p>
      <p>Address: {user.address}</p>
    </div>
  );
}