Overview
PasskeyWalletClient is a viem-compatible wallet client that extends the standard WalletClient with passkey-authenticated transaction signing. It provides a familiar viem API while handling all WebAuthn operations internally.
Use this when you want:
- A standard viem
WalletClientinterface - Batched transaction support via
sendCalls() - Output-first token requests (specify what tokens you want to receive)
Creating a Wallet Client
import { createPasskeyWalletClient } from '@rhinestone/1auth';
import { base } from 'viem/chains';
import { http } from 'viem';
const walletClient = createPasskeyWalletClient({
accountAddress: '0x...', // User's smart account address
username: 'user@example.com',
chain: base,
transport: http(),
});Config Options
| Option | Type | Required | Description |
|---|---|---|---|
accountAddress | Address | Yes | User's smart account address |
username | string | Yes | Username for the passkey provider |
chain | Chain | Yes | viem chain configuration |
transport | Transport | Yes | viem transport (e.g., http()) |
providerUrl | string | No | URL of the 1auth provider (defaults to https://passkey.1auth.box) |
dialogUrl | string | No | URL for the dialog UI |
waitForHash | boolean | No | Wait for transaction hash before resolving (default: true) |
hashTimeoutMs | number | No | Maximum time to wait for hash in ms |
hashIntervalMs | number | No | Poll interval for hash in ms |
sendCalls
Send multiple calls as a single batched transaction. Opens the passkey modal for user approval.
const hash = await walletClient.sendCalls({
calls: [
{
to: '0x...', // Contract address
data: '0x...', // Encoded calldata
value: parseEther('0.1'), // Optional ETH value
label: 'Swap ETH for USDC', // Optional: shown in signing UI
sublabel: '0.1 ETH → 250 USDC', // Optional: additional context
},
],
chainId: 8453, // Optional: override chain
});Parameters
| Property | Type | Required | Description |
|---|---|---|---|
calls | TransactionCall[] | Yes | Array of calls to execute |
chainId | number | No | Override the default chain ID |
tokenRequests | { token: string; amount: bigint }[] | No | Output tokens to deliver |
TransactionCall
| Property | Type | Required | Description |
|---|---|---|---|
to | Address | Yes | Target contract address |
data | Hex | No | Encoded calldata |
value | bigint | No | ETH value in wei |
label | string | No | Label shown in signing UI |
sublabel | string | No | Additional context for UI |
Returns
Promise<Hash> - The transaction hash once confirmed.
Token Requests (Output-First Model)
The tokenRequests parameter lets you specify what tokens and amounts you want to receive as the output of your transaction. This is the output-first model - you declare the desired result, and the orchestrator figures out how to achieve it.
import { parseUnits } from 'viem';
const hash = await walletClient.sendCalls({
calls: [
{
to: '0xUSDC_ADDRESS',
data: '0x', // Empty for simple transfers
label: 'Receive USDC',
},
],
tokenRequests: [
{
token: '0xUSDC_ADDRESS', // Token contract address
amount: parseUnits('100', 6), // 100 USDC (6 decimals)
},
],
});Type Signature
tokenRequests?: {
token: string; // ERC-20 token contract address
amount: bigint; // Amount in base units (use parseUnits)
}[];When to Use Token Requests
- Swaps: Specify the output token and amount you want to receive
- Cross-chain transfers: Declare the destination token and amount
- Multi-step operations: Let the orchestrator optimize the path
The orchestrator will automatically:
- Determine required input tokens from your portfolio
- Find the optimal route across chains
- Execute bridging and swaps as needed
Example: Token Swap
import { parseUnits } from 'viem';
// Swap: receive 100 USDC on Base
const hash = await walletClient.sendCalls({
calls: [
{
to: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
data: '0x',
label: 'Swap to USDC',
sublabel: 'Receive 100 USDC',
},
],
tokenRequests: [
{
token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
amount: parseUnits('100', 6),
},
],
chainId: 8453, // Base
});
console.log('Transaction hash:', hash);Notes
- The client extends viem's
WalletClient, so standard methods likegetAddresses()work as expected sendCalls()opens the passkey modal for user approval before executing- Use
waitForHash: falseif you only need intent confirmation (faster, but no hash) - Token amounts use
bigintfor viem compatibility - useparseUnits()for decimals