Hi Creit Tech team,
We've been building a cross-chain passkey wallet sdk (Veridex) and would like to upstream a Stellar wallet module that exposes a WebAuthn/passkey-backed Soroban smart account through the existing StellarWalletsKit plugin surface. We're opening this issue before filing a PR so we can align with you on the integration approach.
What it is
A ModuleInterface implementation whose signTransaction / signAuthEntry / signMessage methods produce SEP-43 envelopes carrying a WebAuthn assertion. The on-chain half is a small Soroban custom account whose __check_auth verifies secp256r1 via Crypto::secp256r1_verify.
- Module shape: matches existing modules (Freighter, xBull, Lobstr).
moduleType = HOT_WALLET, isPlatformWrapper = false.
- Public key: 65-byte SEC1-uncompressed (0x04 || X || Y) stored in contract instance storage at init time.
- Signed message construction follows the canonical WebAuthn rule:
sha256(authenticatorData || sha256(clientDataJSON)).
- Footprint: ~250 LOC for the module, ~150 LOC for the contract. No new runtime dep on the kit side beyond
@simplewebauthn/browser.
Reference implementation
Working prototype (links to be filled in once the demo repo is public):
- Off-chain:
VeridexStellarWalletModule implementing ModuleInterface, plus a thin StellarPasskeySigner and
deterministic deriveSmartAccountId helper.
- On-chain: single-key
PasskeySmartAccount Soroban contract (soroban-sdk 22.x).
- Demo: Vite + React app that plugs the module into
StellarWalletsKit alongside allowAllModules() and exercises getAddress / signMessage / signAuthEntry end-to-end on testnet.
Proposed integration plan (in this repo, not a parallel package)
We'd like to land the module directly under src/sdk/modules/ rather than ship a side-package. Concretely, three small PRs:
- PR 1 - Module skeleton. Adds the
ModuleInterface implementation, icon asset, and a smoke test that mocks the WebAuthn surface. No change to public types.
- PR 2 - Smart-account adapter. A small helper that resolves a passkey to its Soroban contract id. We'd prefer to delegate the on-chain side to Tyler's
kalepail/smart-account-kit rather than ship our own contract, if that's the direction you and Tyler are converging on (open question below).
- PR 3 - Docs + compatibility matrix. README page documenting browser/OS/authenticator support, including known gaps (Firefox/Linux quirks, iCloud sync edge cases).
Each PR stands alone and can be reverted independently.
Open questions
- Coordination with
kalepail/smart-account-kit. What's the cleanest seam, should this module delegate contract deployment +
lookup to smart-account-kit, or is there a smaller primitive you'd prefer we call directly? We'll ping Tyler in parallel so the three of us land on one story.
ModuleType surface. HOT_WALLET is the closest existing fit, but a smart-account-backed signer is operationally distinct (no extension, no QR, no mobile-app handoff). Worth introducing a SMART_ACCOUNT variant, or is product-name + icon enough disambiguation for the built-in modal?
- SEP-43 container shape. Today we emit a base64 JSON envelope so the signed payload survives a generic relayer. Happy to harmonize with whatever container
smart-account-kit (and downstream wallets like Meridian Pay) are converging on.
- Compatibility matrix. We've tested Chrome/Safari/Firefox on macOS / iOS / Android, with platform authenticators, YubiKey, and 1Password/iCloud sync. Happy to add the matrix to
/docs in this repo.
What's the best way to keep this coordinated, async on this issue, or would a short call work? We can match your timezone.
Thanks!
Hi Creit Tech team,
We've been building a cross-chain passkey wallet sdk (Veridex) and would like to upstream a Stellar wallet module that exposes a WebAuthn/passkey-backed Soroban smart account through the existing
StellarWalletsKitplugin surface. We're opening this issue before filing a PR so we can align with you on the integration approach.What it is
A
ModuleInterfaceimplementation whosesignTransaction/signAuthEntry/signMessagemethods produce SEP-43 envelopes carrying a WebAuthn assertion. The on-chain half is a small Soroban custom account whose__check_authverifies secp256r1 viaCrypto::secp256r1_verify.moduleType = HOT_WALLET,isPlatformWrapper = false.sha256(authenticatorData || sha256(clientDataJSON)).@simplewebauthn/browser.Reference implementation
Working prototype (links to be filled in once the demo repo is public):
VeridexStellarWalletModuleimplementingModuleInterface, plus a thinStellarPasskeySigneranddeterministic
deriveSmartAccountIdhelper.PasskeySmartAccountSoroban contract (soroban-sdk22.x).StellarWalletsKitalongsideallowAllModules()and exercisesgetAddress/signMessage/signAuthEntryend-to-end on testnet.Proposed integration plan (in this repo, not a parallel package)
We'd like to land the module directly under
src/sdk/modules/rather than ship a side-package. Concretely, three small PRs:ModuleInterfaceimplementation, icon asset, and a smoke test that mocks the WebAuthn surface. No change to public types.kalepail/smart-account-kitrather than ship our own contract, if that's the direction you and Tyler are converging on (open question below).Each PR stands alone and can be reverted independently.
Open questions
kalepail/smart-account-kit. What's the cleanest seam, should this module delegate contract deployment +lookup to
smart-account-kit, or is there a smaller primitive you'd prefer we call directly? We'll ping Tyler in parallel so the three of us land on one story.ModuleTypesurface.HOT_WALLETis the closest existing fit, but a smart-account-backed signer is operationally distinct (no extension, no QR, no mobile-app handoff). Worth introducing aSMART_ACCOUNTvariant, or is product-name + icon enough disambiguation for the built-in modal?smart-account-kit(and downstream wallets like Meridian Pay) are converging on./docsin this repo.What's the best way to keep this coordinated, async on this issue, or would a short call work? We can match your timezone.
Thanks!