> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://v3.viem.sh/api/mcp` to find what you need.

# `WebAuthn.createCredential`

Registers a **WebAuthn Credential** designed to be used to create a [WebAuthn Account](/account-abstraction/accounts/webauthn/fromCredential).

:::note
This function uses [`ox/WebAuthn`](https://github.com/wevm/ox) under the hood.
:::

## Overview

`WebAuthn.createCredential` initiates the WebAuthn (passkey) registration flow on the user's device, creating a cryptographic P256 credential that can later be used for authentication.

This function uses `navigator.credentials.create()` internally. [Read more](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/create).

## Import

```ts twoslash
import { WebAuthn } from 'viem/utils'
```

## Usage

At minimum, you need to provide a name to identify the credential:

```ts twoslash
import { WebAuthnAccount } from 'viem/erc4337'
import { WebAuthn } from 'viem/utils'

// Register a credential (ie. passkey). // [!code focus]
const credential = await WebAuthn.createCredential({ // [!code focus]
  name: 'Example', // [!code focus]
}) // [!code focus]

// Create a WebAuthn account from the credential.
const account = WebAuthnAccount.fromCredential(credential)
```

The function returns a `P256Credential` object that you can then pass to `WebAuthnAccount.fromCredential()` to create an account, or store in your database for later use.

## Returns

`P256Credential`

A P-256 WebAuthn Credential object with the following structure:

```ts
{
  attestationObject: ArrayBuffer
  clientDataJSON: ArrayBuffer
  id: string
  publicKey: PublicKey
  raw: PublicKeyCredential
}
```

This credential object is designed to be passed to `WebAuthnAccount.fromCredential()` to create a `WebAuthnAccount`, which can sign User Operations and messages.

## Parameters

### challenge

* **Type:** `Uint8Array`

A random cryptographic value that proves the credential creation request. If you don't provide one, the function generates a random one.

```ts twoslash
import { WebAuthn } from 'viem/utils'
const credential = await WebAuthn.createCredential({
  challenge: new Uint8Array([1, 2, 3]),
  name: 'Example',
})
```

### createFn

* **Type:** `(options: CredentialCreationOptions) => Promise<Credential | null>`
* **Default:** `window.navigator.credentials.create`

Allows you to override the default credential creation function. By default, it uses `window.navigator.credentials.create`, which is the standard WebAuthn API. Override this only if you're in an environment that doesn't support WebAuthn natively (React Native, test environments, etc.). Pass a custom function that accepts the same options and returns a credential or null.

```ts twoslash
// @noErrors
import { WebAuthnAccount } from 'viem/erc4337'
import { WebAuthn } from 'viem/utils'
import * as passkey from 'react-native-passkeys'

const credential = await WebAuthn.createCredential({
  name: 'Example',
  createFn: passkey.create,
})

const account = WebAuthnAccount.fromCredential(credential)
```

### excludeCredentialIds

* **Type:** `string[]`

An array of credential IDs you want to prevent from being re-registered. If a user already has a credential with one of these IDs on their device, the registration will fail. Use this to prevent duplicate credentials and ensure each device can only register once.

```ts twoslash
import { WebAuthn } from 'viem/utils'
const credential = await WebAuthn.createCredential({
  excludeCredentialIds: ['abc', 'def'],
  name: 'Example',
})
```

### name

* **Type:** `string`

A user-friendly display name for the credential. This appears in your browser's credential manager and helps users identify which passkey they're using. Use something descriptive like "My Laptop Fingerprint" or "Security Key".

```ts twoslash
import { WebAuthn } from 'viem/utils'
const credential = await WebAuthn.createCredential({
  name: 'Example',
})
```

### rp

* **Type:** `{ id: string; name: string }`

An object describing the relying party. [Read more](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions#rp).

```ts twoslash
import { WebAuthn } from 'viem/utils'
const credential = await WebAuthn.createCredential({
  name: 'Example',
  rp: {
    id: 'example.com',
    name: 'Example',
  },
})
```

### timeout

* **Type:** `number`

How long (in milliseconds) to wait for the user to complete the registration.

```ts twoslash
import { WebAuthn } from 'viem/utils'
const credential = await WebAuthn.createCredential({
  name: 'Example',
  timeout: 1000,
})
```

## Error Cases

The registration can fail or be cancelled for several reasons:

* The user cancels the credential creation dialog
* The device doesn't support WebAuthn
* The credential already exists (if using `excludeCredentialIds`)
* The timeout expires while waiting for user interaction
* The authenticator is locked or unavailable

Wrap the function call in a try-catch block to handle these gracefully.
