SoroPass

Introduction

A minimal passkey SDK plus drop-in create / sign / recover components for Stellar smart accounts, adopted into stellar-wallets-kit.

A minimal passkey SDK plus drop-in create / sign / recover components for Stellar smart accounts — adopted into stellar-wallets-kit. Wallet teams ship passkeys without hand-rolling WebAuthn, on-chain signing, or compatibility logic. It is a layer, not a wallet — no accounts to manage, no balances of our own.

Proven, not promised

The secp256r1 __check_auth path is verified on testnet, not modeled — a real passkey signature authorizes a smart-account call, and a wrong-key signature is rejected on-chain. See the deployed webauthn-account contract on Stellar Expert.

Two ways to adopt

What's in the box

Where it fits

LayerWhoWhat
Your productYour wallet / dAppyour UI + design system
SoroPass@soropassSDK + UI + PasskeyModule
Kitstellar-wallets-kitthe wallet kit you already use
On-chainSoroban smart accountnative secp256r1 verify

You own your product and design system; SoroPass is the passkey layer in between, built on already-deployed, audited smart-account contracts. We don't reinvent the contract layer.

Minimal surface

  • ES256-onlypubKeyCredParams pinned to alg −7; anything else throws ES256_NOT_SUPPORTED. Soroban verifies secp256r1.
  • Always low-S — signatures are low-S normalized client-side, so the ~50% of Apple passkeys that emit high-S still verify on-chain.
  • ~2 runtime deps — a tiny core (noble p256 + hashes); no heavy frameworks.
  • @stellar/stellar-sdk is a peer — declared as a peer dependency, never bundled into the SDK output.
  • Tree-shakeable subpaths — import only what you use: @soropass/core/create, /sign, /recover, /connect.

Try it in 20 seconds

Mock mode — zero network, no authenticator, runs in CI. The same facade swaps to mode: 'real' for production.

demo.ts
import { createPasskeyKit } from '@soropass/core/testing';

const kit = createPasskeyKit({ mode: 'mock', rpId: 'localhost' });

const cred = await kit.createPasskey({ userName: 'alice' });
console.log(cred.contractId); // C-address of the new smart account

const signed = await kit.signAuthEntry(entryXdr);
const accounts = await kit.recover();

On this page