Thanks to visit codestin.com
Credit goes to github.com

Skip to content

kalepail/passkey-kit

Repository files navigation

Passkey Kit

Tip

Looking for the latest smart wallet SDK?

This package is the legacy precursor to OpenZeppelin Smart Accounts. For new projects, use smart-account-kit — a comprehensive SDK built on top of the audited OpenZeppelin stellar-contracts library.

Smart Account Kit includes:

  • Context rules with fine-grained authorization scopes
  • Policy support (threshold multisig, spending limits, custom policies)
  • Session management with automatic credential persistence
  • External wallet adapter support
  • Built-in indexer for contract discovery

See the OpenZeppelin Smart Account package and multisig example for more details.

Warning

Code in this repo is demo material only. It has not been audited. Do not use to hold, protect, or secure anything.

A TypeScript SDK for creating and managing Stellar smart wallets using passkeys. Works with OpenZeppelin Relayer for submitting passkey-signed transactions onchain.

Demo: passkey-kit-demo.pages.dev

Installation

pnpm i passkey-kit

Exports

import {
    PasskeyKit,      // Client-side wallet management
    PasskeyServer,   // Server-side utilities
    SACClient,       // Stellar Asset Contract helper
    PasskeyClient,   // Low-level contract client (from passkey-kit-sdk)
    SignerKey,       // Signer key type constructor
    SignerStore,     // Storage type enum
    type Signer,     // Signer type
    type SignerLimits // Signer limits type
} from 'passkey-kit'

PasskeyKit (Client)

Handles wallet creation, connection, and transaction signing.

Constructor

const account = new PasskeyKit({
    rpcUrl: string,              // Stellar RPC URL
    networkPassphrase: string,   // Network passphrase
    walletWasmHash: string,      // Smart wallet WASM hash
    timeoutInSeconds?: number,   // Transaction timeout (default: 30)
    WebAuthn?: {                 // Optional WebAuthn override
        startRegistration,
        startAuthentication
    }
})

Properties

Property Type Description
keyId string | undefined Current passkey ID (base64url)
wallet PasskeyClient | undefined Connected wallet client
networkPassphrase string Network passphrase

Methods

createWallet(app, user, settings?)

Creates a new passkey and deploys a smart wallet.

const { rawResponse, keyId, keyIdBase64, contractId, signedTx } = await account.createWallet(
    'My App',           // App name shown in passkey prompt
    '[email protected]', // User identifier
    {
        rpId?: string,  // Relying party ID
        authenticatorSelection?: AuthenticatorSelectionCriteria
    }
)

createKey(app, user, settings?)

Creates a new passkey without deploying a wallet.

const { rawResponse, keyId, keyIdBase64, publicKey } = await account.createKey(
    'My App',
    '[email protected]',
    { rpId?: string, authenticatorSelection?: AuthenticatorSelectionCriteria }
)

connectWallet(opts?)

Connects to an existing wallet using a passkey.

const { rawResponse, keyId, keyIdBase64, contractId } = await account.connectWallet({
    rpId?: string,
    keyId?: string | Uint8Array,           // Skip passkey prompt if provided
    getContractId?: (keyId: string) => Promise<string | undefined>,  // Lookup function
    walletPublicKey?: string               // For backwards compatibility
})

sign(txn, options?)

Signs all auth entries for the connected wallet in a transaction.

const signedTxn = await account.sign(
    txn,  // AssembledTransaction | Tx | string (XDR)
    {
        rpId?: string,
        keyId?: 'any' | string | Uint8Array,  // 'any' allows any passkey
        keypair?: Keypair,                     // Sign with Ed25519 instead
        policy?: string,                       // Sign with policy instead
        expiration?: number                    // Ledger expiration
    }
)

signAuthEntry(entry, options?)

Signs a single authorization entry. Same options as sign().

const signedEntry = await account.signAuthEntry(entry, options)

Signer Management

Add, update, or remove signers from the wallet.

// Add signers
await account.addSecp256r1(keyId, publicKey, limits, store, expiration?)
await account.addEd25519(publicKey, limits, store, expiration?)
await account.addPolicy(policy, limits, store, expiration?)

// Update signers
await account.updateSecp256r1(keyId, publicKey, limits, store, expiration?)
await account.updateEd25519(publicKey, limits, store, expiration?)
await account.updatePolicy(policy, limits, store, expiration?)

// Remove signer
await account.remove(signerKey)

Parameters:

  • keyId - Passkey ID (string or Uint8Array)
  • publicKey - Public key (string or Uint8Array for Secp256r1, Stellar public key for Ed25519)
  • policy - Policy contract address
  • limits - SignerLimits (see Types below)
  • store - SignerStore.Persistent or SignerStore.Temporary
  • expiration - Optional ledger expiration

PasskeyServer (Server)

Server-side utilities for Mercury indexing and OpenZeppelin Relayer.

Constructor

const server = new PasskeyServer({
    rpcUrl?: string,
    relayerUrl?: string,         // OpenZeppelin Relayer URL
    relayerApiKey?: string,      // Relayer API key
    mercuryProjectName?: string, // Mercury project name
    mercuryUrl?: string,         // Mercury URL
    mercuryJwt?: string,         // Mercury JWT (use either JWT or Key)
    mercuryKey?: string          // Mercury API key
})

Methods

getSigners(contractId)

Get all signers for a wallet from Mercury.

const signers: Signer[] = await server.getSigners('C...')

getContractId(options, index?)

Reverse lookup a wallet address from a signer.

const contractId = await server.getContractId({
    keyId?: string,     // Passkey ID (Secp256r1)
    publicKey?: string, // Ed25519 public key
    policy?: string     // Policy address
}, index)  // If multiple wallets, select by index (default: 0)

send(txn)

Submit a transaction via OpenZeppelin Relayer.

const result = await server.send(txn)  // AssembledTransaction | Tx | string

SACClient

Helper for interacting with Stellar Asset Contracts.

const sac = new SACClient({
    networkPassphrase: string,
    rpcUrl: string
})

const tokenClient = sac.getSACClient('C...')  // SAC contract ID

Types

SignerKey

SignerKey.Policy(contractAddress)    // Policy signer
SignerKey.Ed25519(publicKey)         // Ed25519 signer
SignerKey.Secp256r1(keyId)           // Passkey signer

SignerLimits

type SignerLimits = Map<string, SignerKey[] | undefined> | undefined

// Example: Limit signer to specific contract, requires co-signer
const limits = new Map([
    ['C...contractAddress', [SignerKey.Ed25519('G...')]]
])

SignerStore

enum SignerStore {
    Persistent = 'Persistent',  // Permanent storage
    Temporary = 'Temporary'     // Expires, cheaper
}

Signer

type Signer = {
    kind: string       // 'Secp256r1' | 'Ed25519' | 'Policy'
    key: string        // Signer identifier
    val: string        // Public key or empty
    expiration: number | null
    storage: 'Persistent' | 'Temporary'
    limits: string     // JSON stringified limits
    evicted?: boolean  // True if temporary signer was evicted
}

Deploy the Mercury Indexer

To track signers and reverse lookup wallet addresses, deploy the Zephyr program:

cd ./zephyr
cargo install mercury-cli
# Get a JWT from https://test.mercurydata.app
export MERCURY_JWT="<YOUR.MERCURY.JWT>"
# Requires Rust 1.79.0+
mercury-cli --jwt $MERCURY_JWT --local false --mainnet false deploy

TypeScript Configuration

This library exports TypeScript only to avoid bundling @stellar/stellar-sdk twice. Configure your bundler to transpile it.

Next.js (next.config.mjs):

/** @type {import('next').NextConfig} */
const nextConfig = {
    transpilePackages: [
        'passkey-kit',
        'passkey-factory-sdk',
        'passkey-kit-sdk',
        'sac-sdk',
    ]
}

export default nextConfig

Contributing

# Install dependencies
pnpm i

# Build
pnpm run build

# Run demo
cd ./demo && pnpm i && pnpm run start

Directory structure:

  • ./src - TypeScript SDK source
  • ./demo - Demo application
  • ./contracts - Rust Soroban smart contracts
  • ./zephyr - Mercury Zephyr indexer program

Important

If modifying contracts in ./contracts, run the make commands. Update SMART_WALLET_FACTORY and SMART_WALLET_WASM values from make deploy before running make init.

Important

The bindings in ./packages have been heavily modified. When rebuilding, prefer updating only the src/index.ts files in each package.


Resources

About

TS SDK for creating and managing Stellar smart wallets

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors 3

  •  
  •  
  •  

Languages