Try it
Overview
createOneAuthConnection is the ergonomic front door for connecting a user and getting
back a ready-to-use EIP-1193 provider plus the connected { address, signerType }.
By default the app gets 1auth smart accounts + intents (passkey signer). Offering a
traditional wallet (WalletConnect / injected — RainbowKit-style) as the account signer
is opt-in via eoaConnect: true — only then does the dialog show the "Continue with
wallet" option, and picking it connects the EOA as the signer (no 1auth account is
created). Passkey selection is unchanged either way.
When the user picks a traditional wallet (an EOA), the returned provider forwards
eth_sendTransaction / personal_sign / signTypedData / wallet_sendCalls straight
to that wallet's native RPC — no Rhinestone intents. When they pick a passkey,
transactions route through 1auth intents exactly as they do everywhere else. Your app
writes one downstream code path either way.
It composes OneAuthClient.connect() and
createOneAuthProvider() and binds the resolved session to the provider the
instant connect() resolves — so a transaction issued in the same tick routes correctly
without waiting for you to persist anything.
Usage
import { createOneAuthConnection } from '@rhinestone/1auth';
import { createWalletClient, custom } from 'viem';
import { base } from 'viem/chains';
// Omit eoaConnect (or set false) for passkey-only → 1auth smart accounts + intents.
// Set eoaConnect: true to also offer a traditional wallet (EOA, no intents).
const conn = createOneAuthConnection({ clientId: 'my-app', eoaConnect: true });
// Opens the 1auth dialog — the user picks passkey OR a traditional wallet.
const session = await conn.connect();
const walletClient = createWalletClient({
account: session.address,
chain: base,
transport: custom(session.provider),
});
// Same call for both signer types:
// - EOA (traditional wallet): sent via the wallet's native RPC, no intents
// - passkey: routed through 1auth intents
await walletClient.sendTransaction({ to: '0x…', value: 1n });Branch on signerType when you need to:
if (session.signerType === 'eoa') {
// Traditional wallet — single-chain, native RPC. No chain abstraction.
} else {
// 1auth passkey smart account — cross-chain intents available.
}Reuse an existing client
const client = new OneAuthClient({ clientId: 'my-app', sponsorship });
const conn = createOneAuthConnection({ client, defaultChainId: 8453 });
const { address, signerType, provider } = await conn.connect();Config
Accepts every OneAuthClient config option plus:
| Option | Type | Required | Description |
|---|---|---|---|
client | OneAuthClient | No | Reuse a pre-built client instead of constructing one from the config. |
eoaConnect | boolean | No | Opt in to offering a traditional wallet as the account signer (EOA, bypasses intents). Defaults to false — by default you get 1auth smart accounts + intents. Can be overridden per connect() call. |
defaultChainId | number | No | Chain the provider reports via eth_chainId and uses as the default intent target. Defaults to 8453 (Base). |
storageKey | string | No | localStorage key the session is persisted under. Defaults to "1auth-user". |
closeOn, waitForHash, hashTimeoutMs, hashIntervalMs | — | No | Forwarded to the provider for passkey intent sends. |
Returns — OneAuthConnection
| Member | Type | Description |
|---|---|---|
client | OneAuthClient | The underlying client (escape hatch for signMessage, history, etc.). |
provider | OneAuthProvider | Ready-to-use EIP-1193 provider. Stable across reconnects. |
connect(options?) | Promise<OneAuthSession> | Opens the dialog and resolves the session. Rejects ({ code, message }) on cancel/failure. |
getSession() | OneAuthSession | null | Current persisted session. Never opens a dialog. |
disconnect() | Promise<void> | Clears the session and emits accountsChanged([]) / disconnect. |
subscribe(listener) | () => void | Notified on connect/disconnect; returns an unsubscribe function. |
OneAuthSession
interface OneAuthSession {
signerType: 'passkey' | 'eoa';
address: `0x${string}`;
provider: OneAuthProvider;
chainId: number;
autoConnected: boolean;
}Gotcha: EOA sessions are single-chain
Cross-chain intents are not available for EOA (traditional-wallet) sessions — the
wallet's native RPC is single-chain by design, with no 1auth chain abstraction. Calling
sendIntent / sendBatchIntent on an EOA session fails with E_SIGNER_UNSUPPORTED. If
you need chain abstraction, use the passkey signer.