
Security News
Federal Audit Finds NIST Wasted Funds With No Plan to Clear NVD Backlog
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.
passkey-kit
Advanced tools
A helper library for creating and using smart wallet accounts on the Stellar blockchain.
[!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
pnpm i passkey-kit
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'
Handles wallet creation, connection, and transaction signing.
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
}
})
| Property | Type | Description |
|---|---|---|
keyId | string | undefined | Current passkey ID (base64url) |
wallet | PasskeyClient | undefined | Connected wallet client |
networkPassphrase | string | Network passphrase |
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
'user@example.com', // 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',
'user@example.com',
{ 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)
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 addresslimits - SignerLimits (see Types below)store - SignerStore.Persistent or SignerStore.Temporaryexpiration - Optional ledger expirationServer-side utilities for Mercury indexing and OpenZeppelin Relayer.
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
})
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
Helper for interacting with Stellar Asset Contracts.
const sac = new SACClient({
networkPassphrase: string,
rpcUrl: string
})
const tokenClient = sac.getSACClient('C...') // SAC contract ID
SignerKey.Policy(contractAddress) // Policy signer
SignerKey.Ed25519(publicKey) // Ed25519 signer
SignerKey.Secp256r1(keyId) // Passkey signer
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...')]]
])
enum SignerStore {
Persistent = 'Persistent', // Permanent storage
Temporary = 'Temporary' // Expires, cheaper
}
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
}
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
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
# 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. UpdateSMART_WALLET_FACTORYandSMART_WALLET_WASMvalues frommake deploybefore runningmake init.
[!IMPORTANT] The bindings in
./packageshave been heavily modified. When rebuilding, prefer updating only thesrc/index.tsfiles in each package.
FAQs
A helper library for creating and using smart wallet accounts on the Stellar blockchain.
The npm package passkey-kit receives a total of 405 weekly downloads. As such, passkey-kit popularity was classified as not popular.
We found that passkey-kit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Federal audit finds NIST lacked a plan to clear the NVD backlog, wasted funds on duplicate work, and delayed use of CISA data.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.

Research
/Security News
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.