{"_id":"webauthx","_rev":"4-4602cb71f91a0522eb234ddc605e6953","name":"webauthx","dist-tags":{"latest":"0.1.2"},"versions":{"0.0.0":{"name":"webauthx","version":"0.0.0","_id":"webauthx@0.0.0","maintainers":[{"name":"jmoxey","email":"jakemoxey@gmail.com"}],"dist":{"shasum":"072a90a28cb1d81685756abd061457148c4f2dfc","tarball":"https://registry.npmjs.org/webauthx/-/webauthx-0.0.0.tgz","fileCount":1,"integrity":"sha512-LimWMv9EdaVys6wgrKlMxM59MoUf9qL8vI7udqpWR18nxL0IQ5LhGPrJSusiUzQcgYBGA7+QCHFzc/AVmgsLpQ==","signatures":[{"sig":"MEUCIB1lTNfjMba+MMzRm2ZW3dH/V9B+UhpBM0y6Oinwk0jWAiEAovmtkHsCIlcakCUQrDvfhYuy92w4BYHkzmrRZj16zLs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47},"_npmUser":{"name":"jmoxey","email":"jakemoxey@gmail.com"},"_npmVersion":"10.8.2","directories":{},"_nodeVersion":"24.6.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/webauthx_0.0.0_1771549607699_0.36027246684345404","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"webauthx","version":"0.1.0","license":"MIT","_id":"webauthx@0.1.0","maintainers":[{"name":"jmoxey","email":"jakemoxey@gmail.com"}],"homepage":"https://github.com/wevm/webauthx#readme","bugs":{"url":"https://github.com/wevm/webauthx/issues"},"dist":{"shasum":"2d1a96ab27e33d437132ec9fe4eacf80c470de04","tarball":"https://registry.npmjs.org/webauthx/-/webauthx-0.1.0.tgz","fileCount":46,"integrity":"sha512-Z43YHetVeXdV5/4+YqKSz+cAflpbMmxSMz//kXEb2u3ZUqVbPG1zrM+Zp7KaME/QgUFGhGkAE2XHwqCAXnU75g==","signatures":[{"sig":"MEYCIQDbocuJCVopXLMmiJENPWah7egIcPiEj8YezoopIxFnXQIhAL6ml4Ol5jHqmSoMy0whx/PDtKVDMwSo8PnocxzRrhJ6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/webauthx@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":73365},"main":"./dist/index.js","type":"module","_from":"file:webauthx-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"src":"./src/index.ts","types":"./dist/index.d.ts","default":"./dist/index.js"},"./client":{"src":"./src/client/index.ts","types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./server":{"src":"./src/server/index.ts","types":"./dist/server/index.d.ts","default":"./dist/server/index.js"}},"scripts":{"dev":"zile dev","test":"vitest","build":"zile","check":"oxlint --fix --ignore-pattern package.json && oxfmt","check:types":"tsc -b","changeset:publish":"zile publish:prepare && changeset publish && zile publish:post","changeset:version":"changeset version"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f9542a78-7820-4f97-a9f3-c262750ab6f0"}},"_resolved":"/tmp/81f27b7c03e655e65e696f47f98cb9ff/webauthx-0.1.0.tgz","_integrity":"sha512-Z43YHetVeXdV5/4+YqKSz+cAflpbMmxSMz//kXEb2u3ZUqVbPG1zrM+Zp7KaME/QgUFGhGkAE2XHwqCAXnU75g==","repository":{"url":"git+https://github.com/wevm/webauthx.git","type":"git"},"_npmVersion":"11.5.1","description":"<picture>   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-dark.svg\">   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/wevm/webau","directories":{},"sideEffects":false,"[!start-pkg]":"","_nodeVersion":"24.5.0","dependencies":{"ox":"~0.14.6"},"_hasShrinkwrap":false,"devDependencies":{"zile":"latest","oxfmt":"latest","oxlint":"latest","vitest":"latest","typescript":"latest","@types/node":"latest","@changesets/cli":"latest","@vitest/browser-playwright":"^4.0.18"},"_npmOperationalInternal":{"tmp":"tmp/webauthx_0.1.0_1774048735134_0.29707489568272893","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"webauthx","version":"0.1.1","license":"MIT","_id":"webauthx@0.1.1","maintainers":[{"name":"jmoxey","email":"jakemoxey@gmail.com"}],"homepage":"https://github.com/wevm/webauthx#readme","bugs":{"url":"https://github.com/wevm/webauthx/issues"},"dist":{"shasum":"eb3b549148efb2f431f91d59413e3f9af68789a0","tarball":"https://registry.npmjs.org/webauthx/-/webauthx-0.1.1.tgz","fileCount":46,"integrity":"sha512-3jiskZl0jiTUoO8r3ySUYItdXNDBpfzxnxPx7XM0giF2dIY7S4KqHVbH04Qglz98nP8RaSV1/+3eDCx1s3WDiQ==","signatures":[{"sig":"MEUCICv2DMBpklGspgiShUyWHZV4G3JcKUGALC6qlu1AyyEJAiEA1fUZs0e7JUGw+99hXYgWtES9HxGITffbtS43pHyP3sA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/webauthx@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":73366},"main":"./dist/index.js","type":"module","_from":"file:webauthx-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"src":"./src/index.ts","types":"./dist/index.d.ts","default":"./dist/index.js"},"./client":{"src":"./src/client/index.ts","types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./server":{"src":"./src/server/index.ts","types":"./dist/server/index.d.ts","default":"./dist/server/index.js"}},"scripts":{"dev":"zile dev","test":"vitest","build":"zile","check":"oxlint --fix --ignore-pattern package.json && oxfmt","check:types":"tsc -b","changeset:publish":"zile publish:prepare && changeset publish && zile publish:post","changeset:version":"changeset version"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f9542a78-7820-4f97-a9f3-c262750ab6f0"}},"_resolved":"/tmp/ca596f5f494a19739c358b14c8b3f583/webauthx-0.1.1.tgz","_integrity":"sha512-3jiskZl0jiTUoO8r3ySUYItdXNDBpfzxnxPx7XM0giF2dIY7S4KqHVbH04Qglz98nP8RaSV1/+3eDCx1s3WDiQ==","repository":{"url":"git+https://github.com/wevm/webauthx.git","type":"git"},"_npmVersion":"11.5.1","description":"<picture>   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-dark.svg\">   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/wevm/webau","directories":{},"sideEffects":false,"[!start-pkg]":"","_nodeVersion":"24.5.0","dependencies":{"ox":"~0.14.11"},"_hasShrinkwrap":false,"devDependencies":{"zile":"latest","oxfmt":"latest","oxlint":"latest","vitest":"latest","typescript":"latest","@types/node":"latest","@changesets/cli":"latest","@vitest/browser-playwright":"^4.0.18"},"_npmOperationalInternal":{"tmp":"tmp/webauthx_0.1.1_1775595493336_0.7620195548398234","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"webauthx","type":"module","version":"0.1.2","main":"./dist/index.js","license":"MIT","repository":{"type":"git","url":"git+https://github.com/wevm/webauthx.git"},"dependencies":{"ox":"~0.14.11"},"sideEffects":false,"module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","src":"./src/index.ts","default":"./dist/index.js"},"./client":{"types":"./dist/client/index.d.ts","src":"./src/client/index.ts","default":"./dist/client/index.js"},"./server":{"types":"./dist/server/index.d.ts","src":"./src/server/index.ts","default":"./dist/server/index.js"}},"_id":"webauthx@0.1.2","description":"<picture>   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-dark.svg\">   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/wevm/webau","bugs":{"url":"https://github.com/wevm/webauthx/issues"},"homepage":"https://github.com/wevm/webauthx#readme","_integrity":"sha512-J0H9/BOW/aRtWa/rKsGjf1+YQ5xkfgycTT455fsHyqG4+hYJ5dPDrNcIXrjGnjBKGru/qxY75m68iHg27rHoUg==","_resolved":"/tmp/835689b02b061b078b5c4cf249af148c/webauthx-0.1.2.tgz","_from":"file:webauthx-0.1.2.tgz","_nodeVersion":"24.5.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-J0H9/BOW/aRtWa/rKsGjf1+YQ5xkfgycTT455fsHyqG4+hYJ5dPDrNcIXrjGnjBKGru/qxY75m68iHg27rHoUg==","shasum":"f6e8f8974fbe5547b293e93ddb1cda7d1a98e893","tarball":"https://registry.npmjs.org/webauthx/-/webauthx-0.1.2.tgz","fileCount":52,"unpackedSize":93926,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/webauthx@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCafefGbCnOWdTu6Cv9xH9midSkN+aptZsteO4zYi6r5AIhANu0lmgUdfYNJ+HlOY3YBHrJidOUIzwMHUmicYZSTfRk"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f9542a78-7820-4f97-a9f3-c262750ab6f0"}},"directories":{},"maintainers":[{"name":"jmoxey","email":"jakemoxey@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/webauthx_0.1.2_1777309093421_0.7691526298184055"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-20T01:06:47.697Z","modified":"2026-04-27T16:58:13.818Z","0.0.0":"2026-02-20T01:06:47.823Z","0.1.0":"2026-03-20T23:18:55.281Z","0.1.1":"2026-04-07T20:58:13.473Z","0.1.2":"2026-04-27T16:58:13.557Z"},"bugs":{"url":"https://github.com/wevm/webauthx/issues"},"license":"MIT","homepage":"https://github.com/wevm/webauthx#readme","repository":{"type":"git","url":"git+https://github.com/wevm/webauthx.git"},"description":"<picture>   <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-dark.svg\">   <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/wevm/webau","maintainers":[{"name":"jmoxey","email":"jakemoxey@gmail.com"}],"readme":"<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-dark.svg\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-light.svg\">\n  <img alt=\"webauthx\" src=\"https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/.github/banner-light.svg\" width=\"100%\">\n</picture>\n\n<p></p>\n\n<p align=\"center\"><b>Tools for server ↔ client WebAuthn ceremony orchestration.</b></p>\n\n<p align=\"center\">\n  <a href=\"#quickprompt\">Quickprompt</a> · <a href=\"#install\">Install</a> · <a href=\"#usage-walkthrough\">Usage Walkthrough</a> · <a href=\"#api-reference\">API Reference</a> · <a href=\"#license\">License</a>\n</p>\n\n## Quickprompt\n\nPrompt your agent:\n\n```\nAdd passkey authentication to my app using https://raw.githubusercontent.com/wevm/webauthx/refs/heads/main/SKILL.md, and add it to my skills.\n```\n\n## Install\n\n```bash\nnpm i webauthx\n```\n\n```bash\npnpm i webauthx\n```\n\n```bash\nbun i webauthx\n```\n\n## Usage Walkthrough\n\n### Registration (Sign up)\n\nRegister a new passkey credential for a user. The server generates a challenge, the client creates the credential, and the server verifies it.\n\n#### 1. Generate Options (Server)\n\n```ts\nimport { Registration } from 'webauthx/server'\n\napp.post('/register/options', async (request) => {\n  const { name } = await request.json()\n\n  // Generate a challenge and WebAuthn options for the client.\n  const { challenge, options } = Registration.getOptions({\n    name,\n    rp: { id: 'example.com', name: 'Example' },\n  })\n\n  // Persist challenge for verification in the next step.\n  await store.storeChallenge(challenge)\n\n  // Send WebAuthn options to the client.\n  return Response.json({ options })\n})\n```\n\n#### 2. Create Credential (Client)\n\n```ts\nimport { Registration } from 'webauthx/client'\n\n// Fetch WebAuthn options from the server.\nconst { options } = await fetch('/register/options', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ name: 'alice' }),\n}).then((r) => r.json())\n\n// Prompt the user to create a passkey.\nconst credential = await Registration.create({ options })\n\n// Send the credential to the server for verification.\nawait fetch('/register/verify', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ credential }),\n})\n```\n\n#### 3. Verify Credential (Server)\n\n```ts\nimport { Registration } from 'webauthx/server'\n\napp.post('/register/verify', async (request) => {\n  const { credential } = await request.json()\n\n  // Consume the stored challenge (single-use).\n  const challenge = await store.consumeChallenge(request)\n\n  // Verify attestation & extract the public key.\n  const result = Registration.verify(credential, {\n    challenge,\n    origin: 'https://example.com',\n    rpId: 'example.com',\n  })\n\n  // Persist the credential for future authentication.\n  await store.storeCredential({\n    ...result.credential,\n    aaguid: result.aaguid,\n  })\n})\n```\n\n#### 4. Resolve Authenticator Name (Optional)\n\n```ts\nimport { Aaguid } from 'webauthx/server'\n\nconst info = await Aaguid.lookup({ id: storedCredential.aaguid })\n// => { name: '1Password', iconLight?: 'data:image/...', iconDark?: 'data:image/...' }\n// => null\n```\n\n### Authentication (Log in)\n\nAuthenticate a returning user with their existing passkey. The server generates a challenge, the client signs it, and the server verifies the signature.\n\n#### 1. Generate Options (Server)\n\n```ts\nimport { Authentication } from 'webauthx/server'\n\napp.post('/auth/options', async (request) => {\n  const { credentialId } = await request.json()\n\n  // Generate a challenge and WebAuthn options for the client.\n  const { challenge, options } = Authentication.getOptions({\n    credentialId,\n    rpId: 'example.com',\n  })\n\n  // Persist challenge for verification in the next step.\n  await store.storeChallenge(challenge)\n\n  // Send WebAuthn options to the client.\n  return Response.json({ options })\n})\n```\n\n#### 2. Sign Challenge (Client)\n\n```ts\nimport { Authentication } from 'webauthx/client'\n\n// Fetch WebAuthn options from the server.\nconst { options } = await fetch('/auth/options', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ credentialId }),\n}).then((r) => r.json())\n\n// Prompt the user to sign the challenge with their passkey.\nconst response = await Authentication.sign({ options })\n\n// Send the response to the server for verification.\nawait fetch('/auth/verify', {\n  method: 'POST',\n  headers: { 'Content-Type': 'application/json' },\n  body: JSON.stringify({ response }),\n})\n```\n\n#### 3. Verify Signature (Server)\n\n```ts\nimport { Authentication } from 'webauthx/server'\n\napp.post('/auth/verify', async (request) => {\n  const { response } = await request.json()\n\n  // Consume the stored challenge (single-use).\n  const challenge = await store.consumeChallenge(request)\n\n  // Look up the stored public key for this credential.\n  const credential = await store.getCredential(response.id)\n\n  // Verify the P-256 signature.\n  const valid = Authentication.verify(response, {\n    challenge,\n    publicKey: credential.publicKey,\n    origin: 'https://example.com',\n    rpId: 'example.com',\n  })\n})\n```\n\n## API Reference\n\n### `webauthx/client`\n\n#### `Authentication.sign`\n\nSigns a challenge via `navigator.credentials.get`. Accepts WebAuthn options from the server and returns a response ready to send back.\n\n##### Usage\n\n```ts\nimport { Authentication } from 'webauthx/client'\n\nconst response = await Authentication.sign({ options })\n```\n\n##### Parameters\n\n| Parameter | Type                       | Description                                        |\n| --------- | -------------------------- | -------------------------------------------------- |\n| `getFn`   | `function`                 | Custom credential request function (for testing).  |\n| `options` | `CredentialRequestOptions` | WebAuthn options from `Authentication.getOptions`. |\n\n##### Return Value\n\n`Promise<Authentication.Response>`\n\nResponse to send to the server.\n\n#### `Registration.create`\n\nCreates a new WebAuthn credential via `navigator.credentials.create`. Accepts WebAuthn options from the server and returns a credential ready to send back.\n\n##### Usage\n\n```ts\nimport { Registration } from 'webauthx/client'\n\nconst credential = await Registration.create({ options })\n```\n\n##### Parameters\n\n| Parameter  | Type                        | Description                                        |\n| ---------- | --------------------------- | -------------------------------------------------- |\n| `createFn` | `function`                  | Custom credential creation function (for testing). |\n| `options`  | `CredentialCreationOptions` | WebAuthn options from `Registration.getOptions`.   |\n\n##### Return Value\n\n`Promise<Registration.Credential>`\n\nCredential to send to the server.\n\n---\n\n### `webauthx/server`\n\n#### `Authentication.getOptions`\n\nGenerates `PublicKeyCredentialRequestOptions` for authentication. A random 32-byte challenge is generated if one isn't provided.\n\n##### Usage\n\n```ts\nimport { Authentication } from 'webauthx/server'\n\nconst { challenge, options } = Authentication.getOptions({\n  credentialId: storedCredential.id,\n  rpId: 'example.com',\n})\n```\n\n##### Parameters\n\n| Parameter          | Type                 | Description                                                             |\n| ------------------ | -------------------- | ----------------------------------------------------------------------- |\n| `challenge`        | `Hex`                | Optional challenge. A random 32-byte hex value is generated if omitted. |\n| `credentialId`     | `string \\| string[]` | Credential ID(s) to allow.                                              |\n| `rpId`             | `string`             | Relying party ID.                                                       |\n| `timeout`          | `number`             | Timeout in milliseconds.                                                |\n| `userVerification` | `string`             | User verification requirement.                                          |\n\n##### Return Value\n\n`{ challenge: Hex; options: CredentialRequestOptions }`\n\nChallenge to store and the WebAuthn options to send to the client.\n\n#### `Authentication.verify`\n\nVerifies an authentication response from the client. Validates the rpIdHash, origin, challenge, and P-256 signature.\n\n##### Usage\n\n```ts\nimport { Authentication } from 'webauthx/server'\n\nconst valid = Authentication.verify(response, {\n  challenge,\n  publicKey: credential.publicKey,\n  origin: 'https://example.com',\n  rpId: 'example.com',\n})\n```\n\n##### Parameters\n\n| Parameter           | Type                      | Description                                  |\n| ------------------- | ------------------------- | -------------------------------------------- |\n| `options.challenge` | `Hex`                     | Expected challenge.                          |\n| `options.origin`    | `string \\| string[]`      | Expected origin(s).                          |\n| `options.publicKey` | `Hex`                     | The stored P-256 public key (hex).           |\n| `options.rpId`      | `string`                  | Expected relying party ID.                   |\n| `response`          | `Authentication.Response` | The authentication response from the client. |\n\n##### Return Value\n\n`boolean`\n\n`true` if the signature is valid.\n\n#### `Registration.getOptions`\n\nGenerates `PublicKeyCredentialCreationOptions` for registration. A random 32-byte challenge is generated if one isn't provided.\n\n##### Usage\n\n```ts\nimport { Registration } from 'webauthx/server'\n\nconst { challenge, options } = Registration.getOptions({\n  name: 'alice',\n  rp: { id: 'example.com', name: 'Example' },\n})\n```\n\n##### Parameters\n\n| Parameter                | Type                                                        | Description                                                             |\n| ------------------------ | ----------------------------------------------------------- | ----------------------------------------------------------------------- |\n| `attestation`            | `string`                                                    | Attestation conveyance preference.                                      |\n| `authenticatorSelection` | `object`                                                    | Authenticator selection criteria.                                       |\n| `challenge`              | `Hex`                                                       | Optional challenge. A random 32-byte hex value is generated if omitted. |\n| `excludeCredentialIds`   | `string[]`                                                  | Credential IDs to exclude (prevent re-registration).                    |\n| `name`                   | `string`                                                    | Display name for the credential (shorthand for `user.name`).            |\n| `rp`                     | `{ id: string; name: string }`                              | Relying party identifier and display name.                              |\n| `timeout`                | `number`                                                    | Timeout in milliseconds.                                                |\n| `user`                   | `{ name: string; displayName?: string; id?: BufferSource }` | User account descriptor. Alternative to `name`.                         |\n\n##### Return Value\n\n`{ challenge: Hex; options: CredentialCreationOptions }`\n\nChallenge to store and the WebAuthn options to send to the client.\n\n#### `Registration.verify`\n\nVerifies a registration credential from the client. Validates the attestation, rpIdHash, challenge, and origin, and extracts the P-256 public key.\n\n##### Usage\n\n```ts\nimport { Registration } from 'webauthx/server'\n\nconst result = Registration.verify(credential, {\n  challenge,\n  origin: 'https://example.com',\n  rpId: 'example.com',\n})\n```\n\n##### Parameters\n\n| Parameter                  | Type                                                    | Description                                           |\n| -------------------------- | ------------------------------------------------------- | ----------------------------------------------------- |\n| `credential`               | `Registration.Credential`                               | The credential from the client.                       |\n| `options.challenge`        | `Hex \\| Uint8Array \\| ((challenge: string) => boolean)` | Expected challenge value or async validator function. |\n| `options.origin`           | `string \\| string[]`                                    | Expected origin(s) (e.g. `\"https://example.com\"`).    |\n| `options.rpId`             | `string`                                                | Relying party ID (e.g. `\"example.com\"`).              |\n| `options.userVerification` | `string`                                                | User verification requirement. Default: `'required'`. |\n\n##### Return Value\n\n`Registration.Response & { aaguid: string }`\n\nIncludes the verified credential, signature counter, and the credential's\nauthenticator AAGUID.\n\n### `webauthx/server`\n\nLooks up friendly authenticator metadata from the community-maintained AAGUID\nregistry. By default, the registry is fetched from the upstream combined JSON\nfile and cached in-memory for subsequent lookups.\n\n##### Usage\n\n```ts\nimport { Aaguid } from 'webauthx/server'\n\nconst info = await Aaguid.lookup({\n  id: '08987058-cadc-4b81-b6e1-30de50dcbe96',\n})\n```\n\n##### `Aaguid.extract`\n\nExtracts the AAGUID from a serialized registration credential.\n\n```ts\nconst aaguid = Aaguid.extract(credential)\n```\n\nReturns `string | undefined`.\n\n##### `Aaguid.lookup`\n\nLooks up authenticator metadata by AAGUID.\n\n```ts\nconst info = await Aaguid.lookup({ id: aaguid })\n```\n\nReturns `Aaguid.Info | null`.\n\nParameters:\n\n| Parameter    | Type           | Description                                                              |\n| ------------ | -------------- | ------------------------------------------------------------------------ |\n| `cache`      | `boolean`      | Reuse an in-memory cache for the selected `remoteList`. Default: `true`. |\n| `fetchFn`    | `typeof fetch` | Custom fetch implementation.                                             |\n| `id`         | `string`       | AAGUID to resolve.                                                       |\n| `remoteList` | `string`       | Override the remote registry URL. Defaults to `Aaguid.remoteList`.       |\n\n##### `Aaguid.Info`\n\n```ts\ntype Info = {\n  name: string\n  iconLight?: string | undefined\n  iconDark?: string | undefined\n}\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}