SoroPass
SDK

createPasskey

Register an ES256-only passkey, extract its SEC-1 public key, deploy a smart account, and persist the credential via the @soropass/core/create subpath.

The @soropass/core/create subpath: register an ES256-only passkey, extract its SEC-1 public key, deploy a smart account through your factory, and persist the credential id. ES256 is enforced at the source — anything else hard-fails.

Overview

Import only what you need from the /create subpath. createPasskey is the one call most apps need; the rest are the building blocks it composes, exported for advanced flows and testing.

import {
  createPasskey,
  assertES256,
  buildCreateOptions,
  browserWebAuthnClient,
  defaultCredentialStorage,
  coseKeyToSec1,
} from '@soropass/core/create';

ES256-only invariant. pubKeyCredParams is exactly [{ type: 'public-key', alg: -7 }]. Any other algorithm (RS256, EdDSA, …) throws KitError('ES256_NOT_SUPPORTED') — Soroban verifies only secp256r1.

@stellar/stellar-sdk is a peer dependency and is never bundled into the SDK output. The contract-specific work lives behind the AccountDeployer you supply.

Highlights

  • ES256 at the sourcebuildCreateOptions emits pubKeyCredParams [{ type: 'public-key', alg: -7 }] only; assertES256 throws unless alg === -7.
  • SEC-1 extraction — the CBOR COSE EC2 key is decoded to a 65-byte SEC-1 0x04‖X‖Y point; non-P-256 keys (RS256) hard-fail.
  • Safari gesture ruleassertUserActivation enforces the WebKit active-user-gesture requirement; the create-button click is the gesture.
  • Factory deploy — your AccountDeployer deploys the smart account for the new passkey and returns its contractId.
  • Pluggable clientsbrowserWebAuthnClient and defaultCredentialStorage are defaults; pass your own WebAuthnClient / CredentialStorage.
  • Credential persisted — the credential id is stored so connect() can find the account later, with an in-memory fallback for Node / SSR.

createPasskey()

Register an ES256-only passkey, extract its SEC-1 public key (RS256 hard-fails), deploy a smart account via the factory, persist the credential id, and return the account.

createPasskey(options: CreatePasskeyOptions): Promise<PasskeyCredential>

CreatePasskeyOptions

FieldTypeDescription
rpId (required)stringYour site's registrable domain.
rpName (required)stringHuman-readable relying-party name shown in the OS sheet.
userName (required)stringAccount name presented to the user during registration.
deployer (required)AccountDeployerDeploys the smart account for the new passkey (contract-specific).
webauthnWebAuthnClientWebAuthn client; defaults to browserWebAuthnClient().
storageCredentialStorageWhere the credential id is persisted; defaults to defaultCredentialStorage().
userIdUint8ArrayOptional user handle bytes; generated if omitted.
challengeUint8ArrayOptional registration challenge; generated if omitted.
residentKey'discouraged' | 'preferred' | 'required'authenticatorSelection.residentKey hint.
userVerification'discouraged' | 'preferred' | 'required'authenticatorSelection.userVerification hint.
userActivation{ isActive: boolean }Pass navigator.userActivation to enforce the Safari gesture rule.

Returns — PasskeyCredential

Returns Promise<PasskeyCredential> — the deployed account and its passkey.

FieldTypeDescription
contractIdstringC-address of the deployed smart account.
credentialIdstringWebAuthn credential id, persisted via storage for later connect().
publicKeyUint8Array65-byte SEC-1 secp256r1 public key (0x04‖X‖Y).
register.ts
import { createPasskey } from '@soropass/core/create';

const account = await createPasskey({
  rpId: 'app.example.com',
  rpName: 'Example',
  userName: 'alice@example.com',
  deployer,                         // your AccountDeployer
  residentKey: 'required',
  userVerification: 'preferred',
  userActivation: navigator.userActivation, // Safari gesture rule
});

console.log(account.contractId);    // C... smart-account address
console.log(account.credentialId);  // persisted for connect()
console.log(account.publicKey.length); // 65 (SEC-1)

The create button click is the WebAuthn user gesture — call createPasskey directly from the click handler so the registration ceremony is allowed to prompt.

AccountDeployer

The contract-specific seam. createPasskey hands your deployer the extracted SEC-1 public key and credential id, and expects the deployed smart-account address back. Keeps the SDK free of any contract coupling.

interface AccountDeployer {
  deploy(input: {
    publicKey: Uint8Array;
    credentialId: string;
  }): Promise<{ contractId: string; txHash?: string }>;
}
FieldTypeDescription
input.publicKeyUint8Array65-byte SEC-1 public key of the new passkey.
input.credentialIdstringWebAuthn credential id to bind to the account.
→ contractIdstringC-address of the deployed smart account.
→ txHashstring?Optional deploy transaction hash.

Assertions & options

The guards and option-builder that enforce the invariants. createPasskey calls these internally; they're exported so you can assert at your own boundaries.

assertES256()

Throws ES256_NOT_SUPPORTED unless alg === -7.

assertES256(alg: number): void

assertUserActivation()

Throws USER_CANCELLED if not an active user gesture (Safari / WebKit rule).

assertUserActivation(activation?: { isActive: boolean }): void
guards.ts
import { assertES256, assertUserActivation } from '@soropass/core/create';

button.addEventListener('click', () => {
  assertUserActivation(navigator.userActivation); // throws USER_CANCELLED otherwise
  assertES256(-7);                                // ok; -257 (RS256) throws
});

buildCreateOptions()

Builds a PublicKeyCredentialCreationOptions with pubKeyCredParams [{ type: 'public-key', alg: -7 }] only.

buildCreateOptions(/* ... */): PublicKeyCredentialCreationOptions

Clients & storage

Default, swappable adapters for the WebAuthn ceremony and credential persistence. Override either via CreatePasskeyOptions.webauthn / .storage.

FunctionReturnsDescription
browserWebAuthnClient()WebAuthnClientnavigator.credentials-backed client (the default).
defaultCredentialStorage()CredentialStoragelocalStorage with an in-memory fallback (Node / SSR).
browserWebAuthnClient(): WebAuthnClient
defaultCredentialStorage(): CredentialStorage

In Node / SSR there is no localStorage; defaultCredentialStorage() falls back to an in-memory store so the SDK stays import-safe outside the browser.

Public-key extraction

The path from a WebAuthn attestation to the 65-byte SEC-1 point the contract verifies. Each step is exported so you can extract from whichever shape you hold.

FunctionReturnsDescription
coseKeyToSec1(coseKey)Uint8ArrayCBOR COSE EC2 → 65-byte SEC-1 0x04‖X‖Y; enforces P-256, else throws ES256_NOT_SUPPORTED.
extractPublicKeyFromAuthData(authData)Uint8ArrayPulls the COSE key out of authenticatorData and returns the SEC-1 point.
extractPublicKeyFromAttestationObject(attestationObject)Uint8ArrayDecodes the attestationObject and returns the SEC-1 point.
coseKeyToSec1(coseKey: Uint8Array): Uint8Array
extractPublicKeyFromAuthData(authData: Uint8Array): Uint8Array
extractPublicKeyFromAttestationObject(attestationObject: Uint8Array): Uint8Array
extract.ts
import {
  extractPublicKeyFromAttestationObject,
} from '@soropass/core/create';

// 65-byte SEC-1 point: 0x04 ‖ X ‖ Y — non-P-256 keys throw ES256_NOT_SUPPORTED
const publicKey = extractPublicKeyFromAttestationObject(attestationObject);

Need the full error taxonomy? See the KitError taxonomy for every code these functions can throw.

On this page