SDK Integration Guide
GuideComplete guide to integrating the 1auth SDK into your application.
Overview
This guide covers how to integrate the 1auth SDK for authentication, transaction signing, and message signing.
Installation
pnpm add @1auth/sdkQuick Start
1. Initialize the Client
import { PasskeyProviderClient } from '@1auth/sdk';
const client = new PasskeyProviderClient({
providerUrl: 'https://your-auth-provider.com',
clientId: 'your-client-id',
theme: {
mode: 'system', // 'light' | 'dark' | 'system'
accent: '#6366f1', // Optional accent color
},
});2. Authentication
// Open auth modal (recommended)
const result = await client.authWithModal();
if (result.success) {
console.log('Logged in as:', result.username);
// Store user for later
localStorage.setItem('user', JSON.stringify({ username: result.username }));
}3. Transaction Signing
// Send a cross-chain intent
const result = await client.sendIntent({
username: 'alice',
targetChain: 8453, // Base
calls: [
{
to: '0x...',
data: '0x...',
value: '1000000000000000000', // 1 ETH in wei
label: 'Mint NFT',
sublabel: 'CoolNFT #1234',
},
],
closeOn: 'preconfirmed', // When to return success
});
if (result.success) {
console.log('TX Hash:', result.transactionHash);
}4. Message Signing
Sign arbitrary messages for authentication or verification:
// Sign a message (e.g., for login verification)
const result = await client.signMessage({
username: 'alice',
message: `Sign in to MyApp\nTimestamp: ${Date.now()}\nNonce: ${crypto.randomUUID()}`,
description: 'Verify your identity to continue',
});
if (result.success) {
// Send signature to your backend for verification
await fetch('/api/verify', {
method: 'POST',
body: JSON.stringify({
signature: result.signature,
message: result.signedMessage,
}),
});
}Complete Examples
PayButton Component
The simplest way to accept payments:
import { PayButton } from '@1auth/sdk';
function Checkout({ productId, price }) {
return (
<PayButton
client={client}
intent={{
targetChain: 8453,
calls: [{
to: PAYMENT_CONTRACT,
data: encodePurchase(productId),
label: 'Purchase Item',
sublabel: `$${price}`,
}],
}}
onSuccess={(result) => {
router.push(`/order/success?tx=${result.transactionHash}`);
}}
onError={(error) => {
toast.error(error.message);
}}
>
Buy Now - ${price}
</PayButton>
);
}Custom Sign-In Flow
async function signIn() {
// 1. Get challenge from your backend
const { challenge } = await fetch('/api/auth/challenge').then(r => r.json());
// 2. Sign the challenge with passkey
const result = await client.signMessage({
username: savedUsername,
message: challenge,
description: 'Sign in to continue',
});
if (!result.success) {
throw new Error('Sign-in cancelled');
}
// 3. Verify signature on backend
const session = await fetch('/api/auth/verify', {
method: 'POST',
body: JSON.stringify({
signature: result.signature,
challenge,
}),
}).then(r => r.json());
return session;
}Token Swaps
const result = await client.sendSwap({
username: 'alice',
targetChain: 8453,
fromToken: 'ETH',
toToken: 'USDC',
amount: '0.1',
});
if (result.success) {
console.log('Swap completed:', result.transactionHash);
}API Reference
SignMessageOptions
| Property | Type | Required | Description |
|---|---|---|---|
username | string | Yes | Username of the signer |
message | string | Yes | Human-readable message to sign |
challenge | string | No | Custom challenge (defaults to message) |
description | string | No | Description shown to user |
metadata | Record<string, unknown> | No | Additional data to display |
theme | ThemeConfig | No | Theme override for dialog |
SignMessageResult
| Property | Type | Description |
|---|---|---|
success | boolean | Whether signing succeeded |
signature | WebAuthnSignature | The signature (if successful) |
signedMessage | string | Echo of the signed message |
passkey | PasskeyCredentials | Passkey used for signing |
error | { code, message } | Error details (if failed) |
Best Practices
-
Store username locally - After authentication, store the username in localStorage to skip auth on subsequent visits
-
Use closeOn wisely - Different values for different use cases:
claimed- Fastest, use for low-value transactionspreconfirmed- Recommended defaultcompleted- Use when full finality is required
-
Handle errors gracefully - All methods return
{ success: boolean, error?: {...} } -
Single client instance - Create one client and reuse it throughout your app:
// lib/1auth.ts export const authClient = new PasskeyProviderClient({ providerUrl: process.env.NEXT_PUBLIC_AUTH_URL!, clientId: process.env.NEXT_PUBLIC_CLIENT_ID!, }); -
Theme consistency - Set theme once at client creation, override only when needed