Testing with @stellar-passkey/core
The kit ships a mock-mode adapter so downstream adopters can unit- test code that consumes the SDK without standing up a Soroban RPC, deploying a real wallet contract, or driving navigator.credentials.* through a virtual authenticator.
ts
import { createMockKit } from "@stellar-passkey/core";
const kit = createMockKit({ rpId: "your-app.example" });
// 1) Register a synthetic passkey. The seed is deterministic — same
// seed → same P-256 keypair → same mock contract id.
const { contractId, credential } = await kit.createPasskey({
seed: new Uint8Array(32).fill(7),
userName: "alice",
});
// 2) Sign an unsigned Soroban tx envelope. The mock kit uses the same
// `signTransaction` from the live SDK — only the WebAuthn signer is
// replaced with a synthetic P-256 ECDSA over the auth-entry
// preimage. The on-chain `__check_auth` verifier sees a
// byte-identical Signature ScVal to a real Touch ID ceremony.
const { signedTxXdr, signerAddress } = await kit.signTransaction(
unsignedXdr,
{ contractId, credentialId: credential.id, latestLedger: 1_000_000 },
);
// 3) Recover every session held in memory.
const sessions = await kit.recoverPasskey();What's mocked
navigator.credentials.create/navigator.credentials.get— the mock kit never touches the WebAuthn API. The synthetic signer derives a P-256 keypair from a seed via@noble/curves.- Soroban RPC —
connectPasskey/recoverPasskeyresolve from the in-memory map; there is zero outbound network I/O. DeployerCallbacks—createPasskeydoes not call out to a deployer. A mock C-address is derived deterministically from the public key.
What's not mocked
- The auth-entry signing pipeline — DER ↔ raw conversion, low-S normalisation, the
SignatureScVal layout — uses the livesignTransaction/signAuthEntryfrom./sign.ts. Bugs in that path show up identically in mock-mode tests and on testnet. - Apple's high-S quirk. Virtual authenticators (including this mock signer) use deterministic nonces and never emit high-S. To exercise the
normalizeLowSpath, use the pinned fixtures intests/fixtures/apple-high-s/(YK-274).
Gate
The mock kit's unit test (packages/core/src/mock.test.ts) asserts:
createPasskey→signTransaction→recoverPasskeyround-trips without throwing.globalThis.fetchis never called (the test patches it with a throwing spy).- Two calls to
createPasskeywith the sameseedproduce the same contract id (determinism).
The full pnpm -F @stellar-passkey/core test run including the mock tests completes in ≤ 500ms on a modern laptop — well under the 2-second YK-269 ceiling.
When to reach for the live kit instead
Use the live kit (the package's default barrel exports) for:
- Integration tests that need a real
__check_authround-trip — see the YK-266 fixture-tx path inapps/demofor the canonical setup. - Anything that exercises
DeployerCallbacks(the real network surface lives on the consumer's side of that seam). - Browser-side smoke / Playwright tests with a CDP virtual authenticator —
apps/smokeandapps/demo's default tab show the pattern.