@soropass/core 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @soropass/core
2
+
3
+ [![npm](https://img.shields.io/npm/v/@soropass/core.svg)](https://www.npmjs.com/package/@soropass/core)
4
+ [![license](https://img.shields.io/npm/l/@soropass/core.svg)](./LICENSE)
5
+
6
+ Minimal, headless, ES256-only passkey SDK for Stellar smart accounts. It turns a WebAuthn passkey (Face ID, Touch ID, a security key) into the signer of a Soroban smart account, and handles the parts that are easy to get wrong: ES256 enforcement, DER-to-compact low-S conversion, the `__check_auth` authorization-entry wire shape, deterministic C-address derivation, and multi-device recovery.
7
+
8
+ It ships no UI and no framework opinions, and keeps `@stellar/stellar-sdk` as a peer dependency so it is never bundled twice. For drop-in create/sign/recover screens, see [`@soropass/ui`](https://www.npmjs.com/package/@soropass/ui). To register a passkey wallet in [Stellar Wallets Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit), see the [integration guide](https://docs.soropass.dev/docs/wallets-kit).
9
+
10
+ ## Why a passkey needs a smart account
11
+
12
+ A passkey signs with secp256r1 (ES256); a classic Stellar account (`G...`) only verifies Ed25519. So a passkey controls a Soroban **smart-account contract** (`C...`) whose `__check_auth` verifies the WebAuthn assertion on-chain via the host `secp256r1_verify`. This SDK owns that `C` side: create, sign, recover, add a signer.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install @soropass/core "@stellar/stellar-sdk@>=12 <17"
18
+ ```
19
+
20
+ `@stellar/stellar-sdk` is a required peer dependency. Pin it to `>=12 <17`: version 17 reworked the XDR API this release builds against. `@soropass/core` publishes ESM, CommonJS, and type declarations.
21
+
22
+ ## Quick start (no browser)
23
+
24
+ Reproduce a create + sign in Node or CI with the built-in mock authenticator, no WebAuthn hardware and no network. Save as `verify.mjs` and run `node verify.mjs`:
25
+
26
+ ```js
27
+ import { createPasskeyKit, sampleAuthEntry } from '@soropass/core/testing';
28
+ import { referenceCheckAuth } from '@soropass/core';
29
+ import { xdr } from '@stellar/stellar-sdk';
30
+
31
+ const NETWORK = 'Test SDF Network ; September 2015';
32
+
33
+ // Create a passkey and deploy its smart account (in-memory).
34
+ const kit = createPasskeyKit({ mode: 'mock', rpId: 'example.com', rpName: 'Example' });
35
+ const account = await kit.createPasskey({ userName: 'alice' });
36
+
37
+ // Sign a demo auth entry, then verify it the way the on-chain __check_auth does.
38
+ const signed = xdr.SorobanAuthorizationEntry.fromXDR(
39
+ await kit.signAuthEntry(sampleAuthEntry(account.contractId)),
40
+ 'base64',
41
+ );
42
+ console.log(referenceCheckAuth(signed, account.publicKey, NETWORK).success ? 'PASS' : 'FAIL');
43
+ ```
44
+
45
+ ## Create a real account in the browser
46
+
47
+ ```ts
48
+ import { createPasskey, factoryDeployer } from '@soropass/core';
49
+ import { Networks } from '@stellar/stellar-sdk';
50
+
51
+ const account = await createPasskey({
52
+ rpId: location.hostname,
53
+ rpName: 'My Stellar App',
54
+ userName: 'alice',
55
+ deployer: factoryDeployer({
56
+ rpcUrl: 'https://soroban-testnet.stellar.org',
57
+ networkPassphrase: Networks.TESTNET,
58
+ factoryContractId: 'C...', // your AccountFactory
59
+ sourceSecret, // a funded account that pays the one-time deploy fee
60
+ }),
61
+ });
62
+ // account.contractId · account.credentialId · account.publicKey
63
+ ```
64
+
65
+ Sign a transaction with `signTransaction` / `browserPasskeySigner`, resolve a returning user offline with `deriveAccountAddress`, and add a backup device with `registerPasskey` + `add_signer`. The full flows are in the [SDK reference](https://docs.soropass.dev/docs/sdk).
66
+
67
+ ## What you get
68
+
69
+ - **ES256-only.** Registration pins `pubKeyCredParams` to alg `-7`; anything else throws `KitError('ES256_NOT_SUPPORTED')`.
70
+ - **Always low-S.** Roughly half of Apple passkeys emit high-S signatures; the SDK normalizes every signature to canonical low-S so it verifies on-chain.
71
+ - **Tree-shakeable subpaths.** Import only what you use; the heavy crypto is pulled only by `/create` and `/sign`.
72
+ - **Pluggable adapters** for submission (direct, Launchtube, OpenZeppelin Relayer) and indexing (on-chain events, Mercury).
73
+ - **One typed error taxonomy.** Every throw is a `KitError` with a code from a frozen 10-code set.
74
+
75
+ | Subpath | Contents |
76
+ | --- | --- |
77
+ | `.` | Full public surface |
78
+ | `@soropass/core/create` | `createPasskey`, `registerPasskey`, `deriveAccountAddress`, public-key extraction |
79
+ | `@soropass/core/sign` | `signTransaction`, `signAuthEntry`, `browserPasskeySigner`, low-S helpers |
80
+ | `@soropass/core/connect` | `connect` |
81
+ | `@soropass/core/recover` | `recover`, `addSigner`, `removeSigner` |
82
+ | `@soropass/core/types` | `KitError`, `KIT_ERROR_CODES`, `isKitError` |
83
+ | `@soropass/core/testing` | `createPasskeyKit` mock mode, `sampleAuthEntry` (dev only) |
84
+
85
+ ## Documentation
86
+
87
+ - Full docs and API reference: [docs.soropass.dev](https://docs.soropass.dev)
88
+ - Quickstart (three integration paths): [docs.soropass.dev/docs/quickstart](https://docs.soropass.dev/docs/quickstart)
89
+ - Compatibility matrix (device / browser / hardware): [docs.soropass.dev/docs/compatibility](https://docs.soropass.dev/docs/compatibility)
90
+
91
+ ## License
92
+
93
+ Apache-2.0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/anchors.ts","../src/internal/encoding.ts","../src/webauthn/createOptions.ts","../src/internal/bytes.ts","../src/internal/cbor.ts","../src/webauthn/authData.ts","../src/webauthn/publicKey.ts","../src/ceremonies/random.ts","../src/ceremonies/browserClient.ts","../src/ceremonies/create.ts","../src/ceremonies/connect.ts","../src/ceremonies/recover.ts","../src/webauthn/signature.ts","../src/webauthn/clientData.ts","../src/webauthn/payload.ts","../src/webauthn/verify.ts","../src/soroban/preimage.ts","../src/soroban/assemble.ts","../src/soroban/smartWallet.ts","../src/soroban/sign.ts","../src/internal/cborEncode.ts","../src/testing/mockAuthenticator.ts","../src/testing/inMemory.ts","../src/testing/kit.ts","../src/testing/sampleAuthEntry.ts"],"names":["sha256","p256","xdr","hash","StrKey","Address"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * The frozen taxonomy of error codes the SDK can throw. This union is\n * deliberately closed — every failure path maps to exactly one of these.\n */\nexport const KIT_ERROR_CODES = Object.freeze([\n 'USER_CANCELLED',\n 'ES256_NOT_SUPPORTED',\n 'RP_ID_MISMATCH',\n 'ORIGIN_MISMATCH',\n 'CHALLENGE_MISMATCH',\n 'INVALID_SIGNATURE_DER',\n 'INVALID_PUBLIC_KEY',\n 'CONTRACT_AUTH_FAILED',\n 'NETWORK_ERROR',\n 'UNSUPPORTED_AUTHENTICATOR',\n] as const);\n\nexport type KitErrorCode = (typeof KIT_ERROR_CODES)[number];\n\n/** Structured error carrying a machine-readable {@link KitErrorCode}. */\nexport class KitError extends Error {\n readonly code: KitErrorCode;\n override readonly name = 'KitError';\n\n constructor(code: KitErrorCode, message?: string, options?: { cause?: unknown }) {\n super(message ?? code, options);\n this.code = code;\n // Restore the prototype chain so `instanceof KitError` works after\n // down-level transpilation to CJS.\n Object.setPrototypeOf(this, KitError.prototype);\n }\n}\n\nexport function isKitError(value: unknown): value is KitError {\n return value instanceof KitError;\n}\n","import { KitError } from './errors';\n\n/**\n * Stable identifiers for the three battle-tested anchors (S04 / YK-430) — the\n * bugs that silently break ~50% of users. Referenced by stable name from the\n * threat model (S14) and the compatibility matrix (S09) so each mitigation has\n * one canonical id across code and docs.\n */\nexport const BATTLE_TESTED_ANCHORS = Object.freeze({\n /** Apple Touch ID/Face ID emit high-S ~50% of the time; we normalize to low-S. */\n LOW_S_NORMALIZATION: 'low-s-normalization',\n /** Non-ES256 credentials (e.g. some Windows Hello configs) cannot verify on-chain. */\n RS256_HARD_FAIL: 'rs256-hard-fail',\n /** Safari requires create/get inside a user activation or it silently rejects. */\n APPLE_USER_GESTURE: 'apple-user-gesture',\n} as const);\n\nexport type BattleTestedAnchor = (typeof BATTLE_TESTED_ANCHORS)[keyof typeof BATTLE_TESTED_ANCHORS];\n\n/** COSE algorithm id for ES256 (ECDSA w/ SHA-256 over P-256). */\nconst ALG_ES256 = -7;\n\n/**\n * Anchor `RS256_HARD_FAIL`. The Soroban webauthn-wallet verifies *only*\n * secp256r1, so a non-ES256 credential would produce an unusable account.\n * Hard-fail rather than continue (invariant #1).\n */\nexport function assertES256(alg: number): void {\n if (alg !== ALG_ES256) {\n throw new KitError('ES256_NOT_SUPPORTED', `COSE alg ${alg} is not ES256 (-7)`);\n }\n}\n\ninterface UserActivationLike {\n isActive: boolean;\n}\n\n/**\n * Anchor `APPLE_USER_GESTURE`. `navigator.credentials.create/get` on\n * Safari/WebKit must run inside a transient user activation (a real click/tap)\n * or the promise silently rejects. Call this at the very top of a create/sign\n * handler.\n *\n * UI pattern (for S18): never auto-trigger the ceremony from a mount/effect —\n * always gate it behind an explicit user click, and surface `USER_CANCELLED`\n * in the flow state machine. Lenient when `navigator.userActivation` is\n * unavailable (non-browser / older engines) so the SDK stays isomorphic; pass\n * an explicit `{ isActive }` to force the check.\n */\nexport function assertUserActivation(activation?: UserActivationLike): void {\n const ua =\n activation ??\n (globalThis.navigator as { userActivation?: UserActivationLike } | undefined)?.userActivation;\n if (ua && !ua.isActive) {\n throw new KitError(\n 'USER_CANCELLED',\n 'WebAuthn ceremony must be invoked inside a user activation (click/tap)',\n );\n }\n}\n","/**\n * Isomorphic base64url + UTF-8 codecs. `atob`/`btoa`/`TextEncoder`/`TextDecoder`\n * are globals in modern browsers and Node >= 16, so no platform branch is\n * needed and nothing is bundled.\n */\n\n/** Encode bytes as unpadded base64url. */\nexport function bytesToBase64Url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/** Decode base64 or base64url (padding optional) to bytes. */\nexport function base64UrlToBytes(input: string): Uint8Array<ArrayBuffer> {\n const base64 = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(padded);\n const out = new Uint8Array(new ArrayBuffer(binary.length));\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nexport function utf8ToBytes(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n","import { bytesToBase64Url } from '../internal/encoding';\nimport { utf8ToBytes } from '../internal/encoding';\n\nexport type ResidentKeyRequirement = 'discouraged' | 'preferred' | 'required';\nexport type UserVerificationRequirement = 'discouraged' | 'preferred' | 'required';\n\nexport interface BuildCreateOptionsInput {\n rpId: string;\n rpName: string;\n userName: string;\n /** Stable, opaque user handle. Defaults to UTF-8 bytes of `userName`. */\n userId?: Uint8Array;\n userDisplayName?: string;\n /** Raw challenge bytes (base64url-encoded into the options). */\n challenge: Uint8Array;\n residentKey?: ResidentKeyRequirement;\n userVerification?: UserVerificationRequirement;\n timeout?: number;\n}\n\n/** ES256-only credential parameter. The `alg: -7` literal is non-negotiable. */\nexport interface PubKeyCredParam {\n type: 'public-key';\n alg: -7;\n}\n\nexport interface PublicKeyCredentialCreationOptionsJSON {\n rp: { id: string; name: string };\n user: { id: string; name: string; displayName: string };\n challenge: string;\n pubKeyCredParams: PubKeyCredParam[];\n authenticatorSelection: {\n residentKey: ResidentKeyRequirement;\n requireResidentKey: boolean;\n userVerification: UserVerificationRequirement;\n };\n attestation: 'none';\n timeout: number;\n}\n\n/**\n * Build WebAuthn registration options that offer ES256 *and only* ES256\n * (`pubKeyCredParams: [{ type: 'public-key', alg: -7 }]`) — invariant #1.\n * Soroban verifies only secp256r1, so we never advertise any other algorithm.\n */\nexport function buildCreateOptions(\n input: BuildCreateOptionsInput,\n): PublicKeyCredentialCreationOptionsJSON {\n const residentKey = input.residentKey ?? 'required';\n return {\n rp: { id: input.rpId, name: input.rpName },\n user: {\n id: bytesToBase64Url(input.userId ?? utf8ToBytes(input.userName)),\n name: input.userName,\n displayName: input.userDisplayName ?? input.userName,\n },\n challenge: bytesToBase64Url(input.challenge),\n pubKeyCredParams: [{ type: 'public-key', alg: -7 }],\n authenticatorSelection: {\n residentKey,\n requireResidentKey: residentKey === 'required',\n // The v0.2 account requires the User-Verified flag at sign time, so\n // register with 'required' to enroll authenticators that can produce it.\n userVerification: input.userVerification ?? 'required',\n },\n attestation: 'none',\n timeout: input.timeout ?? 60_000,\n };\n}\n","/** Concatenate byte arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((n, a) => n + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) {\n out.set(a, offset);\n offset += a.length;\n }\n return out;\n}\n\n/** Length-safe, constant-time-ish byte equality. */\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i += 1) diff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n return diff === 0;\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = '';\n for (const byte of bytes) hex += byte.toString(16).padStart(2, '0');\n return hex;\n}\n","/**\n * A minimal CBOR (RFC 8949) decoder — only the major types WebAuthn needs:\n * unsigned ints, negative ints, byte strings, text strings, arrays and maps,\n * with 1/2/4-byte length prefixes. Indefinite lengths, tags, floats and\n * 8-byte lengths are intentionally unsupported (COSE keys and attestation\n * objects never use them) and throw. This keeps the SDK dependency-free while\n * staying robust — it is fully fixture-tested. It replaces passkey-kit's\n * hardcoded byte-offset scanning, which had no bounds checks.\n */\nexport type CborValue = number | bigint | Uint8Array | string | CborValue[] | CborMap;\nexport type CborMap = Map<number | string, CborValue>;\n\ninterface Decoded {\n value: CborValue;\n /** Total bytes consumed starting at the requested offset. */\n length: number;\n}\n\nfunction byteAt(bytes: Uint8Array, index: number): number {\n const value = bytes[index];\n if (value === undefined) throw new Error(`CBOR: unexpected end of input at byte ${index}`);\n return value;\n}\n\n/** Decode the first CBOR item at `offset`, returning its value and byte length. */\nconst MAX_DEPTH = 16; // COSE keys / attestation objects nest at most ~3 levels.\n\nexport function decodeCbor(bytes: Uint8Array, offset = 0, depth = 0): Decoded {\n if (depth > MAX_DEPTH) throw new Error('CBOR: maximum nesting depth exceeded');\n const first = byteAt(bytes, offset);\n const major = first >> 5;\n const info = first & 0x1f;\n let pos = offset + 1;\n\n let argument: number;\n if (info < 24) {\n argument = info;\n } else if (info === 24) {\n argument = byteAt(bytes, pos);\n pos += 1;\n } else if (info === 25) {\n argument = (byteAt(bytes, pos) << 8) | byteAt(bytes, pos + 1);\n pos += 2;\n } else if (info === 26) {\n argument =\n byteAt(bytes, pos) * 0x1000000 +\n (byteAt(bytes, pos + 1) << 16) +\n (byteAt(bytes, pos + 2) << 8) +\n byteAt(bytes, pos + 3);\n pos += 4;\n } else {\n throw new Error(`CBOR: unsupported length encoding (additional info ${info})`);\n }\n\n switch (major) {\n case 0: // unsigned integer\n return { value: argument, length: pos - offset };\n case 1: // negative integer\n return { value: -1 - argument, length: pos - offset };\n case 2: {\n // byte string\n const end = pos + argument;\n if (end > bytes.length) throw new Error('CBOR: byte string exceeds input');\n return { value: bytes.slice(pos, end), length: end - offset };\n }\n case 3: {\n // text string (UTF-8)\n const end = pos + argument;\n if (end > bytes.length) throw new Error('CBOR: text string exceeds input');\n return { value: new TextDecoder().decode(bytes.slice(pos, end)), length: end - offset };\n }\n case 4: {\n // array\n const items: CborValue[] = [];\n let cursor = pos;\n for (let i = 0; i < argument; i += 1) {\n const item = decodeCbor(bytes, cursor, depth + 1);\n items.push(item.value);\n cursor += item.length;\n }\n return { value: items, length: cursor - offset };\n }\n case 5: {\n // map\n const map: CborMap = new Map();\n let cursor = pos;\n for (let i = 0; i < argument; i += 1) {\n const key = decodeCbor(bytes, cursor, depth + 1);\n cursor += key.length;\n const val = decodeCbor(bytes, cursor, depth + 1);\n cursor += val.length;\n if (typeof key.value !== 'number' && typeof key.value !== 'string') {\n throw new Error('CBOR: unsupported map key type');\n }\n if (map.has(key.value)) {\n throw new Error('CBOR: duplicate map key (non-canonical)');\n }\n map.set(key.value, val.value);\n }\n return { value: map, length: cursor - offset };\n }\n default:\n throw new Error(`CBOR: unsupported major type ${major}`);\n }\n}\n\nexport function decodeCborFirst(bytes: Uint8Array): CborValue {\n return decodeCbor(bytes, 0).value;\n}\n","import { KitError } from '../errors';\nimport { decodeCbor } from '../internal/cbor';\nimport { sha256 } from '../internal/sha256';\nimport { equalBytes } from '../internal/bytes';\nimport { utf8ToBytes } from '../internal/encoding';\n\nexport interface AuthenticatorDataFlags {\n /** User Present */\n up: boolean;\n /** User Verified */\n uv: boolean;\n /** Backup Eligible */\n be: boolean;\n /** Backup State */\n bs: boolean;\n /** Attested credential data present */\n at: boolean;\n /** Extension data present */\n ed: boolean;\n /** Raw flags byte. */\n bits: number;\n}\n\nexport interface ParsedAuthenticatorData {\n rpIdHash: Uint8Array;\n flags: AuthenticatorDataFlags;\n signCount: number;\n aaguid?: Uint8Array;\n credentialId?: Uint8Array;\n /** Raw CBOR-encoded COSE public key (exact bytes), if attested data present. */\n credentialPublicKey?: Uint8Array;\n}\n\nconst MIN_LENGTH = 37; // rpIdHash(32) + flags(1) + signCount(4)\n\n/** Parse the authenticatorData byte structure (WebAuthn §6.1). */\nexport function parseAuthenticatorData(authData: Uint8Array): ParsedAuthenticatorData {\n if (authData.length < MIN_LENGTH) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `authenticatorData is ${authData.length} bytes, expected at least ${MIN_LENGTH}`,\n );\n }\n const view = new DataView(authData.buffer, authData.byteOffset, authData.byteLength);\n const rpIdHash = authData.slice(0, 32);\n const bits = authData[32] ?? 0;\n const flags: AuthenticatorDataFlags = {\n up: (bits & 0x01) !== 0,\n uv: (bits & 0x04) !== 0,\n be: (bits & 0x08) !== 0,\n bs: (bits & 0x10) !== 0,\n at: (bits & 0x40) !== 0,\n ed: (bits & 0x80) !== 0,\n bits,\n };\n const signCount = view.getUint32(33, false);\n\n const result: ParsedAuthenticatorData = { rpIdHash, flags, signCount };\n\n if (flags.at) {\n if (authData.length < 55) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'authenticatorData truncated in attested data',\n );\n }\n result.aaguid = authData.slice(37, 53);\n const credIdLength = view.getUint16(53, false);\n const credIdEnd = 55 + credIdLength;\n if (authData.length < credIdEnd) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'authenticatorData truncated in credentialId',\n );\n }\n result.credentialId = authData.slice(55, credIdEnd);\n // The COSE public key is the next CBOR item; capture its exact bytes so we\n // stop cleanly before any extension data (when flags.ed is set).\n const rest = authData.slice(credIdEnd);\n const { length } = decodeCbor(rest, 0);\n result.credentialPublicKey = rest.slice(0, length);\n }\n\n return result;\n}\n\n/** Verify that authenticatorData's rpIdHash equals SHA-256(rpId). */\nexport function verifyRpIdHash(authData: Uint8Array, rpId: string): void {\n const actual = parseAuthenticatorData(authData).rpIdHash;\n const expected = sha256(utf8ToBytes(rpId));\n if (!equalBytes(actual, expected)) {\n throw new KitError(\n 'RP_ID_MISMATCH',\n `authenticatorData rpIdHash does not match SHA-256(\"${rpId}\")`,\n );\n }\n}\n","import { p256 } from '@noble/curves/nist';\nimport { KitError } from '../errors';\nimport { concatBytes } from '../internal/bytes';\nimport { decodeCborFirst, type CborMap } from '../internal/cbor';\nimport { parseAuthenticatorData } from './authData';\nimport { assertES256 } from '../anchors';\n\n// COSE key common parameters (RFC 9052) and EC2 key parameters.\nconst COSE_KTY = 1;\nconst COSE_ALG = 3;\nconst COSE_CRV = -1;\nconst COSE_X = -2;\nconst COSE_Y = -3;\n\nconst KTY_EC2 = 2;\nconst CRV_P256 = 1;\n\n/**\n * Convert a CBOR-encoded COSE EC2 public key to the 65-byte SEC-1 uncompressed\n * point `0x04 ‖ X ‖ Y`. Enforces ES256/P-256 — anything else (e.g. RS256)\n * throws `ES256_NOT_SUPPORTED` (invariant #1).\n */\nexport function coseKeyToSec1(coseKey: Uint8Array): Uint8Array {\n let decoded: ReturnType<typeof decodeCborFirst>;\n try {\n decoded = decodeCborFirst(coseKey);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'failed to CBOR-decode COSE key', { cause });\n }\n if (!(decoded instanceof Map)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key is not a CBOR map');\n }\n const map = decoded as CborMap;\n const alg = map.get(COSE_ALG);\n if (typeof alg !== 'number') {\n throw new KitError('ES256_NOT_SUPPORTED', `COSE alg ${String(alg)} is not ES256 (-7)`);\n }\n assertES256(alg); // anchor RS256_HARD_FAIL\n if (map.get(COSE_KTY) !== KTY_EC2) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n `COSE kty ${String(map.get(COSE_KTY))} is not EC2 (2)`,\n );\n }\n if (map.get(COSE_CRV) !== CRV_P256) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n `COSE crv ${String(map.get(COSE_CRV))} is not P-256 (1)`,\n );\n }\n const x = map.get(COSE_X);\n const y = map.get(COSE_Y);\n if (!(x instanceof Uint8Array) || x.length !== 32) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key X coordinate is not 32 bytes');\n }\n if (!(y instanceof Uint8Array) || y.length !== 32) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key Y coordinate is not 32 bytes');\n }\n const sec1 = concatBytes(new Uint8Array([0x04]), x, y);\n // Reject off-curve / invalid points so an invalid key can never be persisted.\n try {\n p256.Point.fromHex(sec1);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'public key is not a valid P-256 point', { cause });\n }\n return sec1;\n}\n\n/** Extract the SEC-1 public key from raw authenticatorData (attested data). */\nexport function extractPublicKeyFromAuthData(authData: Uint8Array): Uint8Array {\n const parsed = parseAuthenticatorData(authData);\n if (!parsed.credentialPublicKey) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n 'authenticatorData has no attested credential public key',\n );\n }\n return coseKeyToSec1(parsed.credentialPublicKey);\n}\n\n/** Extract the SEC-1 public key from a CBOR attestationObject (create ceremony). */\nexport function extractPublicKeyFromAttestationObject(attestationObject: Uint8Array): Uint8Array {\n let decoded: ReturnType<typeof decodeCborFirst>;\n try {\n decoded = decodeCborFirst(attestationObject);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'failed to CBOR-decode attestationObject', { cause });\n }\n if (!(decoded instanceof Map)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'attestationObject is not a CBOR map');\n }\n const authData = (decoded as CborMap).get('authData');\n if (!(authData instanceof Uint8Array)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'attestationObject has no authData byte string');\n }\n return extractPublicKeyFromAuthData(authData);\n}\n","import { KitError } from '../errors';\n\n/**\n * Cryptographically-random bytes, isomorphic (browser + Node global crypto).\n * Throws instead of silently returning all-zero bytes when no secure RNG is\n * present — an all-zero challenge would be catastrophic, not a soft fallback.\n */\nexport function randomBytes(length: number): Uint8Array<ArrayBuffer> {\n const webcrypto = globalThis.crypto as Crypto | undefined;\n if (typeof webcrypto?.getRandomValues !== 'function') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'no secure random source (globalThis.crypto.getRandomValues) is available in this environment',\n );\n }\n const out = new Uint8Array(new ArrayBuffer(length));\n webcrypto.getRandomValues(out);\n return out;\n}\n","import { KitError } from '../errors';\nimport { base64UrlToBytes } from '../internal/encoding';\nimport type { PublicKeyCredentialCreationOptionsJSON } from '../webauthn/createOptions';\nimport { randomBytes } from './random';\nimport type {\n CredentialStorage,\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from './types';\n\n/**\n * Map a `navigator.credentials` rejection to a `KitError`. Dismissing the OS\n * passkey sheet rejects with a `NotAllowedError` (a DOMException) — surface that\n * as `USER_CANCELLED` so the UI shows the true \"you cancelled\" copy instead of\n * the generic unsupported-authenticator fallback (S20 / S04 polish).\n */\nfunction asKitError(error: unknown): KitError {\n if (error instanceof KitError) return error;\n const name =\n typeof error === 'object' && error !== null && 'name' in error\n ? (error as { name?: unknown }).name\n : undefined;\n if (name === 'NotAllowedError') {\n return new KitError('USER_CANCELLED', 'The passkey prompt was dismissed.', { cause: error });\n }\n const message = error instanceof Error ? error.message : 'WebAuthn request failed';\n // Preserve the original DOMException name (e.g. InvalidStateError / ConstraintError)\n // in the message so diagnostics show the true cause, not just the generic bucket.\n const detail = typeof name === 'string' ? `${name}: ${message}` : message;\n return new KitError('UNSUPPORTED_AUTHENTICATOR', detail, { cause: error });\n}\n\n/** The browser `WebAuthnClient` backed by `navigator.credentials`. */\nexport function browserWebAuthnClient(): WebAuthnClient {\n const credentials = (globalThis as { navigator?: Navigator }).navigator?.credentials;\n if (!credentials) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'navigator.credentials is unavailable');\n }\n return {\n async create(options: PublicKeyCredentialCreationOptionsJSON): Promise<WebAuthnCreateResult> {\n const publicKey: PublicKeyCredentialCreationOptions = {\n challenge: base64UrlToBytes(options.challenge),\n rp: options.rp,\n user: {\n id: base64UrlToBytes(options.user.id),\n name: options.user.name,\n displayName: options.user.displayName,\n },\n pubKeyCredParams: options.pubKeyCredParams,\n authenticatorSelection: options.authenticatorSelection,\n attestation: options.attestation,\n timeout: options.timeout,\n };\n let credential: PublicKeyCredential | null;\n try {\n credential = (await credentials.create({ publicKey })) as PublicKeyCredential | null;\n } catch (error) {\n throw asKitError(error);\n }\n if (!credential) throw new KitError('USER_CANCELLED', 'credential creation returned null');\n const response = credential.response as AuthenticatorAttestationResponse;\n return {\n id: credential.id,\n rawId: new Uint8Array(credential.rawId),\n attestationObject: new Uint8Array(response.attestationObject),\n };\n },\n async get(options: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const publicKey: PublicKeyCredentialRequestOptions = {\n rpId: options.rpId,\n challenge: options.challenge ? new Uint8Array(options.challenge) : randomBytes(32),\n allowCredentials: (options.allowCredentials ?? []).map((id) => ({\n type: 'public-key',\n id: base64UrlToBytes(id),\n })),\n userVerification: options.userVerification,\n };\n const request: CredentialRequestOptions = { publicKey };\n if (options.mediation) request.mediation = options.mediation;\n let credential: PublicKeyCredential | null;\n try {\n credential = (await credentials.get(request)) as PublicKeyCredential | null;\n } catch (error) {\n throw asKitError(error);\n }\n if (!credential) throw new KitError('USER_CANCELLED', 'assertion returned null');\n const response = credential.response as AuthenticatorAssertionResponse;\n return {\n id: credential.id,\n rawId: new Uint8Array(credential.rawId),\n authenticatorData: new Uint8Array(response.authenticatorData),\n clientDataJSON: new Uint8Array(response.clientDataJSON),\n signature: new Uint8Array(response.signature),\n };\n },\n };\n}\n\n/** localStorage-backed credential store, with an in-memory fallback (Node/SSR). */\nexport function defaultCredentialStorage(): CredentialStorage {\n const key = (rpId: string): string => `stellar-passkey:${rpId}`;\n const ls = (globalThis as { localStorage?: Storage }).localStorage;\n if (ls) {\n return {\n get: (rpId) => ls.getItem(key(rpId)),\n set: (rpId, credentialId) => {\n ls.setItem(key(rpId), credentialId);\n },\n };\n }\n const memory = new Map<string, string>();\n return {\n get: (rpId) => memory.get(rpId) ?? null,\n set: (rpId, credentialId) => {\n memory.set(rpId, credentialId);\n },\n };\n}\n","import { assertUserActivation } from '../anchors';\nimport { buildCreateOptions } from '../webauthn/createOptions';\nimport { extractPublicKeyFromAttestationObject } from '../webauthn/publicKey';\nimport type { PasskeyCredential } from '../types';\nimport { browserWebAuthnClient, defaultCredentialStorage } from './browserClient';\nimport { randomBytes } from './random';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from './types';\n\nexport interface CreatePasskeyOptions {\n rpId: string;\n rpName: string;\n userName: string;\n /** Deploys the smart account for the new passkey (contract-specific; see AccountDeployer). */\n deployer: AccountDeployer;\n webauthn?: WebAuthnClient;\n storage?: CredentialStorage;\n userId?: Uint8Array;\n challenge?: Uint8Array;\n residentKey?: 'discouraged' | 'preferred' | 'required';\n userVerification?: 'discouraged' | 'preferred' | 'required';\n /** Pass navigator.userActivation to enforce the Safari gesture requirement (S04). */\n userActivation?: { isActive: boolean };\n}\n\n/** Options for {@link registerPasskey} — a create WITHOUT deploy (see below). */\nexport type RegisterPasskeyOptions = Omit<CreatePasskeyOptions, 'deployer' | 'storage'>;\n\n/** A freshly-registered passkey credential (no account deployed yet). */\nexport interface RegisteredPasskey {\n /** base64url credential id returned by the authenticator. */\n credentialId: string;\n /** SEC-1 uncompressed public key (65 bytes). */\n publicKey: Uint8Array;\n}\n\n/**\n * `registerPasskey` — register an ES256-only passkey and extract its SEC-1 public\n * key (RS256 hard-fails), but do NOT deploy an account or persist anything. This\n * is the \"new device\" primitive for multi-device recovery: a fresh device\n * produces a `{credentialId, publicKey}` signer spec that an existing device then\n * authorizes on-chain via `addSigner`. (`createPasskey` is this plus a deploy.)\n */\nexport async function registerPasskey(options: RegisterPasskeyOptions): Promise<RegisteredPasskey> {\n assertUserActivation(options.userActivation); // anchor: apple-user-gesture (S04)\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n\n const creationOptions = buildCreateOptions({\n rpId: options.rpId,\n rpName: options.rpName,\n userName: options.userName,\n userId: options.userId,\n challenge: options.challenge ?? randomBytes(32),\n residentKey: options.residentKey,\n userVerification: options.userVerification,\n });\n\n const credential = await webauthn.create(creationOptions);\n // ES256-only enforcement happens here: a non-ES256 credential throws ES256_NOT_SUPPORTED.\n const publicKey = extractPublicKeyFromAttestationObject(credential.attestationObject);\n return { credentialId: credential.id, publicKey };\n}\n\n/**\n * `createPasskey` — register an ES256-only passkey (see {@link registerPasskey}),\n * deploy a smart account for it via the factory, persist the credential id, and\n * return the account.\n */\nexport async function createPasskey(options: CreatePasskeyOptions): Promise<PasskeyCredential> {\n const storage = options.storage ?? defaultCredentialStorage();\n const { credentialId, publicKey } = await registerPasskey(options);\n const { contractId } = await options.deployer.deploy({ publicKey, credentialId });\n storage.set(options.rpId, credentialId);\n return { contractId, credentialId, publicKey };\n}\n","import type { IndexerAdapter } from '../adapters/types';\nimport { browserWebAuthnClient, defaultCredentialStorage } from './browserClient';\nimport type { CredentialStorage, WebAuthnClient } from './types';\n\nexport interface ConnectOptions {\n rpId: string;\n indexer: IndexerAdapter;\n webauthn?: WebAuthnClient;\n storage?: CredentialStorage;\n /** Override silent-mediation detection (default: probe isConditionalMediationAvailable). */\n silentMediationSupported?: boolean;\n /**\n * SEC-1 (65-byte) public key of this passkey. When set, `connect` returns the\n * account whose factory `deployed` event names this exact key, ignoring any\n * other candidate for the same credential id. Because `deploy` is\n * permissionless, a credential id can resolve to more than one account; pass\n * the founding key (persisted at create time) so a poisoned candidate is never\n * selected. When omitted, `connect` returns the first resolved account and you\n * MUST verify enrollment yourself before trusting it with funds.\n */\n publicKey?: Uint8Array;\n}\n\nexport interface ConnectResult {\n contractId: string;\n credentialId: string;\n}\n\nasync function probeConditionalMediation(): Promise<boolean> {\n const pkc = (\n globalThis as {\n PublicKeyCredential?: { isConditionalMediationAvailable?: () => Promise<boolean> };\n }\n ).PublicKeyCredential;\n if (!pkc?.isConditionalMediationAvailable) return false;\n try {\n return await pkc.isConditionalMediationAvailable();\n } catch {\n return false;\n }\n}\n\n/**\n * `connect` — silent reconnect using the stored credential id. Where conditional\n * mediation is available, does a best-effort `mediation:'silent'` liveness check;\n * the C-address is resolved via the IndexerAdapter regardless, so connect\n * degrades gracefully where silent mediation is unsupported. Returns null when\n * there is no stored credential (the caller should `recover`) or no account.\n */\nexport async function connect(options: ConnectOptions): Promise<ConnectResult | null> {\n const storage = options.storage ?? defaultCredentialStorage();\n const credentialId = storage.get(options.rpId);\n if (!credentialId) return null;\n\n const silentSupported = options.silentMediationSupported ?? (await probeConditionalMediation());\n if (silentSupported) {\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n try {\n await webauthn.get({\n rpId: options.rpId,\n allowCredentials: [credentialId],\n mediation: 'silent',\n });\n } catch {\n // A silent get may no-op or reject; resolution is via the indexer.\n }\n }\n\n const accounts = await options.indexer.resolveByCredential(credentialId);\n const selected = selectAccount(accounts, options.publicKey);\n return selected ? { contractId: selected.contractId, credentialId } : null;\n}\n\n/** True if two byte arrays are equal. */\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/**\n * Pick the resolved account. With an expected public key, return only the\n * candidate whose factory-reported founding key matches it (poison-resistant);\n * without one, fall back to the first candidate (see the `publicKey` doc on\n * ConnectOptions for why that is a trust decision the caller must back up).\n */\nfunction selectAccount(\n accounts: { contractId: string; publicKey?: Uint8Array }[],\n publicKey?: Uint8Array,\n): { contractId: string } | null {\n if (publicKey) {\n const match = accounts.find((a) => a.publicKey && bytesEqual(a.publicKey, publicKey));\n return match ? { contractId: match.contractId } : null;\n }\n return accounts[0] ?? null;\n}\n","import { assertUserActivation } from '../anchors';\nimport type { IndexerAdapter } from '../adapters/types';\nimport { browserWebAuthnClient } from './browserClient';\nimport { randomBytes } from './random';\nimport type { WebAuthnClient } from './types';\n\nexport interface RecoverOptions {\n rpId: string;\n indexer: IndexerAdapter;\n webauthn?: WebAuthnClient;\n challenge?: Uint8Array;\n userActivation?: { isActive: boolean };\n}\n\nexport interface RecoverResult {\n contractId: string;\n credentialId: string;\n}\n\n/**\n * `recover` — the lost-localStorage / new-device path. Performs a\n * discoverable-credential `get()` (no allowCredentials), then resolves every\n * smart account controlled by that credential via the IndexerAdapter.\n */\nexport async function recover(options: RecoverOptions): Promise<RecoverResult[]> {\n assertUserActivation(options.userActivation); // anchor: apple-user-gesture (S04)\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n const assertion = await webauthn.get({\n rpId: options.rpId,\n allowCredentials: [],\n challenge: options.challenge ?? randomBytes(32),\n });\n const accounts = await options.indexer.resolveByCredential(assertion.id);\n return accounts.map((account) => ({\n contractId: account.contractId,\n credentialId: assertion.id,\n }));\n}\n","import { p256 } from '@noble/curves/nist';\nimport { KitError } from '../errors';\n\n/** Maximum DER length of a P-256 ECDSA signature: SEQ + two 33-byte INTEGERs. */\nconst MAX_DER_LENGTH = 72;\n\n/**\n * Convert an ASN.1 DER ECDSA signature to the 64-byte raw `R‖S` form Soroban's\n * `secp256r1_verify` expects, using noble's audited DER parser (R and S are\n * left-padded to 32 bytes big-endian). Rejects malformed or over-long input.\n *\n * Note: this does NOT enforce low-S — that normalization is added in S04\n * (YK-430). The output here mirrors the signature exactly as parsed.\n */\nexport function derToCompact(der: Uint8Array): Uint8Array {\n if (der.length > MAX_DER_LENGTH) {\n throw new KitError(\n 'INVALID_SIGNATURE_DER',\n `DER signature is ${der.length} bytes, exceeds max ${MAX_DER_LENGTH}`,\n );\n }\n try {\n return p256.Signature.fromDER(der).toCompactRawBytes();\n } catch (cause) {\n throw new KitError('INVALID_SIGNATURE_DER', 'failed to parse DER signature', { cause });\n }\n}\n\nfunction assertCompactLength(compactSignature: Uint8Array): void {\n if (compactSignature.length !== 64) {\n throw new KitError(\n 'INVALID_SIGNATURE_DER',\n `compact signature must be 64 bytes, got ${compactSignature.length}`,\n );\n }\n}\n\n/** True if a 64-byte compact signature is in canonical low-S form (S ≤ n/2). */\nexport function isLowS(compactSignature: Uint8Array): boolean {\n assertCompactLength(compactSignature);\n return !p256.Signature.fromCompact(compactSignature).hasHighS();\n}\n\n/**\n * Normalize a 64-byte compact signature to canonical low-S: if S > n/2, replace\n * S with n − S (anchor LOW_S_NORMALIZATION, invariant #2). ~50% of Apple Touch\n * ID / Face ID assertions are high-S, and Soroban's `secp256r1_verify` REJECTS a\n * high-S signature at decode, so the SDK MUST emit low-S or roughly half of real\n * assertions would fail on-chain. Low-S is a validity requirement here, not just\n * malleability hygiene. Idempotent: low-S input is returned unchanged.\n */\nexport function normalizeLowS(compactSignature: Uint8Array): Uint8Array {\n assertCompactLength(compactSignature);\n return p256.Signature.fromCompact(compactSignature).normalizeS().toCompactRawBytes();\n}\n\n/** DER → 64-byte canonical low-S compact — the conversion the signing ceremony uses. */\nexport function derToCompactLowS(der: Uint8Array): Uint8Array {\n return normalizeLowS(derToCompact(der));\n}\n","import { KitError } from '../errors';\nimport { base64UrlToBytes, bytesToBase64Url, bytesToUtf8 } from '../internal/encoding';\n\n/** The subset of clientDataJSON fields we rely on. */\nexport interface ClientData {\n type: string;\n /** base64url-encoded challenge as embedded by the client. */\n challenge: string;\n origin: string;\n crossOrigin?: boolean;\n}\n\n/** Encode a raw challenge as the base64url string embedded in clientDataJSON. */\nexport function encodeChallenge(challenge: Uint8Array): string {\n return bytesToBase64Url(challenge);\n}\n\n/** Decode the base64url challenge embedded in clientDataJSON back to bytes. */\nexport function decodeChallenge(challenge: string): Uint8Array {\n return base64UrlToBytes(challenge);\n}\n\n/** Parse clientDataJSON bytes into a typed, validated-shape object. */\nexport function parseClientDataJSON(clientDataJSON: Uint8Array): ClientData {\n let raw: unknown;\n try {\n raw = JSON.parse(bytesToUtf8(clientDataJSON));\n } catch (cause) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is not valid JSON', { cause });\n }\n if (typeof raw !== 'object' || raw === null) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is not a JSON object');\n }\n const obj = raw as Record<string, unknown>;\n const { type, challenge, origin, crossOrigin } = obj;\n if (typeof type !== 'string' || typeof challenge !== 'string' || typeof origin !== 'string') {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is missing required fields');\n }\n return {\n type,\n challenge,\n origin,\n crossOrigin: typeof crossOrigin === 'boolean' ? crossOrigin : undefined,\n };\n}\n\n/**\n * Parse and verify clientDataJSON for an authentication (`webauthn.get`)\n * assertion: the ceremony type, the origin (exact match against one or more\n * allowed origins), and the embedded challenge (base64url string).\n */\nexport function verifyClientDataJSON(\n clientDataJSON: Uint8Array,\n expected: { origin: string | string[]; challenge: string },\n): ClientData {\n const data = parseClientDataJSON(clientDataJSON);\n if (data.type !== 'webauthn.get') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `clientDataJSON.type \"${data.type}\" is not \"webauthn.get\"`,\n );\n }\n const allowed = Array.isArray(expected.origin) ? expected.origin : [expected.origin];\n if (!allowed.includes(data.origin)) {\n throw new KitError('ORIGIN_MISMATCH', `origin \"${data.origin}\" not in [${allowed.join(', ')}]`);\n }\n if (data.challenge !== expected.challenge) {\n throw new KitError('CHALLENGE_MISMATCH', 'clientDataJSON challenge does not match expected');\n }\n return data;\n}\n","import { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\n\n/**\n * Reconstruct the 32-byte payload the authenticator signed and that Soroban's\n * `__check_auth` re-derives on-chain:\n *\n * SHA256( authenticatorData ‖ SHA256(clientDataJSON) )\n */\nexport function reconstructSignedPayload(input: {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n}): Uint8Array {\n const clientDataHash = sha256(input.clientDataJSON);\n return sha256(concatBytes(input.authenticatorData, clientDataHash));\n}\n","import { p256 } from '@noble/curves/nist';\nimport { reconstructSignedPayload } from './payload';\nimport { derToCompact } from './signature';\n\nexport interface VerifyAssertionInput {\n /** SEC-1 uncompressed public key (65 bytes, `0x04 ‖ X ‖ Y`). */\n publicKey: Uint8Array;\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n /** DER-encoded (≤72 B) or already-compact (64 B) signature. */\n signature: Uint8Array;\n}\n\n/**\n * Verify a WebAuthn assertion the way the on-chain `secp256r1_verify` does:\n * reconstruct `SHA256(authData ‖ SHA256(cdj))` and check ECDSA. `lowS: false`\n * mirrors the host function, which does NOT enforce low-S (we normalize\n * separately before submitting — see S04/YK-430).\n */\nexport function verifyAssertionSignature(input: VerifyAssertionInput): boolean {\n const payload = reconstructSignedPayload(input);\n const compact = input.signature.length === 64 ? input.signature : derToCompact(input.signature);\n // `format: 'compact'` pins the 64-byte interpretation — without it noble tries\n // DER-first and could misread a compact signature that happens to start 0x30.\n return p256.verify(compact, payload, input.publicKey, { lowS: false, format: 'compact' });\n}\n","import { xdr, hash } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\n\n/**\n * Compute the auth-entry preimage hash that `__check_auth` reconstructs and that\n * becomes the WebAuthn `challenge`:\n * SHA256( XDR( HashIdPreimage::SorobanAuthorization{ networkId, nonce,\n * signatureExpirationLedger, invocation } ) )\n * where networkId = SHA256(networkPassphrase).\n */\nexport function authEntryChallengeBytes(\n entry: xdr.SorobanAuthorizationEntry,\n networkPassphrase: string,\n): Uint8Array {\n const credentials = entry.credentials();\n if (credentials.switch().name !== 'sorobanCredentialsAddress') {\n throw new KitError('CONTRACT_AUTH_FAILED', 'auth entry has no address credentials to sign');\n }\n const address = credentials.address();\n const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(\n new xdr.HashIdPreimageSorobanAuthorization({\n networkId: Buffer.from(hash(Buffer.from(utf8ToBytes(networkPassphrase)))),\n nonce: address.nonce(),\n signatureExpirationLedger: address.signatureExpirationLedger(),\n invocation: entry.rootInvocation(),\n }),\n );\n return new Uint8Array(hash(preimage.toXDR()));\n}\n\n/** The base64url challenge string the authenticator signs (43 chars). */\nexport function authEntryChallenge(\n entry: xdr.SorobanAuthorizationEntry,\n networkPassphrase: string,\n): string {\n return bytesToBase64Url(authEntryChallengeBytes(entry, networkPassphrase));\n}\n","import { xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport type { AssertionResult } from './sign';\n\n/**\n * Set an address-credential auth entry's signature to the `Secp256r1Signature`\n * struct our v0.2 `webauthn-account` `__check_auth` consumes:\n *\n * ScVal::Map {\n * authenticator_data: Bytes,\n * client_data_json: Bytes,\n * public_key: BytesN<65>, // the enrolled signer to verify against\n * signature: BytesN<64>,\n * }\n *\n * Map keys are alphabetical, so the ScMap is canonically sorted as Soroban\n * requires. `signature` MUST already be 64-byte low-S compact (`signAuthEntry`\n * normalizes before calling this). `publicKey` names which enrolled signer the\n * contract checks; the multi-signer account rejects a key it does not hold\n * before any crypto runs.\n */\nexport function applyAssertionToEntry(\n entry: xdr.SorobanAuthorizationEntry,\n assertion: AssertionResult,\n publicKey: Uint8Array,\n): xdr.SorobanAuthorizationEntry {\n entry.credentials().address().signature(buildSingleSignerSignatureScVal(assertion, publicKey));\n return entry;\n}\n\n/** The v0.2 single-signer `Secp256r1Signature` ScVal (4 fields, sorted ScMap). */\nexport function buildSingleSignerSignatureScVal(\n assertion: AssertionResult,\n publicKey: Uint8Array,\n): xdr.ScVal {\n if (publicKey.length !== 65) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n `single-signer signature needs a 65-byte SEC-1 public key (got ${String(publicKey.length)})`,\n );\n }\n return xdr.ScVal.scvMap([\n bytesField('authenticator_data', assertion.authenticatorData),\n bytesField('client_data_json', assertion.clientDataJSON),\n bytesField('public_key', publicKey),\n bytesField('signature', assertion.signature),\n ]);\n}\n\n/**\n * The 3-field `Secp256r1Signature` ScVal that passkey-kit v1's smart-wallet\n * consumes ({ authenticator_data, client_data_json, signature }): that contract\n * resolves the public key from its own `SignerKey -> public key` storage, so the\n * key is NOT inlined here. Kept separate from the single-signer struct above so\n * the two ABIs never drift into each other.\n */\nexport function buildSignatureScVal(assertion: AssertionResult): xdr.ScVal {\n return xdr.ScVal.scvMap([\n bytesField('authenticator_data', assertion.authenticatorData),\n bytesField('client_data_json', assertion.clientDataJSON),\n bytesField('signature', assertion.signature),\n ]);\n}\n\nfunction bytesField(name: string, bytes: Uint8Array): xdr.ScMapEntry {\n return new xdr.ScMapEntry({\n key: xdr.ScVal.scvSymbol(name),\n val: xdr.ScVal.scvBytes(Buffer.from(bytes)),\n });\n}\n","import { xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { buildSignatureScVal } from './assemble';\nimport type { AssertionResult } from './sign';\n\n/**\n * The passkey-kit / `webauthn-wallet` smart-wallet ABI target.\n *\n * Our own single-signer account declares `type Signature = Secp256r1Signature`\n * and consumes the bare struct (see `assemble.ts`). passkey-kit's smart-wallet\n * declares `type Signature = Signatures`, so authorizing it needs the assertion\n * wrapped as `Signatures(Map<SignerKey, Signature>)`. The exact shape, the raw-\n * credential-id key, and the canonical map ordering below are confirmed by\n * kalepail (passkey-kit author) in issue #32 against v1 / v0.13.0 (Protocol 27,\n * independently audited); the wire shape is unchanged from v0.12.\n */\n\n/**\n * `SignerKey::Secp256r1(Bytes)` → `scvVec([Symbol(\"Secp256r1\"), Bytes(rawId)])`.\n * The key is the RAW WebAuthn credential-id bytes (base64url-decoded `rawId`):\n * never hashed, never the UTF-8 of the base64url string, and never the public\n * key — the SEC-1 public key lives in `SignerVal` on-chain, not in the key.\n */\nexport function buildSignerKeyScVal(credentialId: Uint8Array): xdr.ScVal {\n return xdr.ScVal.scvVec([\n xdr.ScVal.scvSymbol('Secp256r1'),\n xdr.ScVal.scvBytes(Buffer.from(credentialId)),\n ]);\n}\n\n/** `Signature::Secp256r1(Secp256r1Signature)` → `scvVec([Symbol(\"Secp256r1\"), <bare struct map>])`. */\nexport function buildSmartWalletSignatureVariant(assertion: AssertionResult): xdr.ScVal {\n return xdr.ScVal.scvVec([xdr.ScVal.scvSymbol('Secp256r1'), buildSignatureScVal(assertion)]);\n}\n\nfunction decomposeSignerKey(key: xdr.ScVal): { variant: string; payload: Uint8Array } {\n const vec = key.vec();\n if (!vec || vec.length < 2) {\n throw new KitError('CONTRACT_AUTH_FAILED', 'malformed SignerKey (expected an enum vec)');\n }\n const variant = vec[0]!.sym().toString();\n const el = vec[1]!;\n // Secp256r1(Bytes) and Ed25519(BytesN<32>) are scvBytes; Policy(Address) falls\n // back to its XDR bytes (rare in a passkey SDK — see the ordering note below).\n const payload =\n el.switch().name === 'scvBytes' ? new Uint8Array(el.bytes()) : new Uint8Array(el.toXDR());\n return { variant, payload };\n}\n\nfunction compareBytes(a: Uint8Array, b: Uint8Array): number {\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n if (a[i] !== b[i]) return a[i]! < b[i]! ? -1 : 1;\n }\n return a.length - b.length;\n}\n\n/**\n * Canonical Soroban-host ordering for `SignerKey` map keys. The host requires\n * `Map<SignerKey, _>` entries sorted by ScVal `Ord` — an **element-wise byte\n * comparison**, NOT a length-major XDR-hex / `localeCompare` string sort. This is\n * the one correctness landmine kalepail flagged in #32: passkey-kit v1 replaced\n * its old string sort with exactly this because the old approach could mis-order\n * same-variant keys of differing length, producing a map the host rejects.\n *\n * We compare the enum variant symbol first, then the payload bytes element-wise,\n * so homogeneous `Secp256r1` keys (the multi-passkey case) sort purely by their\n * raw credential-id bytes. (Ordering across mixed variant types relies on the\n * variant names being capitalized single words, which matches the host's symbol\n * order; a Policy/Address-keyed multi-sig is out of scope for this passkey SDK.)\n */\nexport function compareSignerKeyScVal(a: xdr.ScVal, b: xdr.ScVal): number {\n const ka = decomposeSignerKey(a);\n const kb = decomposeSignerKey(b);\n if (ka.variant !== kb.variant) return ka.variant < kb.variant ? -1 : 1;\n return compareBytes(ka.payload, kb.payload);\n}\n\n/**\n * Assemble/merge a passkey assertion into an address-credential auth entry as the\n * smart-wallet `Signatures(Map<SignerKey, Signature>)` wire shape\n * (`ScVal::Vec([ScVal::Map(...)])`). `assertion.signature` MUST already be 64-byte\n * low-S compact (`signAuthEntry` normalizes first). Existing map entries — a\n * partially-signed multi-sig entry — are preserved; an entry for the same signer\n * key is replaced; then the whole map is canonically sorted.\n *\n * Use this for the passkey-kit / webauthn-wallet ABI. For our own single-signer\n * account (`type Signature = Secp256r1Signature`) use `applyAssertionToEntry`.\n */\nexport function applyAssertionToSmartWalletEntry(\n entry: xdr.SorobanAuthorizationEntry,\n assertion: AssertionResult,\n): xdr.SorobanAuthorizationEntry {\n const credentials = entry.credentials();\n if (credentials.switch().name !== 'sorobanCredentialsAddress') {\n throw new KitError('CONTRACT_AUTH_FAILED', 'auth entry has no address credentials to sign');\n }\n const key = buildSignerKeyScVal(assertion.credentialId);\n const newEntry = new xdr.ScMapEntry({ key, val: buildSmartWalletSignatureVariant(assertion) });\n\n const current = credentials.address().signature();\n let mapEntries: xdr.ScMapEntry[];\n switch (current.switch().name) {\n case 'scvVoid':\n mapEntries = [newEntry];\n break;\n case 'scvVec': {\n // Preserve any existing signatures (partial multi-sig); replace same key.\n const existing = current.vec()?.[0]?.map() ?? [];\n mapEntries = existing.filter((e) => compareSignerKeyScVal(e.key(), key) !== 0);\n mapEntries.push(newEntry);\n break;\n }\n default:\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'unexpected existing signature shape for a smart-wallet entry',\n );\n }\n mapEntries.sort((a, b) => compareSignerKeyScVal(a.key(), b.key()));\n credentials.address().signature(xdr.ScVal.scvVec([xdr.ScVal.scvMap(mapEntries)]));\n return entry;\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { derToCompactLowS, normalizeLowS } from '../webauthn/signature';\nimport { parseClientDataJSON, verifyClientDataJSON, type ClientData } from '../webauthn/clientData';\nimport { parseAuthenticatorData, verifyRpIdHash } from '../webauthn/authData';\nimport { verifyAssertionSignature } from '../webauthn/verify';\nimport { authEntryChallenge } from './preimage';\nimport { applyAssertionToEntry } from './assemble';\nimport { applyAssertionToSmartWalletEntry } from './smartWallet';\n\n/**\n * Which contract ABI the assembled signature targets:\n * - `single-signer` (default): the bare `Secp256r1Signature` struct our own\n * webauthn-account consumes (`type Signature = Secp256r1Signature`).\n * - `smart-wallet`: passkey-kit's `Signatures(Map<SignerKey, Signature>)`\n * (`type Signature = Signatures`) — see `smartWallet.ts` / kalepail #32.\n * Both reuse the identical low-S, field-packing, and challenge-binding core;\n * only the outer wrapper differs, so the two stay separate ABI targets behind\n * one signing interface.\n */\nexport type WalletTarget = 'single-signer' | 'smart-wallet';\n\n/** The raw WebAuthn assertion a signer returns for a given challenge. */\nexport interface AssertionResult {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n /** DER-encoded (≤72B) or already-compact (64B) ECDSA signature. */\n signature: Uint8Array;\n /** base64url credential id → the SignerKey. */\n credentialId: Uint8Array;\n /**\n * SEC-1 (65-byte) public key of the signing passkey. The v0.2 single-signer\n * account verifies against this exact key, so the signer must supply it here\n * (or the caller passes it via `SorobanSignOptions.publicKey`). Not used by\n * the smart-wallet target, which resolves the key on-chain by credential id.\n */\n publicKey?: Uint8Array;\n}\n\n/** Produce a WebAuthn assertion over the base64url `challenge` (e.g. navigator.credentials.get). */\nexport type WebAuthnSigner = (challenge: string) => Promise<AssertionResult> | AssertionResult;\n\n/**\n * Opt-in pre-flight validation of the returned assertion, run BEFORE the entry\n * is assembled and submitted. On-chain `__check_auth` is the real gate, but\n * catching these client-side turns an opaque on-chain failure into a typed\n * `KitError` at the call site. Providing this object always enforces the\n * `webauthn.get` type, the User-Present (UP) flag (required by passkey-kit v1),\n * and challenge-binding; `rpId` / `origin` / `publicKey` add their checks when\n * supplied. Omit the object entirely to skip pre-flight (the default).\n */\nexport interface SignVerifyOptions {\n /** Verify `authenticatorData.rpIdHash === SHA-256(rpId)`. */\n rpId?: string;\n /** Verify `clientDataJSON.origin` is one of these exact origins. */\n origin?: string | string[];\n /** SEC-1 (65-byte) public key → verify the ECDSA assertion signature. */\n publicKey?: Uint8Array;\n /** Also require the User-Verified (UV) flag (biometric / PIN). Default false. */\n requireUserVerification?: boolean;\n /** Allow an assertion made in a cross-origin context (crossOrigin=true). Default false. */\n allowCrossOrigin?: boolean;\n}\n\nexport interface SorobanSignOptions {\n networkPassphrase: string;\n sign: WebAuthnSigner;\n /**\n * Restrict `signTransaction` to auth entries whose credential address equals this\n * C-address. When set, only the connected account's entries are signed and any other\n * authorizer's entries are left untouched, so the passkey never signs on behalf of, or\n * prompts for, accounts that are not the signer. Omit to sign every address-credential\n * entry.\n */\n signerAddress?: string;\n /**\n * SEC-1 (65-byte) public key of the signing passkey, for the `single-signer`\n * target: the v0.2 `webauthn-account` carries the signer's key inline and\n * verifies against it. Takes precedence over any `publicKey` the signer\n * returns on its `AssertionResult`. Required for `single-signer` when the\n * signer does not return one; ignored by the `smart-wallet` target.\n */\n publicKey?: Uint8Array;\n /** Contract ABI to assemble for. Defaults to `single-signer` (our account). */\n target?: WalletTarget;\n /** Opt-in pre-flight assertion validation. Omit to skip. */\n verify?: SignVerifyOptions;\n /**\n * Stamp this `signatureExpirationLedger` onto every address-credential auth\n * entry BEFORE the challenge is computed, so the signature binds the exact\n * expiration the contract re-derives in `__check_auth`. Needed for smart-wallet\n * writes (add/remove signer) where the caller learns the ledger at sign time;\n * omit when the entry already carries the intended expiration.\n */\n signatureExpirationLedger?: number;\n}\n\n/** Validate an assertion against the expected challenge + RP context. Throws KitError. */\nfunction preflightAssertion(\n assertion: AssertionResult,\n challenge: string,\n verify: SignVerifyOptions,\n): void {\n // Ceremony type + challenge-binding (+ origin when provided).\n let clientData: ClientData;\n if (verify.origin !== undefined) {\n clientData = verifyClientDataJSON(assertion.clientDataJSON, {\n origin: verify.origin,\n challenge,\n });\n } else {\n clientData = parseClientDataJSON(assertion.clientDataJSON);\n if (clientData.type !== 'webauthn.get') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `clientDataJSON.type \"${clientData.type}\" is not \"webauthn.get\"`,\n );\n }\n if (clientData.challenge !== challenge) {\n throw new KitError('CHALLENGE_MISMATCH', 'assertion challenge does not match the auth entry');\n }\n }\n if (clientData.crossOrigin === true && !verify.allowCrossOrigin) {\n throw new KitError(\n 'ORIGIN_MISMATCH',\n 'assertion was made in a cross-origin context (crossOrigin=true)',\n );\n }\n // User-Present is mandatory (passkey-kit v1 hardening); UV is opt-in.\n const parsed = parseAuthenticatorData(assertion.authenticatorData);\n if (!parsed.flags.up) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'assertion is missing the User-Present (UP) flag',\n );\n }\n if (verify.requireUserVerification && !parsed.flags.uv) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'assertion is missing the required User-Verified (UV) flag',\n );\n }\n if (verify.rpId !== undefined) {\n verifyRpIdHash(assertion.authenticatorData, verify.rpId);\n }\n if (verify.publicKey !== undefined) {\n const ok = verifyAssertionSignature({\n publicKey: verify.publicKey,\n authenticatorData: assertion.authenticatorData,\n clientDataJSON: assertion.clientDataJSON,\n signature: assertion.signature,\n });\n if (!ok) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'assertion signature failed pre-flight verification',\n );\n }\n }\n}\n\nasync function signEntryInPlace(\n entry: xdr.SorobanAuthorizationEntry,\n options: SorobanSignOptions,\n): Promise<void> {\n // Stamp the expiration first: the challenge preimage includes\n // signatureExpirationLedger, so it must be final before we compute it.\n if (options.signatureExpirationLedger !== undefined) {\n const creds = entry.credentials();\n if (creds.switch().name === 'sorobanCredentialsAddress') {\n creds.address().signatureExpirationLedger(options.signatureExpirationLedger);\n }\n }\n const challenge = authEntryChallenge(entry, options.networkPassphrase);\n const assertion = await options.sign(challenge);\n if (options.verify) preflightAssertion(assertion, challenge, options.verify);\n // Always low-S normalize (invariant #2), on BOTH branches: an already-compact\n // 64-byte signature from a custom signer can still be high-S, which the on-chain\n // secp256r1 verifier rejects.\n const signature =\n assertion.signature.length === 64\n ? normalizeLowS(assertion.signature)\n : derToCompactLowS(assertion.signature);\n const normalized = {\n credentialId: assertion.credentialId,\n authenticatorData: assertion.authenticatorData,\n clientDataJSON: assertion.clientDataJSON,\n signature,\n };\n if (options.target === 'smart-wallet') {\n applyAssertionToSmartWalletEntry(entry, normalized);\n } else {\n const publicKey = options.publicKey ?? assertion.publicKey;\n if (publicKey === undefined) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'single-signer signing requires the signer public key: set SorobanSignOptions.publicKey or return publicKey from the signer',\n );\n }\n applyAssertionToEntry(entry, normalized, publicKey);\n }\n}\n\n/**\n * Sign a single `SorobanAuthorizationEntry` (base64 XDR): compute the challenge,\n * obtain a WebAuthn assertion, low-S-normalize, and assemble the contract\n * signature. Returns the signed entry as base64 XDR.\n */\nexport async function signAuthEntry(\n entryXdr: string,\n options: SorobanSignOptions,\n): Promise<string> {\n const entry = xdr.SorobanAuthorizationEntry.fromXDR(entryXdr, 'base64');\n await signEntryInPlace(entry, options);\n return entry.toXDR('base64');\n}\n\n/**\n * The operations whose Soroban auth entries we sign, for a v1 or a fee-bump\n * envelope. (Sign the Soroban auth entries before adding classic tx signatures\n * or fee-bumping; a fee-bump around an already-classic-signed inner tx is the\n * caller's sequencing concern.)\n */\nfunction operationsForSigning(envelope: xdr.TransactionEnvelope): xdr.Operation[] {\n const kind = envelope.switch().name;\n if (kind === 'envelopeTypeTx') return envelope.v1().tx().operations();\n if (kind === 'envelopeTypeTxFeeBump') {\n const inner = envelope.feeBump().tx().innerTx();\n if (inner.switch().name !== 'envelopeTypeTx') {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'signTransaction: fee-bump inner transaction is not a v1 transaction',\n );\n }\n return inner.v1().tx().operations();\n }\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n `signTransaction: unsupported envelope type \"${kind}\" (expected v1 or fee-bump)`,\n );\n}\n\n/**\n * Sign every address-credential Soroban auth entry carried by the InvokeHostFunction\n * operations of a transaction (base64 XDR envelope — v1 or fee-bump). Returns the\n * signed envelope XDR.\n */\nexport async function signTransaction(txXdr: string, options: SorobanSignOptions): Promise<string> {\n const envelope = xdr.TransactionEnvelope.fromXDR(txXdr, 'base64');\n for (const op of operationsForSigning(envelope)) {\n if (op.body().switch().name !== 'invokeHostFunction') continue;\n const entries = op.body().invokeHostFunctionOp().auth();\n for (const entry of entries) {\n if (entry.credentials().switch().name !== 'sorobanCredentialsAddress') continue;\n if (\n options.signerAddress !== undefined &&\n Address.fromScAddress(entry.credentials().address().address()).toString() !==\n options.signerAddress\n ) {\n continue;\n }\n await signEntryInPlace(entry, options);\n }\n }\n return envelope.toXDR('base64');\n}\n","import type { CborValue } from './cbor';\nimport { utf8ToBytes } from './encoding';\n\n/**\n * Minimal CBOR encoder — the inverse of `cbor.ts`, supporting the same major\n * types (uint, negint, byte string, text string, array, map). Used by the\n * deterministic mock authenticator (S15) to synthesize real attestationObject /\n * COSE-key bytes, so the mock create path goes through the exact same\n * `extractPublicKeyFromAttestationObject` as production. Not canonical-ordered\n * (our decoder is order-agnostic) and intentionally narrow.\n */\nfunction head(major: number, arg: number): number[] {\n const m = major << 5;\n if (arg < 24) return [m | arg];\n if (arg < 0x100) return [m | 24, arg];\n if (arg < 0x10000) return [m | 25, (arg >> 8) & 0xff, arg & 0xff];\n return [m | 26, (arg >>> 24) & 0xff, (arg >> 16) & 0xff, (arg >> 8) & 0xff, arg & 0xff];\n}\n\nfunction write(value: CborValue, out: number[]): void {\n if (typeof value === 'number' && Number.isInteger(value)) {\n if (value >= 0) out.push(...head(0, value));\n else out.push(...head(1, -1 - value));\n } else if (value instanceof Uint8Array) {\n out.push(...head(2, value.length));\n for (const b of value) out.push(b);\n } else if (typeof value === 'string') {\n const bytes = utf8ToBytes(value);\n out.push(...head(3, bytes.length));\n for (const b of bytes) out.push(b);\n } else if (Array.isArray(value)) {\n out.push(...head(4, value.length));\n for (const item of value) write(item, out);\n } else if (value instanceof Map) {\n out.push(...head(5, value.size));\n for (const [k, v] of value) {\n write(k, out);\n write(v, out);\n }\n } else {\n throw new Error('CBOR encode: unsupported value');\n }\n}\n\nexport function encodeCbor(value: CborValue): Uint8Array {\n const out: number[] = [];\n write(value, out);\n return Uint8Array.from(out);\n}\n","import { p256 } from '@noble/curves/nist';\nimport { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\nimport { encodeCbor } from '../internal/cborEncode';\nimport type { CborValue } from '../internal/cbor';\nimport type {\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from '../ceremonies/types';\nimport type { AssertionResult } from '../soroban/sign';\n\nexport interface MockAuthenticatorOptions {\n rpId: string;\n origin?: string;\n /** Deterministic seed → keypair + credentialId. */\n seed?: string;\n /** Emit high-S signatures, to exercise the perpetual low-S guard (S04). */\n forceHighS?: boolean;\n}\n\nexport interface MockAuthenticator extends WebAuthnClient {\n readonly publicKey: Uint8Array; // 65-byte SEC-1\n readonly credentialId: string; // base64url\n readonly privateKey: Uint8Array;\n /** WebAuthnSigner for the Soroban sign path (challenge already base64url). */\n sign(challenge: string): AssertionResult;\n}\n\nfunction deriveScalar(seed: string): Uint8Array {\n const n = p256.CURVE.n;\n let scalar = BigInt('0x' + bytesToHexLocal(sha256(utf8ToBytes('priv:' + seed)))) % n;\n if (scalar === 0n) scalar = 1n;\n const hex = scalar.toString(16).padStart(64, '0');\n return Uint8Array.from((hex.match(/../g) ?? []).map((h) => parseInt(h, 16)));\n}\nfunction bytesToHexLocal(bytes: Uint8Array): string {\n let hex = '';\n for (const b of bytes) hex += b.toString(16).padStart(2, '0');\n return hex;\n}\n\n/**\n * A deterministic, in-memory WebAuthn authenticator for the mock kit (S15). It\n * synthesizes a REAL attestationObject / COSE key (so `createPasskey` runs the\n * exact production extraction path) and signs assertions with the same P-256\n * key — optionally as high-S to prove the low-S normalization guard.\n */\nexport function mockAuthenticator(options: MockAuthenticatorOptions): MockAuthenticator {\n const seed = options.seed ?? 'mock-authenticator';\n const origin = options.origin ?? `https://${options.rpId}`;\n const privateKey = deriveScalar(seed);\n const publicKey = p256.getPublicKey(privateKey, false); // 0x04 ‖ X ‖ Y\n const x = publicKey.slice(1, 33);\n const y = publicKey.slice(33, 65);\n const credIdBytes = sha256(utf8ToBytes('cred:' + seed)).slice(0, 16);\n const credentialId = bytesToBase64Url(credIdBytes);\n const rpIdHash = sha256(utf8ToBytes(options.rpId));\n\n const coseKey = encodeCbor(\n new Map<number | string, CborValue>([\n [1, 2], // kty EC2\n [3, -7], // alg ES256\n [-1, 1], // crv P-256\n [-2, x],\n [-3, y],\n ]),\n );\n\n const attestedAuthData = concatBytes(\n rpIdHash,\n new Uint8Array([0x45]), // UP | UV | AT\n new Uint8Array([0, 0, 0, 0]), // signCount\n new Uint8Array(16), // aaguid\n new Uint8Array([0, credIdBytes.length]),\n credIdBytes,\n coseKey,\n );\n const attestationObject = encodeCbor(\n new Map<number | string, CborValue>([\n ['fmt', 'none'],\n ['attStmt', new Map<number | string, CborValue>()],\n ['authData', attestedAuthData],\n ]),\n );\n\n function signAssertion(challengeB64: string): {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n signatureDer: Uint8Array;\n } {\n const authenticatorData = concatBytes(\n rpIdHash,\n new Uint8Array([0x05]),\n new Uint8Array([0, 0, 0, 1]),\n );\n const clientDataJSON = utf8ToBytes(\n JSON.stringify({ type: 'webauthn.get', challenge: challengeB64, origin }),\n );\n const payload = sha256(concatBytes(authenticatorData, sha256(clientDataJSON)));\n const sig = p256.sign(payload, privateKey); // low-S by default\n const s = options.forceHighS ? p256.CURVE.n - sig.s : sig.s;\n const signatureDer = new p256.Signature(sig.r, s).toDERRawBytes();\n return { authenticatorData, clientDataJSON, signatureDer };\n }\n\n return {\n publicKey,\n credentialId,\n privateKey,\n create(): Promise<WebAuthnCreateResult> {\n return Promise.resolve({ id: credentialId, rawId: credIdBytes, attestationObject });\n },\n get(getOptions: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const challengeB64 = getOptions.challenge ? bytesToBase64Url(getOptions.challenge) : 'mock';\n const a = signAssertion(challengeB64);\n return Promise.resolve({\n id: credentialId,\n rawId: credIdBytes,\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n });\n },\n sign(challenge: string): AssertionResult {\n const a = signAssertion(challenge);\n return {\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n credentialId: credIdBytes,\n publicKey,\n };\n },\n };\n}\n","import { StrKey } from '@stellar/stellar-sdk';\nimport { sha256 } from '../internal/sha256';\nimport { utf8ToBytes } from '../internal/encoding';\nimport type { AccountDeployer } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\n\nexport interface InMemoryBackend {\n deployer: AccountDeployer;\n indexer: IndexerAdapter;\n submission: SubmissionAdapter;\n /** credentialId → { contractId, publicKey } — shared so create/connect/recover agree. */\n registry: Map<string, { contractId: string; publicKey: Uint8Array }>;\n}\n\n/**\n * Deterministic, zero-IO backend for the mock kit: the deployer derives a stable\n * C-address from the credentialId and records it; the indexer resolves from the\n * same registry; submission is a no-op SUCCESS.\n *\n * The address is a real StrKey contract id (checksummed, decodable), so a mock\n * account can be fed straight into `new Address(...)` / auth-entry XDR the same way\n * a deployed one is. It is deterministic but arbitrary: it is not the address the\n * factory would deploy for this credential (that is {@link deriveAccountAddress}).\n */\nexport function createInMemoryBackend(): InMemoryBackend {\n const registry = new Map<string, { contractId: string; publicKey: Uint8Array }>();\n let nonce = 0;\n return {\n registry,\n deployer: {\n deploy({ publicKey, credentialId }) {\n const contractId = StrKey.encodeContract(\n Buffer.from(sha256(utf8ToBytes('account:' + credentialId))),\n );\n registry.set(credentialId, { contractId, publicKey });\n return Promise.resolve({ contractId, txHash: `mock-deploy-${String(nonce++)}` });\n },\n },\n indexer: {\n resolveByCredential(credentialId) {\n const account = registry.get(credentialId);\n // Carry the founding public key the same way the real `eventsIndexer` reads it\n // off the factory `deployed` event, so mock-mode connect/recover can verify\n // enrollment and recover the signing key (no mock/live divergence).\n return Promise.resolve(\n account ? [{ contractId: account.contractId, publicKey: account.publicKey }] : [],\n );\n },\n },\n submission: {\n send: () => Promise.resolve({ status: 'SUCCESS', hash: 'mock-tx' }),\n },\n };\n}\n","import { createPasskey as createPasskeyCeremony } from '../ceremonies/create';\nimport { connect as connectCeremony, type ConnectResult } from '../ceremonies/connect';\nimport { recover as recoverCeremony, type RecoverResult } from '../ceremonies/recover';\nimport { signAuthEntry as signAuthEntryFn, type WebAuthnSigner } from '../soroban/sign';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\nimport type { PasskeyCredential } from '../types';\nimport { mockAuthenticator } from './mockAuthenticator';\nimport { createInMemoryBackend } from './inMemory';\n\nconst TESTNET = 'Test SDF Network ; September 2015';\n\nexport interface CreatePasskeyKitOptions {\n mode: 'mock' | 'live';\n rpId: string;\n rpName?: string;\n networkPassphrase?: string;\n // mock-mode knobs\n seed?: string;\n forceHighS?: boolean;\n // live-mode dependencies\n webauthn?: WebAuthnClient;\n deployer?: AccountDeployer;\n indexer?: IndexerAdapter;\n submission?: SubmissionAdapter;\n storage?: CredentialStorage;\n signer?: WebAuthnSigner;\n}\n\nexport interface PasskeyKit {\n readonly mode: 'mock' | 'live';\n readonly rpId: string;\n createPasskey(input?: { userName?: string }): Promise<PasskeyCredential>;\n connect(): Promise<ConnectResult | null>;\n recover(): Promise<RecoverResult[]>;\n signAuthEntry(entryXdr: string): Promise<string>;\n}\n\nfunction inMemoryStorage(): CredentialStorage {\n const map = new Map<string, string>();\n return { get: (rpId) => map.get(rpId) ?? null, set: (rpId, id) => void map.set(rpId, id) };\n}\n\n/**\n * The downstream-adopter kit (S15, Deliverable #6). `mode:'mock'` wires a\n * deterministic in-memory authenticator + backend (zero network IO) so the\n * happy path matches the live path's SHAPE — swap `mock → live` and the demo\n * stays green. `mode:'live'` takes real adapters + a WebAuthn signer.\n */\nexport function createPasskeyKit(options: CreatePasskeyKitOptions): PasskeyKit {\n const networkPassphrase = options.networkPassphrase ?? TESTNET;\n const rpName = options.rpName ?? options.rpId;\n\n let webauthn: WebAuthnClient;\n let deployer: AccountDeployer;\n let indexer: IndexerAdapter;\n let storage: CredentialStorage;\n let signer: WebAuthnSigner;\n\n if (options.mode === 'mock') {\n const auth = mockAuthenticator({\n rpId: options.rpId,\n seed: options.seed,\n forceHighS: options.forceHighS,\n });\n const backend = createInMemoryBackend();\n webauthn = auth;\n deployer = backend.deployer;\n indexer = backend.indexer;\n signer = auth.sign;\n storage = inMemoryStorage();\n } else {\n if (!options.webauthn || !options.deployer || !options.indexer || !options.signer) {\n throw new Error('live mode requires webauthn, deployer, indexer and signer');\n }\n webauthn = options.webauthn;\n deployer = options.deployer;\n indexer = options.indexer;\n signer = options.signer;\n storage = options.storage ?? inMemoryStorage();\n }\n\n return {\n mode: options.mode,\n rpId: options.rpId,\n createPasskey: (input) =>\n createPasskeyCeremony({\n rpId: options.rpId,\n rpName,\n userName: input?.userName ?? 'user',\n deployer,\n webauthn,\n storage,\n }),\n connect: () =>\n connectCeremony({\n rpId: options.rpId,\n indexer,\n webauthn,\n storage,\n silentMediationSupported: false,\n }),\n recover: () => recoverCeremony({ rpId: options.rpId, indexer, webauthn }),\n signAuthEntry: (entryXdr) => signAuthEntryFn(entryXdr, { networkPassphrase, sign: signer }),\n };\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\n\n/**\n * A ready-to-sign `SorobanAuthorizationEntry` (base64 XDR) for a demo call on\n * `contractId`. A convenience for smoke tests and examples, so you do not hand-\n * build auth-entry XDR just to have something to sign. The nonce and expiration\n * are fixed placeholders, so this is for local verification, not production.\n */\nexport function sampleAuthEntry(contractId: string, functionName = 'protected'): string {\n const address = new Address(contractId).toScAddress();\n const entry = new xdr.SorobanAuthorizationEntry({\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(\n new xdr.SorobanAddressCredentials({\n address,\n nonce: new xdr.Int64(1),\n signatureExpirationLedger: 1000,\n signature: xdr.ScVal.scvVoid(),\n }),\n ),\n rootInvocation: new xdr.SorobanAuthorizedInvocation({\n function: xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(\n new xdr.InvokeContractArgs({ contractAddress: address, functionName, args: [] }),\n ),\n subInvocations: [],\n }),\n });\n return entry.toXDR('base64');\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/anchors.ts","../src/internal/encoding.ts","../src/webauthn/createOptions.ts","../src/internal/bytes.ts","../src/internal/cbor.ts","../src/webauthn/authData.ts","../src/webauthn/publicKey.ts","../src/ceremonies/random.ts","../src/ceremonies/browserClient.ts","../src/ceremonies/create.ts","../src/ceremonies/connect.ts","../src/ceremonies/recover.ts","../src/webauthn/signature.ts","../src/webauthn/clientData.ts","../src/webauthn/payload.ts","../src/webauthn/verify.ts","../src/soroban/preimage.ts","../src/soroban/assemble.ts","../src/soroban/smartWallet.ts","../src/soroban/sign.ts","../src/internal/cborEncode.ts","../src/testing/mockAuthenticator.ts","../src/testing/inMemory.ts","../src/testing/kit.ts","../src/testing/sampleAuthEntry.ts"],"names":["sha256","p256","xdr","hash","StrKey","Address"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * The frozen taxonomy of error codes the SDK can throw. This union is\n * deliberately closed — every failure path maps to exactly one of these.\n */\nexport const KIT_ERROR_CODES = Object.freeze([\n 'USER_CANCELLED',\n 'ES256_NOT_SUPPORTED',\n 'RP_ID_MISMATCH',\n 'ORIGIN_MISMATCH',\n 'CHALLENGE_MISMATCH',\n 'INVALID_SIGNATURE_DER',\n 'INVALID_PUBLIC_KEY',\n 'CONTRACT_AUTH_FAILED',\n 'NETWORK_ERROR',\n 'UNSUPPORTED_AUTHENTICATOR',\n] as const);\n\nexport type KitErrorCode = (typeof KIT_ERROR_CODES)[number];\n\n/** Structured error carrying a machine-readable {@link KitErrorCode}. */\nexport class KitError extends Error {\n readonly code: KitErrorCode;\n override readonly name = 'KitError';\n\n constructor(code: KitErrorCode, message?: string, options?: { cause?: unknown }) {\n super(message ?? code, options);\n this.code = code;\n // Restore the prototype chain so `instanceof KitError` works after\n // down-level transpilation to CJS.\n Object.setPrototypeOf(this, KitError.prototype);\n }\n}\n\nexport function isKitError(value: unknown): value is KitError {\n return value instanceof KitError;\n}\n","import { KitError } from './errors';\n\n/**\n * Stable identifiers for the three battle-tested anchors (S04 / YK-430) — the\n * bugs that silently break ~50% of users. Referenced by stable name from the\n * threat model (S14) and the compatibility matrix (S09) so each mitigation has\n * one canonical id across code and docs.\n */\nexport const BATTLE_TESTED_ANCHORS = Object.freeze({\n /** Apple Touch ID/Face ID emit high-S ~50% of the time; we normalize to low-S. */\n LOW_S_NORMALIZATION: 'low-s-normalization',\n /** Non-ES256 credentials (e.g. some Windows Hello configs) cannot verify on-chain. */\n RS256_HARD_FAIL: 'rs256-hard-fail',\n /** Safari requires create/get inside a user activation or it silently rejects. */\n APPLE_USER_GESTURE: 'apple-user-gesture',\n} as const);\n\nexport type BattleTestedAnchor = (typeof BATTLE_TESTED_ANCHORS)[keyof typeof BATTLE_TESTED_ANCHORS];\n\n/** COSE algorithm id for ES256 (ECDSA w/ SHA-256 over P-256). */\nconst ALG_ES256 = -7;\n\n/**\n * Anchor `RS256_HARD_FAIL`. The Soroban webauthn-wallet verifies *only*\n * secp256r1, so a non-ES256 credential would produce an unusable account.\n * Hard-fail rather than continue (invariant #1).\n */\nexport function assertES256(alg: number): void {\n if (alg !== ALG_ES256) {\n throw new KitError('ES256_NOT_SUPPORTED', `COSE alg ${alg} is not ES256 (-7)`);\n }\n}\n\ninterface UserActivationLike {\n isActive: boolean;\n}\n\n/**\n * Anchor `APPLE_USER_GESTURE`. `navigator.credentials.create/get` on\n * Safari/WebKit must run inside a transient user activation (a real click/tap)\n * or the promise silently rejects. Call this at the very top of a create/sign\n * handler.\n *\n * UI pattern (for S18): never auto-trigger the ceremony from a mount/effect —\n * always gate it behind an explicit user click, and surface `USER_CANCELLED`\n * in the flow state machine. Lenient when `navigator.userActivation` is\n * unavailable (non-browser / older engines) so the SDK stays isomorphic; pass\n * an explicit `{ isActive }` to force the check.\n */\nexport function assertUserActivation(activation?: UserActivationLike): void {\n const ua =\n activation ??\n (globalThis.navigator as { userActivation?: UserActivationLike } | undefined)?.userActivation;\n if (ua && !ua.isActive) {\n throw new KitError(\n 'USER_CANCELLED',\n 'WebAuthn ceremony must be invoked inside a user activation (click/tap)',\n );\n }\n}\n","/**\n * Isomorphic base64url + UTF-8 codecs. `atob`/`btoa`/`TextEncoder`/`TextDecoder`\n * are globals in modern browsers and Node >= 16, so no platform branch is\n * needed and nothing is bundled.\n */\n\n/** Encode bytes as unpadded base64url. */\nexport function bytesToBase64Url(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/** Decode base64 or base64url (padding optional) to bytes. */\nexport function base64UrlToBytes(input: string): Uint8Array<ArrayBuffer> {\n const base64 = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n const binary = atob(padded);\n const out = new Uint8Array(new ArrayBuffer(binary.length));\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nexport function utf8ToBytes(text: string): Uint8Array {\n return new TextEncoder().encode(text);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n","import { bytesToBase64Url } from '../internal/encoding';\nimport { utf8ToBytes } from '../internal/encoding';\n\nexport type ResidentKeyRequirement = 'discouraged' | 'preferred' | 'required';\nexport type UserVerificationRequirement = 'discouraged' | 'preferred' | 'required';\n\nexport interface BuildCreateOptionsInput {\n rpId: string;\n rpName: string;\n userName: string;\n /** Stable, opaque user handle. Defaults to UTF-8 bytes of `userName`. */\n userId?: Uint8Array;\n userDisplayName?: string;\n /** Raw challenge bytes (base64url-encoded into the options). */\n challenge: Uint8Array;\n residentKey?: ResidentKeyRequirement;\n userVerification?: UserVerificationRequirement;\n timeout?: number;\n}\n\n/** ES256-only credential parameter. The `alg: -7` literal is non-negotiable. */\nexport interface PubKeyCredParam {\n type: 'public-key';\n alg: -7;\n}\n\nexport interface PublicKeyCredentialCreationOptionsJSON {\n rp: { id: string; name: string };\n user: { id: string; name: string; displayName: string };\n challenge: string;\n pubKeyCredParams: PubKeyCredParam[];\n authenticatorSelection: {\n residentKey: ResidentKeyRequirement;\n requireResidentKey: boolean;\n userVerification: UserVerificationRequirement;\n };\n attestation: 'none';\n timeout: number;\n}\n\n/**\n * Build WebAuthn registration options that offer ES256 *and only* ES256\n * (`pubKeyCredParams: [{ type: 'public-key', alg: -7 }]`) — invariant #1.\n * Soroban verifies only secp256r1, so we never advertise any other algorithm.\n */\nexport function buildCreateOptions(\n input: BuildCreateOptionsInput,\n): PublicKeyCredentialCreationOptionsJSON {\n const residentKey = input.residentKey ?? 'required';\n return {\n rp: { id: input.rpId, name: input.rpName },\n user: {\n id: bytesToBase64Url(input.userId ?? utf8ToBytes(input.userName)),\n name: input.userName,\n displayName: input.userDisplayName ?? input.userName,\n },\n challenge: bytesToBase64Url(input.challenge),\n pubKeyCredParams: [{ type: 'public-key', alg: -7 }],\n authenticatorSelection: {\n residentKey,\n requireResidentKey: residentKey === 'required',\n // The v0.2 account requires the User-Verified flag at sign time, so\n // register with 'required' to enroll authenticators that can produce it.\n userVerification: input.userVerification ?? 'required',\n },\n attestation: 'none',\n timeout: input.timeout ?? 60_000,\n };\n}\n","/** Concatenate byte arrays into one. */\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n const total = arrays.reduce((n, a) => n + a.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const a of arrays) {\n out.set(a, offset);\n offset += a.length;\n }\n return out;\n}\n\n/** Length-safe, constant-time-ish byte equality. */\nexport function equalBytes(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i += 1) diff |= (a[i] ?? 0) ^ (b[i] ?? 0);\n return diff === 0;\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = '';\n for (const byte of bytes) hex += byte.toString(16).padStart(2, '0');\n return hex;\n}\n","/**\n * A minimal CBOR (RFC 8949) decoder — only the major types WebAuthn needs:\n * unsigned ints, negative ints, byte strings, text strings, arrays and maps,\n * with 1/2/4-byte length prefixes. Indefinite lengths, tags, floats and\n * 8-byte lengths are intentionally unsupported (COSE keys and attestation\n * objects never use them) and throw. This keeps the SDK dependency-free while\n * staying robust — it is fully fixture-tested. It replaces passkey-kit's\n * hardcoded byte-offset scanning, which had no bounds checks.\n */\nexport type CborValue = number | bigint | Uint8Array | string | CborValue[] | CborMap;\nexport type CborMap = Map<number | string, CborValue>;\n\ninterface Decoded {\n value: CborValue;\n /** Total bytes consumed starting at the requested offset. */\n length: number;\n}\n\nfunction byteAt(bytes: Uint8Array, index: number): number {\n const value = bytes[index];\n if (value === undefined) throw new Error(`CBOR: unexpected end of input at byte ${index}`);\n return value;\n}\n\n/** Decode the first CBOR item at `offset`, returning its value and byte length. */\nconst MAX_DEPTH = 16; // COSE keys / attestation objects nest at most ~3 levels.\n\nexport function decodeCbor(bytes: Uint8Array, offset = 0, depth = 0): Decoded {\n if (depth > MAX_DEPTH) throw new Error('CBOR: maximum nesting depth exceeded');\n const first = byteAt(bytes, offset);\n const major = first >> 5;\n const info = first & 0x1f;\n let pos = offset + 1;\n\n let argument: number;\n if (info < 24) {\n argument = info;\n } else if (info === 24) {\n argument = byteAt(bytes, pos);\n pos += 1;\n } else if (info === 25) {\n argument = (byteAt(bytes, pos) << 8) | byteAt(bytes, pos + 1);\n pos += 2;\n } else if (info === 26) {\n argument =\n byteAt(bytes, pos) * 0x1000000 +\n (byteAt(bytes, pos + 1) << 16) +\n (byteAt(bytes, pos + 2) << 8) +\n byteAt(bytes, pos + 3);\n pos += 4;\n } else {\n throw new Error(`CBOR: unsupported length encoding (additional info ${info})`);\n }\n\n switch (major) {\n case 0: // unsigned integer\n return { value: argument, length: pos - offset };\n case 1: // negative integer\n return { value: -1 - argument, length: pos - offset };\n case 2: {\n // byte string\n const end = pos + argument;\n if (end > bytes.length) throw new Error('CBOR: byte string exceeds input');\n return { value: bytes.slice(pos, end), length: end - offset };\n }\n case 3: {\n // text string (UTF-8)\n const end = pos + argument;\n if (end > bytes.length) throw new Error('CBOR: text string exceeds input');\n return { value: new TextDecoder().decode(bytes.slice(pos, end)), length: end - offset };\n }\n case 4: {\n // array\n const items: CborValue[] = [];\n let cursor = pos;\n for (let i = 0; i < argument; i += 1) {\n const item = decodeCbor(bytes, cursor, depth + 1);\n items.push(item.value);\n cursor += item.length;\n }\n return { value: items, length: cursor - offset };\n }\n case 5: {\n // map\n const map: CborMap = new Map();\n let cursor = pos;\n for (let i = 0; i < argument; i += 1) {\n const key = decodeCbor(bytes, cursor, depth + 1);\n cursor += key.length;\n const val = decodeCbor(bytes, cursor, depth + 1);\n cursor += val.length;\n if (typeof key.value !== 'number' && typeof key.value !== 'string') {\n throw new Error('CBOR: unsupported map key type');\n }\n if (map.has(key.value)) {\n throw new Error('CBOR: duplicate map key (non-canonical)');\n }\n map.set(key.value, val.value);\n }\n return { value: map, length: cursor - offset };\n }\n default:\n throw new Error(`CBOR: unsupported major type ${major}`);\n }\n}\n\nexport function decodeCborFirst(bytes: Uint8Array): CborValue {\n return decodeCbor(bytes, 0).value;\n}\n","import { KitError } from '../errors';\nimport { decodeCbor } from '../internal/cbor';\nimport { sha256 } from '../internal/sha256';\nimport { equalBytes } from '../internal/bytes';\nimport { utf8ToBytes } from '../internal/encoding';\n\nexport interface AuthenticatorDataFlags {\n /** User Present */\n up: boolean;\n /** User Verified */\n uv: boolean;\n /** Backup Eligible */\n be: boolean;\n /** Backup State */\n bs: boolean;\n /** Attested credential data present */\n at: boolean;\n /** Extension data present */\n ed: boolean;\n /** Raw flags byte. */\n bits: number;\n}\n\nexport interface ParsedAuthenticatorData {\n rpIdHash: Uint8Array;\n flags: AuthenticatorDataFlags;\n signCount: number;\n aaguid?: Uint8Array;\n credentialId?: Uint8Array;\n /** Raw CBOR-encoded COSE public key (exact bytes), if attested data present. */\n credentialPublicKey?: Uint8Array;\n}\n\nconst MIN_LENGTH = 37; // rpIdHash(32) + flags(1) + signCount(4)\n\n/** Parse the authenticatorData byte structure (WebAuthn §6.1). */\nexport function parseAuthenticatorData(authData: Uint8Array): ParsedAuthenticatorData {\n if (authData.length < MIN_LENGTH) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `authenticatorData is ${authData.length} bytes, expected at least ${MIN_LENGTH}`,\n );\n }\n const view = new DataView(authData.buffer, authData.byteOffset, authData.byteLength);\n const rpIdHash = authData.slice(0, 32);\n const bits = authData[32] ?? 0;\n const flags: AuthenticatorDataFlags = {\n up: (bits & 0x01) !== 0,\n uv: (bits & 0x04) !== 0,\n be: (bits & 0x08) !== 0,\n bs: (bits & 0x10) !== 0,\n at: (bits & 0x40) !== 0,\n ed: (bits & 0x80) !== 0,\n bits,\n };\n const signCount = view.getUint32(33, false);\n\n const result: ParsedAuthenticatorData = { rpIdHash, flags, signCount };\n\n if (flags.at) {\n if (authData.length < 55) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'authenticatorData truncated in attested data',\n );\n }\n result.aaguid = authData.slice(37, 53);\n const credIdLength = view.getUint16(53, false);\n const credIdEnd = 55 + credIdLength;\n if (authData.length < credIdEnd) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'authenticatorData truncated in credentialId',\n );\n }\n result.credentialId = authData.slice(55, credIdEnd);\n // The COSE public key is the next CBOR item; capture its exact bytes so we\n // stop cleanly before any extension data (when flags.ed is set).\n const rest = authData.slice(credIdEnd);\n const { length } = decodeCbor(rest, 0);\n result.credentialPublicKey = rest.slice(0, length);\n }\n\n return result;\n}\n\n/** Verify that authenticatorData's rpIdHash equals SHA-256(rpId). */\nexport function verifyRpIdHash(authData: Uint8Array, rpId: string): void {\n const actual = parseAuthenticatorData(authData).rpIdHash;\n const expected = sha256(utf8ToBytes(rpId));\n if (!equalBytes(actual, expected)) {\n throw new KitError(\n 'RP_ID_MISMATCH',\n `authenticatorData rpIdHash does not match SHA-256(\"${rpId}\")`,\n );\n }\n}\n","import { p256 } from '@noble/curves/nist';\nimport { KitError } from '../errors';\nimport { concatBytes } from '../internal/bytes';\nimport { decodeCborFirst, type CborMap } from '../internal/cbor';\nimport { parseAuthenticatorData } from './authData';\nimport { assertES256 } from '../anchors';\n\n// COSE key common parameters (RFC 9052) and EC2 key parameters.\nconst COSE_KTY = 1;\nconst COSE_ALG = 3;\nconst COSE_CRV = -1;\nconst COSE_X = -2;\nconst COSE_Y = -3;\n\nconst KTY_EC2 = 2;\nconst CRV_P256 = 1;\n\n/**\n * Convert a CBOR-encoded COSE EC2 public key to the 65-byte SEC-1 uncompressed\n * point `0x04 ‖ X ‖ Y`. Enforces ES256/P-256 — anything else (e.g. RS256)\n * throws `ES256_NOT_SUPPORTED` (invariant #1).\n */\nexport function coseKeyToSec1(coseKey: Uint8Array): Uint8Array {\n let decoded: ReturnType<typeof decodeCborFirst>;\n try {\n decoded = decodeCborFirst(coseKey);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'failed to CBOR-decode COSE key', { cause });\n }\n if (!(decoded instanceof Map)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key is not a CBOR map');\n }\n const map = decoded as CborMap;\n const alg = map.get(COSE_ALG);\n if (typeof alg !== 'number') {\n throw new KitError('ES256_NOT_SUPPORTED', `COSE alg ${String(alg)} is not ES256 (-7)`);\n }\n assertES256(alg); // anchor RS256_HARD_FAIL\n if (map.get(COSE_KTY) !== KTY_EC2) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n `COSE kty ${String(map.get(COSE_KTY))} is not EC2 (2)`,\n );\n }\n if (map.get(COSE_CRV) !== CRV_P256) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n `COSE crv ${String(map.get(COSE_CRV))} is not P-256 (1)`,\n );\n }\n const x = map.get(COSE_X);\n const y = map.get(COSE_Y);\n if (!(x instanceof Uint8Array) || x.length !== 32) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key X coordinate is not 32 bytes');\n }\n if (!(y instanceof Uint8Array) || y.length !== 32) {\n throw new KitError('INVALID_PUBLIC_KEY', 'COSE key Y coordinate is not 32 bytes');\n }\n const sec1 = concatBytes(new Uint8Array([0x04]), x, y);\n // Reject off-curve / invalid points so an invalid key can never be persisted.\n try {\n p256.Point.fromHex(sec1);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'public key is not a valid P-256 point', { cause });\n }\n return sec1;\n}\n\n/** Extract the SEC-1 public key from raw authenticatorData (attested data). */\nexport function extractPublicKeyFromAuthData(authData: Uint8Array): Uint8Array {\n const parsed = parseAuthenticatorData(authData);\n if (!parsed.credentialPublicKey) {\n throw new KitError(\n 'INVALID_PUBLIC_KEY',\n 'authenticatorData has no attested credential public key',\n );\n }\n return coseKeyToSec1(parsed.credentialPublicKey);\n}\n\n/** Extract the SEC-1 public key from a CBOR attestationObject (create ceremony). */\nexport function extractPublicKeyFromAttestationObject(attestationObject: Uint8Array): Uint8Array {\n let decoded: ReturnType<typeof decodeCborFirst>;\n try {\n decoded = decodeCborFirst(attestationObject);\n } catch (cause) {\n throw new KitError('INVALID_PUBLIC_KEY', 'failed to CBOR-decode attestationObject', { cause });\n }\n if (!(decoded instanceof Map)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'attestationObject is not a CBOR map');\n }\n const authData = (decoded as CborMap).get('authData');\n if (!(authData instanceof Uint8Array)) {\n throw new KitError('INVALID_PUBLIC_KEY', 'attestationObject has no authData byte string');\n }\n return extractPublicKeyFromAuthData(authData);\n}\n","import { KitError } from '../errors';\n\n/**\n * Cryptographically-random bytes, isomorphic (browser + Node global crypto).\n * Throws instead of silently returning all-zero bytes when no secure RNG is\n * present — an all-zero challenge would be catastrophic, not a soft fallback.\n */\nexport function randomBytes(length: number): Uint8Array<ArrayBuffer> {\n const webcrypto = globalThis.crypto as Crypto | undefined;\n if (typeof webcrypto?.getRandomValues !== 'function') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'no secure random source (globalThis.crypto.getRandomValues) is available in this environment',\n );\n }\n const out = new Uint8Array(new ArrayBuffer(length));\n webcrypto.getRandomValues(out);\n return out;\n}\n","import { KitError } from '../errors';\nimport { base64UrlToBytes } from '../internal/encoding';\nimport type { PublicKeyCredentialCreationOptionsJSON } from '../webauthn/createOptions';\nimport { randomBytes } from './random';\nimport type {\n CredentialStorage,\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from './types';\n\n/**\n * Map a `navigator.credentials` rejection to a `KitError`. Dismissing the OS\n * passkey sheet rejects with a `NotAllowedError` (a DOMException) — surface that\n * as `USER_CANCELLED` so the UI shows the true \"you cancelled\" copy instead of\n * the generic unsupported-authenticator fallback (S20 / S04 polish).\n */\nfunction asKitError(error: unknown): KitError {\n if (error instanceof KitError) return error;\n const name =\n typeof error === 'object' && error !== null && 'name' in error\n ? (error as { name?: unknown }).name\n : undefined;\n if (name === 'NotAllowedError') {\n return new KitError('USER_CANCELLED', 'The passkey prompt was dismissed.', { cause: error });\n }\n const message = error instanceof Error ? error.message : 'WebAuthn request failed';\n // Preserve the original DOMException name (e.g. InvalidStateError / ConstraintError)\n // in the message so diagnostics show the true cause, not just the generic bucket.\n const detail = typeof name === 'string' ? `${name}: ${message}` : message;\n return new KitError('UNSUPPORTED_AUTHENTICATOR', detail, { cause: error });\n}\n\n/** The browser `WebAuthnClient` backed by `navigator.credentials`. */\nexport function browserWebAuthnClient(): WebAuthnClient {\n const credentials = (globalThis as { navigator?: Navigator }).navigator?.credentials;\n if (!credentials) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'navigator.credentials is unavailable');\n }\n return {\n async create(options: PublicKeyCredentialCreationOptionsJSON): Promise<WebAuthnCreateResult> {\n const publicKey: PublicKeyCredentialCreationOptions = {\n challenge: base64UrlToBytes(options.challenge),\n rp: options.rp,\n user: {\n id: base64UrlToBytes(options.user.id),\n name: options.user.name,\n displayName: options.user.displayName,\n },\n pubKeyCredParams: options.pubKeyCredParams,\n authenticatorSelection: options.authenticatorSelection,\n attestation: options.attestation,\n timeout: options.timeout,\n };\n let credential: PublicKeyCredential | null;\n try {\n credential = (await credentials.create({ publicKey })) as PublicKeyCredential | null;\n } catch (error) {\n throw asKitError(error);\n }\n if (!credential) throw new KitError('USER_CANCELLED', 'credential creation returned null');\n const response = credential.response as AuthenticatorAttestationResponse;\n return {\n id: credential.id,\n rawId: new Uint8Array(credential.rawId),\n attestationObject: new Uint8Array(response.attestationObject),\n };\n },\n async get(options: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const publicKey: PublicKeyCredentialRequestOptions = {\n rpId: options.rpId,\n challenge: options.challenge ? new Uint8Array(options.challenge) : randomBytes(32),\n allowCredentials: (options.allowCredentials ?? []).map((id) => ({\n type: 'public-key',\n id: base64UrlToBytes(id),\n })),\n userVerification: options.userVerification,\n };\n const request: CredentialRequestOptions = { publicKey };\n if (options.mediation) request.mediation = options.mediation;\n let credential: PublicKeyCredential | null;\n try {\n credential = (await credentials.get(request)) as PublicKeyCredential | null;\n } catch (error) {\n throw asKitError(error);\n }\n if (!credential) throw new KitError('USER_CANCELLED', 'assertion returned null');\n const response = credential.response as AuthenticatorAssertionResponse;\n return {\n id: credential.id,\n rawId: new Uint8Array(credential.rawId),\n authenticatorData: new Uint8Array(response.authenticatorData),\n clientDataJSON: new Uint8Array(response.clientDataJSON),\n signature: new Uint8Array(response.signature),\n };\n },\n };\n}\n\n/** localStorage-backed credential store, with an in-memory fallback (Node/SSR). */\nexport function defaultCredentialStorage(): CredentialStorage {\n const key = (rpId: string): string => `stellar-passkey:${rpId}`;\n const ls = (globalThis as { localStorage?: Storage }).localStorage;\n if (ls) {\n return {\n get: (rpId) => ls.getItem(key(rpId)),\n set: (rpId, credentialId) => {\n ls.setItem(key(rpId), credentialId);\n },\n };\n }\n const memory = new Map<string, string>();\n return {\n get: (rpId) => memory.get(rpId) ?? null,\n set: (rpId, credentialId) => {\n memory.set(rpId, credentialId);\n },\n };\n}\n","import { assertUserActivation } from '../anchors';\nimport { buildCreateOptions } from '../webauthn/createOptions';\nimport { extractPublicKeyFromAttestationObject } from '../webauthn/publicKey';\nimport type { PasskeyCredential } from '../types';\nimport { browserWebAuthnClient, defaultCredentialStorage } from './browserClient';\nimport { randomBytes } from './random';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from './types';\n\nexport interface CreatePasskeyOptions {\n rpId: string;\n rpName: string;\n userName: string;\n /** Deploys the smart account for the new passkey (contract-specific; see AccountDeployer). */\n deployer: AccountDeployer;\n webauthn?: WebAuthnClient;\n storage?: CredentialStorage;\n userId?: Uint8Array;\n challenge?: Uint8Array;\n residentKey?: 'discouraged' | 'preferred' | 'required';\n userVerification?: 'discouraged' | 'preferred' | 'required';\n /** Pass navigator.userActivation to enforce the Safari gesture requirement (S04). */\n userActivation?: { isActive: boolean };\n}\n\n/** Options for {@link registerPasskey} — a create WITHOUT deploy (see below). */\nexport type RegisterPasskeyOptions = Omit<CreatePasskeyOptions, 'deployer' | 'storage'>;\n\n/** A freshly-registered passkey credential (no account deployed yet). */\nexport interface RegisteredPasskey {\n /** base64url credential id returned by the authenticator. */\n credentialId: string;\n /** SEC-1 uncompressed public key (65 bytes). */\n publicKey: Uint8Array;\n}\n\n/**\n * `registerPasskey` — register an ES256-only passkey and extract its SEC-1 public\n * key (RS256 hard-fails), but do NOT deploy an account or persist anything. This\n * is the \"new device\" primitive for multi-device recovery: a fresh device\n * produces a `{credentialId, publicKey}` signer spec that an existing device then\n * authorizes on-chain via `addSigner`. (`createPasskey` is this plus a deploy.)\n */\nexport async function registerPasskey(options: RegisterPasskeyOptions): Promise<RegisteredPasskey> {\n assertUserActivation(options.userActivation); // anchor: apple-user-gesture (S04)\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n\n const creationOptions = buildCreateOptions({\n rpId: options.rpId,\n rpName: options.rpName,\n userName: options.userName,\n userId: options.userId,\n challenge: options.challenge ?? randomBytes(32),\n residentKey: options.residentKey,\n userVerification: options.userVerification,\n });\n\n const credential = await webauthn.create(creationOptions);\n // ES256-only enforcement happens here: a non-ES256 credential throws ES256_NOT_SUPPORTED.\n const publicKey = extractPublicKeyFromAttestationObject(credential.attestationObject);\n return { credentialId: credential.id, publicKey };\n}\n\n/**\n * `createPasskey` — register an ES256-only passkey (see {@link registerPasskey}),\n * deploy a smart account for it via the factory, persist the credential id, and\n * return the account.\n */\nexport async function createPasskey(options: CreatePasskeyOptions): Promise<PasskeyCredential> {\n const storage = options.storage ?? defaultCredentialStorage();\n const { credentialId, publicKey } = await registerPasskey(options);\n const { contractId } = await options.deployer.deploy({ publicKey, credentialId });\n storage.set(options.rpId, credentialId);\n return { contractId, credentialId, publicKey };\n}\n","import type { IndexerAdapter } from '../adapters/types';\nimport { browserWebAuthnClient, defaultCredentialStorage } from './browserClient';\nimport type { CredentialStorage, WebAuthnClient } from './types';\n\nexport interface ConnectOptions {\n rpId: string;\n indexer: IndexerAdapter;\n webauthn?: WebAuthnClient;\n storage?: CredentialStorage;\n /** Override silent-mediation detection (default: probe isConditionalMediationAvailable). */\n silentMediationSupported?: boolean;\n /**\n * SEC-1 (65-byte) public key of this passkey. When set, `connect` returns the\n * account whose factory `deployed` event names this exact key, ignoring any\n * other candidate for the same credential id. Because `deploy` is\n * permissionless, a credential id can resolve to more than one account; pass\n * the founding key (persisted at create time) so a poisoned candidate is never\n * selected. When omitted, `connect` returns the first resolved account and you\n * MUST verify enrollment yourself before trusting it with funds.\n */\n publicKey?: Uint8Array;\n}\n\nexport interface ConnectResult {\n contractId: string;\n credentialId: string;\n}\n\nasync function probeConditionalMediation(): Promise<boolean> {\n const pkc = (\n globalThis as {\n PublicKeyCredential?: { isConditionalMediationAvailable?: () => Promise<boolean> };\n }\n ).PublicKeyCredential;\n if (!pkc?.isConditionalMediationAvailable) return false;\n try {\n return await pkc.isConditionalMediationAvailable();\n } catch {\n return false;\n }\n}\n\n/**\n * `connect` — silent reconnect using the stored credential id. Where conditional\n * mediation is available, does a best-effort `mediation:'silent'` liveness check;\n * the C-address is resolved via the IndexerAdapter regardless, so connect\n * degrades gracefully where silent mediation is unsupported. Returns null when\n * there is no stored credential (the caller should `recover`) or no account.\n */\nexport async function connect(options: ConnectOptions): Promise<ConnectResult | null> {\n const storage = options.storage ?? defaultCredentialStorage();\n const credentialId = storage.get(options.rpId);\n if (!credentialId) return null;\n\n const silentSupported = options.silentMediationSupported ?? (await probeConditionalMediation());\n if (silentSupported) {\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n try {\n await webauthn.get({\n rpId: options.rpId,\n allowCredentials: [credentialId],\n mediation: 'silent',\n });\n } catch {\n // A silent get may no-op or reject; resolution is via the indexer.\n }\n }\n\n const accounts = await options.indexer.resolveByCredential(credentialId);\n const selected = selectAccount(accounts, options.publicKey);\n return selected ? { contractId: selected.contractId, credentialId } : null;\n}\n\n/** True if two byte arrays are equal. */\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/**\n * Pick the resolved account. With an expected public key, return only the\n * candidate whose factory-reported founding key matches it (poison-resistant);\n * without one, fall back to the first candidate (see the `publicKey` doc on\n * ConnectOptions for why that is a trust decision the caller must back up).\n */\nfunction selectAccount(\n accounts: { contractId: string; publicKey?: Uint8Array }[],\n publicKey?: Uint8Array,\n): { contractId: string } | null {\n if (publicKey) {\n const match = accounts.find((a) => a.publicKey && bytesEqual(a.publicKey, publicKey));\n return match ? { contractId: match.contractId } : null;\n }\n return accounts[0] ?? null;\n}\n","import { assertUserActivation } from '../anchors';\nimport type { IndexerAdapter } from '../adapters/types';\nimport { browserWebAuthnClient } from './browserClient';\nimport { randomBytes } from './random';\nimport type { WebAuthnClient } from './types';\n\nexport interface RecoverOptions {\n rpId: string;\n indexer: IndexerAdapter;\n webauthn?: WebAuthnClient;\n challenge?: Uint8Array;\n userActivation?: { isActive: boolean };\n}\n\nexport interface RecoverResult {\n contractId: string;\n credentialId: string;\n}\n\n/**\n * `recover` — the lost-localStorage / new-device path. Performs a\n * discoverable-credential `get()` (no allowCredentials), then resolves every\n * smart account controlled by that credential via the IndexerAdapter.\n */\nexport async function recover(options: RecoverOptions): Promise<RecoverResult[]> {\n assertUserActivation(options.userActivation); // anchor: apple-user-gesture (S04)\n const webauthn = options.webauthn ?? browserWebAuthnClient();\n const assertion = await webauthn.get({\n rpId: options.rpId,\n allowCredentials: [],\n challenge: options.challenge ?? randomBytes(32),\n });\n const accounts = await options.indexer.resolveByCredential(assertion.id);\n return accounts.map((account) => ({\n contractId: account.contractId,\n credentialId: assertion.id,\n }));\n}\n","import { p256 } from '@noble/curves/nist';\nimport { KitError } from '../errors';\n\n/** Maximum DER length of a P-256 ECDSA signature: SEQ + two 33-byte INTEGERs. */\nconst MAX_DER_LENGTH = 72;\n\n/**\n * Convert an ASN.1 DER ECDSA signature to the 64-byte raw `R‖S` form Soroban's\n * `secp256r1_verify` expects, using noble's audited DER parser (R and S are\n * left-padded to 32 bytes big-endian). Rejects malformed or over-long input.\n *\n * Note: this does NOT enforce low-S — that normalization is added in S04\n * (YK-430). The output here mirrors the signature exactly as parsed.\n */\nexport function derToCompact(der: Uint8Array): Uint8Array {\n if (der.length > MAX_DER_LENGTH) {\n throw new KitError(\n 'INVALID_SIGNATURE_DER',\n `DER signature is ${der.length} bytes, exceeds max ${MAX_DER_LENGTH}`,\n );\n }\n try {\n return p256.Signature.fromDER(der).toCompactRawBytes();\n } catch (cause) {\n throw new KitError('INVALID_SIGNATURE_DER', 'failed to parse DER signature', { cause });\n }\n}\n\nfunction assertCompactLength(compactSignature: Uint8Array): void {\n if (compactSignature.length !== 64) {\n throw new KitError(\n 'INVALID_SIGNATURE_DER',\n `compact signature must be 64 bytes, got ${compactSignature.length}`,\n );\n }\n}\n\n/** True if a 64-byte compact signature is in canonical low-S form (S ≤ n/2). */\nexport function isLowS(compactSignature: Uint8Array): boolean {\n assertCompactLength(compactSignature);\n return !p256.Signature.fromCompact(compactSignature).hasHighS();\n}\n\n/**\n * Normalize a 64-byte compact signature to canonical low-S: if S > n/2, replace\n * S with n − S (anchor LOW_S_NORMALIZATION, invariant #2). ~50% of Apple Touch\n * ID / Face ID assertions are high-S, and Soroban's `secp256r1_verify` REJECTS a\n * high-S signature at decode, so the SDK MUST emit low-S or roughly half of real\n * assertions would fail on-chain. Low-S is a validity requirement here, not just\n * malleability hygiene. Idempotent: low-S input is returned unchanged.\n */\nexport function normalizeLowS(compactSignature: Uint8Array): Uint8Array {\n assertCompactLength(compactSignature);\n return p256.Signature.fromCompact(compactSignature).normalizeS().toCompactRawBytes();\n}\n\n/** DER → 64-byte canonical low-S compact — the conversion the signing ceremony uses. */\nexport function derToCompactLowS(der: Uint8Array): Uint8Array {\n return normalizeLowS(derToCompact(der));\n}\n","import { KitError } from '../errors';\nimport { base64UrlToBytes, bytesToBase64Url, bytesToUtf8 } from '../internal/encoding';\n\n/** The subset of clientDataJSON fields we rely on. */\nexport interface ClientData {\n type: string;\n /** base64url-encoded challenge as embedded by the client. */\n challenge: string;\n origin: string;\n crossOrigin?: boolean;\n}\n\n/** Encode a raw challenge as the base64url string embedded in clientDataJSON. */\nexport function encodeChallenge(challenge: Uint8Array): string {\n return bytesToBase64Url(challenge);\n}\n\n/** Decode the base64url challenge embedded in clientDataJSON back to bytes. */\nexport function decodeChallenge(challenge: string): Uint8Array {\n return base64UrlToBytes(challenge);\n}\n\n/** Parse clientDataJSON bytes into a typed, validated-shape object. */\nexport function parseClientDataJSON(clientDataJSON: Uint8Array): ClientData {\n let raw: unknown;\n try {\n raw = JSON.parse(bytesToUtf8(clientDataJSON));\n } catch (cause) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is not valid JSON', { cause });\n }\n if (typeof raw !== 'object' || raw === null) {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is not a JSON object');\n }\n const obj = raw as Record<string, unknown>;\n const { type, challenge, origin, crossOrigin } = obj;\n if (typeof type !== 'string' || typeof challenge !== 'string' || typeof origin !== 'string') {\n throw new KitError('UNSUPPORTED_AUTHENTICATOR', 'clientDataJSON is missing required fields');\n }\n return {\n type,\n challenge,\n origin,\n crossOrigin: typeof crossOrigin === 'boolean' ? crossOrigin : undefined,\n };\n}\n\n/**\n * Parse and verify clientDataJSON for an authentication (`webauthn.get`)\n * assertion: the ceremony type, the origin (exact match against one or more\n * allowed origins), and the embedded challenge (base64url string).\n */\nexport function verifyClientDataJSON(\n clientDataJSON: Uint8Array,\n expected: { origin: string | string[]; challenge: string },\n): ClientData {\n const data = parseClientDataJSON(clientDataJSON);\n if (data.type !== 'webauthn.get') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `clientDataJSON.type \"${data.type}\" is not \"webauthn.get\"`,\n );\n }\n const allowed = Array.isArray(expected.origin) ? expected.origin : [expected.origin];\n if (!allowed.includes(data.origin)) {\n throw new KitError('ORIGIN_MISMATCH', `origin \"${data.origin}\" not in [${allowed.join(', ')}]`);\n }\n if (data.challenge !== expected.challenge) {\n throw new KitError('CHALLENGE_MISMATCH', 'clientDataJSON challenge does not match expected');\n }\n return data;\n}\n","import { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\n\n/**\n * Reconstruct the 32-byte payload the authenticator signed and that Soroban's\n * `__check_auth` re-derives on-chain:\n *\n * SHA256( authenticatorData ‖ SHA256(clientDataJSON) )\n */\nexport function reconstructSignedPayload(input: {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n}): Uint8Array {\n const clientDataHash = sha256(input.clientDataJSON);\n return sha256(concatBytes(input.authenticatorData, clientDataHash));\n}\n","import { p256 } from '@noble/curves/nist';\nimport { reconstructSignedPayload } from './payload';\nimport { derToCompact } from './signature';\n\nexport interface VerifyAssertionInput {\n /** SEC-1 uncompressed public key (65 bytes, `0x04 ‖ X ‖ Y`). */\n publicKey: Uint8Array;\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n /** DER-encoded (≤72 B) or already-compact (64 B) signature. */\n signature: Uint8Array;\n}\n\n/**\n * Verify a WebAuthn assertion the way the on-chain `secp256r1_verify` does:\n * reconstruct `SHA256(authData ‖ SHA256(cdj))` and check ECDSA. `lowS: false`\n * mirrors the host function, which does NOT enforce low-S (we normalize\n * separately before submitting — see S04/YK-430).\n */\nexport function verifyAssertionSignature(input: VerifyAssertionInput): boolean {\n const payload = reconstructSignedPayload(input);\n const compact = input.signature.length === 64 ? input.signature : derToCompact(input.signature);\n // `format: 'compact'` pins the 64-byte interpretation — without it noble tries\n // DER-first and could misread a compact signature that happens to start 0x30.\n return p256.verify(compact, payload, input.publicKey, { lowS: false, format: 'compact' });\n}\n","import { xdr, hash } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\n\n/**\n * Compute the auth-entry preimage hash that `__check_auth` reconstructs and that\n * becomes the WebAuthn `challenge`:\n * SHA256( XDR( HashIdPreimage::SorobanAuthorization{ networkId, nonce,\n * signatureExpirationLedger, invocation } ) )\n * where networkId = SHA256(networkPassphrase).\n */\nexport function authEntryChallengeBytes(\n entry: xdr.SorobanAuthorizationEntry,\n networkPassphrase: string,\n): Uint8Array {\n const credentials = entry.credentials();\n if (credentials.switch().name !== 'sorobanCredentialsAddress') {\n throw new KitError('CONTRACT_AUTH_FAILED', 'auth entry has no address credentials to sign');\n }\n const address = credentials.address();\n const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(\n new xdr.HashIdPreimageSorobanAuthorization({\n networkId: Buffer.from(hash(Buffer.from(utf8ToBytes(networkPassphrase)))),\n nonce: address.nonce(),\n signatureExpirationLedger: address.signatureExpirationLedger(),\n invocation: entry.rootInvocation(),\n }),\n );\n return new Uint8Array(hash(preimage.toXDR()));\n}\n\n/** The base64url challenge string the authenticator signs (43 chars). */\nexport function authEntryChallenge(\n entry: xdr.SorobanAuthorizationEntry,\n networkPassphrase: string,\n): string {\n return bytesToBase64Url(authEntryChallengeBytes(entry, networkPassphrase));\n}\n","import { xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport type { AssertionResult } from './sign';\n\n/**\n * Set an address-credential auth entry's signature to the `Secp256r1Signature`\n * struct our v0.2 `webauthn-account` `__check_auth` consumes:\n *\n * ScVal::Map {\n * authenticator_data: Bytes,\n * client_data_json: Bytes,\n * public_key: BytesN<65>, // the enrolled signer to verify against\n * signature: BytesN<64>,\n * }\n *\n * Map keys are alphabetical, so the ScMap is canonically sorted as Soroban\n * requires. `signature` MUST already be 64-byte low-S compact (`signAuthEntry`\n * normalizes before calling this). `publicKey` names which enrolled signer the\n * contract checks; the multi-signer account rejects a key it does not hold\n * before any crypto runs.\n */\nexport function applyAssertionToEntry(\n entry: xdr.SorobanAuthorizationEntry,\n assertion: AssertionResult,\n publicKey: Uint8Array,\n): xdr.SorobanAuthorizationEntry {\n entry.credentials().address().signature(buildSingleSignerSignatureScVal(assertion, publicKey));\n return entry;\n}\n\n/** The v0.2 single-signer `Secp256r1Signature` ScVal (4 fields, sorted ScMap). */\nexport function buildSingleSignerSignatureScVal(\n assertion: AssertionResult,\n publicKey: Uint8Array,\n): xdr.ScVal {\n if (publicKey.length !== 65) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n `single-signer signature needs a 65-byte SEC-1 public key (got ${String(publicKey.length)})`,\n );\n }\n return xdr.ScVal.scvMap([\n bytesField('authenticator_data', assertion.authenticatorData),\n bytesField('client_data_json', assertion.clientDataJSON),\n bytesField('public_key', publicKey),\n bytesField('signature', assertion.signature),\n ]);\n}\n\n/**\n * The 3-field `Secp256r1Signature` ScVal that passkey-kit v1's smart-wallet\n * consumes ({ authenticator_data, client_data_json, signature }): that contract\n * resolves the public key from its own `SignerKey -> public key` storage, so the\n * key is NOT inlined here. Kept separate from the single-signer struct above so\n * the two ABIs never drift into each other.\n */\nexport function buildSignatureScVal(assertion: AssertionResult): xdr.ScVal {\n return xdr.ScVal.scvMap([\n bytesField('authenticator_data', assertion.authenticatorData),\n bytesField('client_data_json', assertion.clientDataJSON),\n bytesField('signature', assertion.signature),\n ]);\n}\n\nfunction bytesField(name: string, bytes: Uint8Array): xdr.ScMapEntry {\n return new xdr.ScMapEntry({\n key: xdr.ScVal.scvSymbol(name),\n val: xdr.ScVal.scvBytes(Buffer.from(bytes)),\n });\n}\n","import { xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { buildSignatureScVal } from './assemble';\nimport type { AssertionResult } from './sign';\n\n/**\n * The passkey-kit / `webauthn-wallet` smart-wallet ABI target.\n *\n * Our own single-signer account declares `type Signature = Secp256r1Signature`\n * and consumes the bare struct (see `assemble.ts`). passkey-kit's smart-wallet\n * declares `type Signature = Signatures`, so authorizing it needs the assertion\n * wrapped as `Signatures(Map<SignerKey, Signature>)`. The exact shape, the raw-\n * credential-id key, and the canonical map ordering below are confirmed by\n * kalepail (passkey-kit author) in issue #32 against v1 / v0.13.0 (Protocol 27,\n * independently audited); the wire shape is unchanged from v0.12.\n */\n\n/**\n * `SignerKey::Secp256r1(Bytes)` → `scvVec([Symbol(\"Secp256r1\"), Bytes(rawId)])`.\n * The key is the RAW WebAuthn credential-id bytes (base64url-decoded `rawId`):\n * never hashed, never the UTF-8 of the base64url string, and never the public\n * key — the SEC-1 public key lives in `SignerVal` on-chain, not in the key.\n */\nexport function buildSignerKeyScVal(credentialId: Uint8Array): xdr.ScVal {\n return xdr.ScVal.scvVec([\n xdr.ScVal.scvSymbol('Secp256r1'),\n xdr.ScVal.scvBytes(Buffer.from(credentialId)),\n ]);\n}\n\n/** `Signature::Secp256r1(Secp256r1Signature)` → `scvVec([Symbol(\"Secp256r1\"), <bare struct map>])`. */\nexport function buildSmartWalletSignatureVariant(assertion: AssertionResult): xdr.ScVal {\n return xdr.ScVal.scvVec([xdr.ScVal.scvSymbol('Secp256r1'), buildSignatureScVal(assertion)]);\n}\n\nfunction decomposeSignerKey(key: xdr.ScVal): { variant: string; payload: Uint8Array } {\n const vec = key.vec();\n if (!vec || vec.length < 2) {\n throw new KitError('CONTRACT_AUTH_FAILED', 'malformed SignerKey (expected an enum vec)');\n }\n const variant = vec[0]!.sym().toString();\n const el = vec[1]!;\n // Secp256r1(Bytes) and Ed25519(BytesN<32>) are scvBytes; Policy(Address) falls\n // back to its XDR bytes (rare in a passkey SDK — see the ordering note below).\n const payload =\n el.switch().name === 'scvBytes' ? new Uint8Array(el.bytes()) : new Uint8Array(el.toXDR());\n return { variant, payload };\n}\n\nfunction compareBytes(a: Uint8Array, b: Uint8Array): number {\n const n = Math.min(a.length, b.length);\n for (let i = 0; i < n; i++) {\n if (a[i] !== b[i]) return a[i]! < b[i]! ? -1 : 1;\n }\n return a.length - b.length;\n}\n\n/**\n * Canonical Soroban-host ordering for `SignerKey` map keys. The host requires\n * `Map<SignerKey, _>` entries sorted by ScVal `Ord` — an **element-wise byte\n * comparison**, NOT a length-major XDR-hex / `localeCompare` string sort. This is\n * the one correctness landmine kalepail flagged in #32: passkey-kit v1 replaced\n * its old string sort with exactly this because the old approach could mis-order\n * same-variant keys of differing length, producing a map the host rejects.\n *\n * We compare the enum variant symbol first, then the payload bytes element-wise,\n * so homogeneous `Secp256r1` keys (the multi-passkey case) sort purely by their\n * raw credential-id bytes. (Ordering across mixed variant types relies on the\n * variant names being capitalized single words, which matches the host's symbol\n * order; a Policy/Address-keyed multi-sig is out of scope for this passkey SDK.)\n */\nexport function compareSignerKeyScVal(a: xdr.ScVal, b: xdr.ScVal): number {\n const ka = decomposeSignerKey(a);\n const kb = decomposeSignerKey(b);\n if (ka.variant !== kb.variant) return ka.variant < kb.variant ? -1 : 1;\n return compareBytes(ka.payload, kb.payload);\n}\n\n/**\n * Assemble/merge a passkey assertion into an address-credential auth entry as the\n * smart-wallet `Signatures(Map<SignerKey, Signature>)` wire shape\n * (`ScVal::Vec([ScVal::Map(...)])`). `assertion.signature` MUST already be 64-byte\n * low-S compact (`signAuthEntry` normalizes first). Existing map entries — a\n * partially-signed multi-sig entry — are preserved; an entry for the same signer\n * key is replaced; then the whole map is canonically sorted.\n *\n * Use this for the passkey-kit / webauthn-wallet ABI. For our own single-signer\n * account (`type Signature = Secp256r1Signature`) use `applyAssertionToEntry`.\n */\nexport function applyAssertionToSmartWalletEntry(\n entry: xdr.SorobanAuthorizationEntry,\n assertion: AssertionResult,\n): xdr.SorobanAuthorizationEntry {\n const credentials = entry.credentials();\n if (credentials.switch().name !== 'sorobanCredentialsAddress') {\n throw new KitError('CONTRACT_AUTH_FAILED', 'auth entry has no address credentials to sign');\n }\n const key = buildSignerKeyScVal(assertion.credentialId);\n const newEntry = new xdr.ScMapEntry({ key, val: buildSmartWalletSignatureVariant(assertion) });\n\n const current = credentials.address().signature();\n let mapEntries: xdr.ScMapEntry[];\n switch (current.switch().name) {\n case 'scvVoid':\n mapEntries = [newEntry];\n break;\n case 'scvVec': {\n // Preserve any existing signatures (partial multi-sig); replace same key.\n const existing = current.vec()?.[0]?.map() ?? [];\n mapEntries = existing.filter((e) => compareSignerKeyScVal(e.key(), key) !== 0);\n mapEntries.push(newEntry);\n break;\n }\n default:\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'unexpected existing signature shape for a smart-wallet entry',\n );\n }\n mapEntries.sort((a, b) => compareSignerKeyScVal(a.key(), b.key()));\n credentials.address().signature(xdr.ScVal.scvVec([xdr.ScVal.scvMap(mapEntries)]));\n return entry;\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\nimport { KitError } from '../errors';\nimport { derToCompactLowS, normalizeLowS } from '../webauthn/signature';\nimport { parseClientDataJSON, verifyClientDataJSON, type ClientData } from '../webauthn/clientData';\nimport { parseAuthenticatorData, verifyRpIdHash } from '../webauthn/authData';\nimport { verifyAssertionSignature } from '../webauthn/verify';\nimport { authEntryChallenge } from './preimage';\nimport { applyAssertionToEntry } from './assemble';\nimport { applyAssertionToSmartWalletEntry } from './smartWallet';\n\n/**\n * Which contract ABI the assembled signature targets:\n * - `single-signer` (default): the bare `Secp256r1Signature` struct our own\n * webauthn-account consumes (`type Signature = Secp256r1Signature`).\n * - `smart-wallet`: passkey-kit's `Signatures(Map<SignerKey, Signature>)`\n * (`type Signature = Signatures`) — see `smartWallet.ts` / kalepail #32.\n * Both reuse the identical low-S, field-packing, and challenge-binding core;\n * only the outer wrapper differs, so the two stay separate ABI targets behind\n * one signing interface.\n */\nexport type WalletTarget = 'single-signer' | 'smart-wallet';\n\n/** The raw WebAuthn assertion a signer returns for a given challenge. */\nexport interface AssertionResult {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n /** DER-encoded (≤72B) or already-compact (64B) ECDSA signature. */\n signature: Uint8Array;\n /** base64url credential id → the SignerKey. */\n credentialId: Uint8Array;\n /**\n * SEC-1 (65-byte) public key of the signing passkey. The v0.2 single-signer\n * account verifies against this exact key, so the signer must supply it here\n * (or the caller passes it via `SorobanSignOptions.publicKey`). Not used by\n * the smart-wallet target, which resolves the key on-chain by credential id.\n */\n publicKey?: Uint8Array;\n}\n\n/** Produce a WebAuthn assertion over the base64url `challenge` (e.g. navigator.credentials.get). */\nexport type WebAuthnSigner = (challenge: string) => Promise<AssertionResult> | AssertionResult;\n\n/**\n * Opt-in pre-flight validation of the returned assertion, run BEFORE the entry\n * is assembled and submitted. On-chain `__check_auth` is the real gate, but\n * catching these client-side turns an opaque on-chain failure into a typed\n * `KitError` at the call site. Providing this object always enforces the\n * `webauthn.get` type, the User-Present (UP) flag (required by passkey-kit v1),\n * and challenge-binding; `rpId` / `origin` / `publicKey` add their checks when\n * supplied. Omit the object entirely to skip pre-flight (the default).\n */\nexport interface SignVerifyOptions {\n /** Verify `authenticatorData.rpIdHash === SHA-256(rpId)`. */\n rpId?: string;\n /** Verify `clientDataJSON.origin` is one of these exact origins. */\n origin?: string | string[];\n /** SEC-1 (65-byte) public key → verify the ECDSA assertion signature. */\n publicKey?: Uint8Array;\n /** Also require the User-Verified (UV) flag (biometric / PIN). Default false. */\n requireUserVerification?: boolean;\n /** Allow an assertion made in a cross-origin context (crossOrigin=true). Default false. */\n allowCrossOrigin?: boolean;\n}\n\nexport interface SorobanSignOptions {\n networkPassphrase: string;\n sign: WebAuthnSigner;\n /**\n * Restrict `signTransaction` to auth entries whose credential address equals this\n * C-address. When set, only the connected account's entries are signed and any other\n * authorizer's entries are left untouched, so the passkey never signs on behalf of, or\n * prompts for, accounts that are not the signer. Omit to sign every address-credential\n * entry.\n */\n signerAddress?: string;\n /**\n * SEC-1 (65-byte) public key of the signing passkey, for the `single-signer`\n * target: the v0.2 `webauthn-account` carries the signer's key inline and\n * verifies against it. Takes precedence over any `publicKey` the signer\n * returns on its `AssertionResult`. Required for `single-signer` when the\n * signer does not return one; ignored by the `smart-wallet` target.\n */\n publicKey?: Uint8Array;\n /** Contract ABI to assemble for. Defaults to `single-signer` (our account). */\n target?: WalletTarget;\n /** Opt-in pre-flight assertion validation. Omit to skip. */\n verify?: SignVerifyOptions;\n /**\n * Stamp this `signatureExpirationLedger` onto every address-credential auth\n * entry BEFORE the challenge is computed, so the signature binds the exact\n * expiration the contract re-derives in `__check_auth`. Needed for smart-wallet\n * writes (add/remove signer) where the caller learns the ledger at sign time;\n * omit when the entry already carries the intended expiration.\n */\n signatureExpirationLedger?: number;\n}\n\n/** Validate an assertion against the expected challenge + RP context. Throws KitError. */\nfunction preflightAssertion(\n assertion: AssertionResult,\n challenge: string,\n verify: SignVerifyOptions,\n): void {\n // Ceremony type + challenge-binding (+ origin when provided).\n let clientData: ClientData;\n if (verify.origin !== undefined) {\n clientData = verifyClientDataJSON(assertion.clientDataJSON, {\n origin: verify.origin,\n challenge,\n });\n } else {\n clientData = parseClientDataJSON(assertion.clientDataJSON);\n if (clientData.type !== 'webauthn.get') {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n `clientDataJSON.type \"${clientData.type}\" is not \"webauthn.get\"`,\n );\n }\n if (clientData.challenge !== challenge) {\n throw new KitError('CHALLENGE_MISMATCH', 'assertion challenge does not match the auth entry');\n }\n }\n if (clientData.crossOrigin === true && !verify.allowCrossOrigin) {\n throw new KitError(\n 'ORIGIN_MISMATCH',\n 'assertion was made in a cross-origin context (crossOrigin=true)',\n );\n }\n // User-Present is mandatory (passkey-kit v1 hardening); UV is opt-in.\n const parsed = parseAuthenticatorData(assertion.authenticatorData);\n if (!parsed.flags.up) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'assertion is missing the User-Present (UP) flag',\n );\n }\n if (verify.requireUserVerification && !parsed.flags.uv) {\n throw new KitError(\n 'UNSUPPORTED_AUTHENTICATOR',\n 'assertion is missing the required User-Verified (UV) flag',\n );\n }\n if (verify.rpId !== undefined) {\n verifyRpIdHash(assertion.authenticatorData, verify.rpId);\n }\n if (verify.publicKey !== undefined) {\n const ok = verifyAssertionSignature({\n publicKey: verify.publicKey,\n authenticatorData: assertion.authenticatorData,\n clientDataJSON: assertion.clientDataJSON,\n signature: assertion.signature,\n });\n if (!ok) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'assertion signature failed pre-flight verification',\n );\n }\n }\n}\n\nasync function signEntryInPlace(\n entry: xdr.SorobanAuthorizationEntry,\n options: SorobanSignOptions,\n): Promise<void> {\n // Stamp the expiration first: the challenge preimage includes\n // signatureExpirationLedger, so it must be final before we compute it.\n if (options.signatureExpirationLedger !== undefined) {\n const creds = entry.credentials();\n if (creds.switch().name === 'sorobanCredentialsAddress') {\n creds.address().signatureExpirationLedger(options.signatureExpirationLedger);\n }\n }\n const challenge = authEntryChallenge(entry, options.networkPassphrase);\n const assertion = await options.sign(challenge);\n if (options.verify) preflightAssertion(assertion, challenge, options.verify);\n // Always low-S normalize (invariant #2), on BOTH branches: an already-compact\n // 64-byte signature from a custom signer can still be high-S, which the on-chain\n // secp256r1 verifier rejects.\n const signature =\n assertion.signature.length === 64\n ? normalizeLowS(assertion.signature)\n : derToCompactLowS(assertion.signature);\n const normalized = {\n credentialId: assertion.credentialId,\n authenticatorData: assertion.authenticatorData,\n clientDataJSON: assertion.clientDataJSON,\n signature,\n };\n if (options.target === 'smart-wallet') {\n applyAssertionToSmartWalletEntry(entry, normalized);\n } else {\n const publicKey = options.publicKey ?? assertion.publicKey;\n if (publicKey === undefined) {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'single-signer signing requires the signer public key: set SorobanSignOptions.publicKey or return publicKey from the signer',\n );\n }\n applyAssertionToEntry(entry, normalized, publicKey);\n }\n}\n\n/**\n * Sign a single `SorobanAuthorizationEntry` (base64 XDR): compute the challenge,\n * obtain a WebAuthn assertion, low-S-normalize, and assemble the contract\n * signature. Returns the signed entry as base64 XDR.\n */\nexport async function signAuthEntry(\n entryXdr: string,\n options: SorobanSignOptions,\n): Promise<string> {\n const entry = xdr.SorobanAuthorizationEntry.fromXDR(entryXdr, 'base64');\n await signEntryInPlace(entry, options);\n return entry.toXDR('base64');\n}\n\n/**\n * The operations whose Soroban auth entries we sign, for a v1 or a fee-bump\n * envelope. (Sign the Soroban auth entries before adding classic tx signatures\n * or fee-bumping; a fee-bump around an already-classic-signed inner tx is the\n * caller's sequencing concern.)\n */\nfunction operationsForSigning(envelope: xdr.TransactionEnvelope): xdr.Operation[] {\n const kind = envelope.switch().name;\n if (kind === 'envelopeTypeTx') return envelope.v1().tx().operations();\n if (kind === 'envelopeTypeTxFeeBump') {\n const inner = envelope.feeBump().tx().innerTx();\n if (inner.switch().name !== 'envelopeTypeTx') {\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n 'signTransaction: fee-bump inner transaction is not a v1 transaction',\n );\n }\n return inner.v1().tx().operations();\n }\n throw new KitError(\n 'CONTRACT_AUTH_FAILED',\n `signTransaction: unsupported envelope type \"${kind}\" (expected v1 or fee-bump)`,\n );\n}\n\n/**\n * Sign every address-credential Soroban auth entry carried by the InvokeHostFunction\n * operations of a transaction (base64 XDR envelope — v1 or fee-bump). Returns the\n * signed envelope XDR.\n */\nexport async function signTransaction(txXdr: string, options: SorobanSignOptions): Promise<string> {\n const envelope = xdr.TransactionEnvelope.fromXDR(txXdr, 'base64');\n for (const op of operationsForSigning(envelope)) {\n if (op.body().switch().name !== 'invokeHostFunction') continue;\n const entries = op.body().invokeHostFunctionOp().auth();\n for (const entry of entries) {\n if (entry.credentials().switch().name !== 'sorobanCredentialsAddress') continue;\n if (\n options.signerAddress !== undefined &&\n Address.fromScAddress(entry.credentials().address().address()).toString() !==\n options.signerAddress\n ) {\n continue;\n }\n await signEntryInPlace(entry, options);\n }\n }\n return envelope.toXDR('base64');\n}\n","import type { CborValue } from './cbor';\nimport { utf8ToBytes } from './encoding';\n\n/**\n * Minimal CBOR encoder — the inverse of `cbor.ts`, supporting the same major\n * types (uint, negint, byte string, text string, array, map). Used by the\n * deterministic mock authenticator (S15) to synthesize real attestationObject /\n * COSE-key bytes, so the mock create path goes through the exact same\n * `extractPublicKeyFromAttestationObject` as production. Not canonical-ordered\n * (our decoder is order-agnostic) and intentionally narrow.\n */\nfunction head(major: number, arg: number): number[] {\n const m = major << 5;\n if (arg < 24) return [m | arg];\n if (arg < 0x100) return [m | 24, arg];\n if (arg < 0x10000) return [m | 25, (arg >> 8) & 0xff, arg & 0xff];\n return [m | 26, (arg >>> 24) & 0xff, (arg >> 16) & 0xff, (arg >> 8) & 0xff, arg & 0xff];\n}\n\nfunction write(value: CborValue, out: number[]): void {\n if (typeof value === 'number' && Number.isInteger(value)) {\n if (value >= 0) out.push(...head(0, value));\n else out.push(...head(1, -1 - value));\n } else if (value instanceof Uint8Array) {\n out.push(...head(2, value.length));\n for (const b of value) out.push(b);\n } else if (typeof value === 'string') {\n const bytes = utf8ToBytes(value);\n out.push(...head(3, bytes.length));\n for (const b of bytes) out.push(b);\n } else if (Array.isArray(value)) {\n out.push(...head(4, value.length));\n for (const item of value) write(item, out);\n } else if (value instanceof Map) {\n out.push(...head(5, value.size));\n for (const [k, v] of value) {\n write(k, out);\n write(v, out);\n }\n } else {\n throw new Error('CBOR encode: unsupported value');\n }\n}\n\nexport function encodeCbor(value: CborValue): Uint8Array {\n const out: number[] = [];\n write(value, out);\n return Uint8Array.from(out);\n}\n","import { p256 } from '@noble/curves/nist';\nimport { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\nimport { encodeCbor } from '../internal/cborEncode';\nimport type { CborValue } from '../internal/cbor';\nimport type {\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from '../ceremonies/types';\nimport type { AssertionResult } from '../soroban/sign';\n\nexport interface MockAuthenticatorOptions {\n rpId: string;\n origin?: string;\n /** Deterministic seed → keypair + credentialId. */\n seed?: string;\n /** Emit high-S signatures, to exercise the perpetual low-S guard (S04). */\n forceHighS?: boolean;\n}\n\nexport interface MockAuthenticator extends WebAuthnClient {\n readonly publicKey: Uint8Array; // 65-byte SEC-1\n readonly credentialId: string; // base64url\n readonly privateKey: Uint8Array;\n /** WebAuthnSigner for the Soroban sign path (challenge already base64url). */\n sign(challenge: string): AssertionResult;\n}\n\nfunction deriveScalar(seed: string): Uint8Array {\n const n = p256.CURVE.n;\n let scalar = BigInt('0x' + bytesToHexLocal(sha256(utf8ToBytes('priv:' + seed)))) % n;\n if (scalar === 0n) scalar = 1n;\n const hex = scalar.toString(16).padStart(64, '0');\n return Uint8Array.from((hex.match(/../g) ?? []).map((h) => parseInt(h, 16)));\n}\nfunction bytesToHexLocal(bytes: Uint8Array): string {\n let hex = '';\n for (const b of bytes) hex += b.toString(16).padStart(2, '0');\n return hex;\n}\n\n/**\n * A deterministic, in-memory WebAuthn authenticator for the mock kit (S15). It\n * synthesizes a REAL attestationObject / COSE key (so `createPasskey` runs the\n * exact production extraction path) and signs assertions with the same P-256\n * key — optionally as high-S to prove the low-S normalization guard.\n */\nexport function mockAuthenticator(options: MockAuthenticatorOptions): MockAuthenticator {\n const seed = options.seed ?? 'mock-authenticator';\n const origin = options.origin ?? `https://${options.rpId}`;\n const privateKey = deriveScalar(seed);\n const publicKey = p256.getPublicKey(privateKey, false); // 0x04 ‖ X ‖ Y\n const x = publicKey.slice(1, 33);\n const y = publicKey.slice(33, 65);\n const credIdBytes = sha256(utf8ToBytes('cred:' + seed)).slice(0, 16);\n const credentialId = bytesToBase64Url(credIdBytes);\n const rpIdHash = sha256(utf8ToBytes(options.rpId));\n\n const coseKey = encodeCbor(\n new Map<number | string, CborValue>([\n [1, 2], // kty EC2\n [3, -7], // alg ES256\n [-1, 1], // crv P-256\n [-2, x],\n [-3, y],\n ]),\n );\n\n const attestedAuthData = concatBytes(\n rpIdHash,\n new Uint8Array([0x45]), // UP | UV | AT\n new Uint8Array([0, 0, 0, 0]), // signCount\n new Uint8Array(16), // aaguid\n new Uint8Array([0, credIdBytes.length]),\n credIdBytes,\n coseKey,\n );\n const attestationObject = encodeCbor(\n new Map<number | string, CborValue>([\n ['fmt', 'none'],\n ['attStmt', new Map<number | string, CborValue>()],\n ['authData', attestedAuthData],\n ]),\n );\n\n function signAssertion(challengeB64: string): {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n signatureDer: Uint8Array;\n } {\n const authenticatorData = concatBytes(\n rpIdHash,\n new Uint8Array([0x05]),\n new Uint8Array([0, 0, 0, 1]),\n );\n const clientDataJSON = utf8ToBytes(\n JSON.stringify({ type: 'webauthn.get', challenge: challengeB64, origin }),\n );\n const payload = sha256(concatBytes(authenticatorData, sha256(clientDataJSON)));\n const sig = p256.sign(payload, privateKey); // low-S by default\n const s = options.forceHighS ? p256.CURVE.n - sig.s : sig.s;\n const signatureDer = new p256.Signature(sig.r, s).toDERRawBytes();\n return { authenticatorData, clientDataJSON, signatureDer };\n }\n\n return {\n publicKey,\n credentialId,\n privateKey,\n create(): Promise<WebAuthnCreateResult> {\n return Promise.resolve({ id: credentialId, rawId: credIdBytes, attestationObject });\n },\n get(getOptions: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const challengeB64 = getOptions.challenge ? bytesToBase64Url(getOptions.challenge) : 'mock';\n const a = signAssertion(challengeB64);\n return Promise.resolve({\n id: credentialId,\n rawId: credIdBytes,\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n });\n },\n sign(challenge: string): AssertionResult {\n const a = signAssertion(challenge);\n return {\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n credentialId: credIdBytes,\n publicKey,\n };\n },\n };\n}\n","import { StrKey } from '@stellar/stellar-sdk';\nimport { sha256 } from '../internal/sha256';\nimport { utf8ToBytes } from '../internal/encoding';\nimport type { AccountDeployer } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\n\nexport interface InMemoryBackend {\n deployer: AccountDeployer;\n indexer: IndexerAdapter;\n submission: SubmissionAdapter;\n /** credentialId → { contractId, publicKey } — shared so create/connect/recover agree. */\n registry: Map<string, { contractId: string; publicKey: Uint8Array }>;\n}\n\n/**\n * Deterministic, zero-IO backend for the mock kit: the deployer derives a stable\n * C-address from the credentialId and records it; the indexer resolves from the\n * same registry; submission is a no-op SUCCESS.\n *\n * The address is a real StrKey contract id (checksummed, decodable), so a mock\n * account can be fed straight into `new Address(...)` / auth-entry XDR the same way\n * a deployed one is. It is deterministic but arbitrary: it is not the address the\n * factory would deploy for this credential (that is {@link deriveAccountAddress}).\n */\nexport function createInMemoryBackend(): InMemoryBackend {\n const registry = new Map<string, { contractId: string; publicKey: Uint8Array }>();\n let nonce = 0;\n return {\n registry,\n deployer: {\n deploy({ publicKey, credentialId }) {\n const contractId = StrKey.encodeContract(\n Buffer.from(sha256(utf8ToBytes('account:' + credentialId))),\n );\n registry.set(credentialId, { contractId, publicKey });\n return Promise.resolve({ contractId, txHash: `mock-deploy-${String(nonce++)}` });\n },\n },\n indexer: {\n resolveByCredential(credentialId) {\n const account = registry.get(credentialId);\n // Carry the founding public key the same way the real `eventsIndexer` reads it\n // off the factory `deployed` event, so mock-mode connect/recover can verify\n // enrollment and recover the signing key (no mock/live divergence).\n return Promise.resolve(\n account ? [{ contractId: account.contractId, publicKey: account.publicKey }] : [],\n );\n },\n },\n submission: {\n send: () => Promise.resolve({ status: 'SUCCESS', hash: 'mock-tx' }),\n },\n };\n}\n","import { createPasskey as createPasskeyCeremony } from '../ceremonies/create';\nimport { connect as connectCeremony, type ConnectResult } from '../ceremonies/connect';\nimport { recover as recoverCeremony, type RecoverResult } from '../ceremonies/recover';\nimport { signAuthEntry as signAuthEntryFn, type WebAuthnSigner } from '../soroban/sign';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\nimport type { PasskeyCredential } from '../types';\nimport { mockAuthenticator } from './mockAuthenticator';\nimport { createInMemoryBackend } from './inMemory';\n\nconst TESTNET = 'Test SDF Network ; September 2015';\n\nexport interface CreatePasskeyKitOptions {\n mode: 'mock' | 'live';\n rpId: string;\n rpName?: string;\n networkPassphrase?: string;\n // mock-mode knobs\n seed?: string;\n forceHighS?: boolean;\n // live-mode dependencies\n webauthn?: WebAuthnClient;\n deployer?: AccountDeployer;\n indexer?: IndexerAdapter;\n submission?: SubmissionAdapter;\n storage?: CredentialStorage;\n signer?: WebAuthnSigner;\n}\n\nexport interface PasskeyKit {\n readonly mode: 'mock' | 'live';\n readonly rpId: string;\n createPasskey(input?: { userName?: string }): Promise<PasskeyCredential>;\n connect(): Promise<ConnectResult | null>;\n recover(): Promise<RecoverResult[]>;\n signAuthEntry(entryXdr: string): Promise<string>;\n}\n\nfunction inMemoryStorage(): CredentialStorage {\n const map = new Map<string, string>();\n return { get: (rpId) => map.get(rpId) ?? null, set: (rpId, id) => void map.set(rpId, id) };\n}\n\n/**\n * The downstream-adopter kit (S15, Deliverable #6). `mode:'mock'` wires a\n * deterministic in-memory authenticator + backend (zero network IO) so the\n * happy path matches the live path's SHAPE — swap `mock → live` and the demo\n * stays green. `mode:'live'` takes real adapters + a WebAuthn signer.\n */\nexport function createPasskeyKit(options: CreatePasskeyKitOptions): PasskeyKit {\n const networkPassphrase = options.networkPassphrase ?? TESTNET;\n const rpName = options.rpName ?? options.rpId;\n\n let webauthn: WebAuthnClient;\n let deployer: AccountDeployer;\n let indexer: IndexerAdapter;\n let storage: CredentialStorage;\n let signer: WebAuthnSigner;\n\n if (options.mode === 'mock') {\n const auth = mockAuthenticator({\n rpId: options.rpId,\n seed: options.seed,\n forceHighS: options.forceHighS,\n });\n const backend = createInMemoryBackend();\n webauthn = auth;\n deployer = backend.deployer;\n indexer = backend.indexer;\n signer = auth.sign;\n storage = inMemoryStorage();\n } else {\n if (!options.webauthn || !options.deployer || !options.indexer || !options.signer) {\n throw new Error('live mode requires webauthn, deployer, indexer and signer');\n }\n webauthn = options.webauthn;\n deployer = options.deployer;\n indexer = options.indexer;\n signer = options.signer;\n storage = options.storage ?? inMemoryStorage();\n }\n\n return {\n mode: options.mode,\n rpId: options.rpId,\n createPasskey: (input) =>\n createPasskeyCeremony({\n rpId: options.rpId,\n rpName,\n userName: input?.userName ?? 'user',\n deployer,\n webauthn,\n storage,\n }),\n connect: () =>\n connectCeremony({\n rpId: options.rpId,\n indexer,\n webauthn,\n storage,\n silentMediationSupported: false,\n }),\n recover: () => recoverCeremony({ rpId: options.rpId, indexer, webauthn }),\n signAuthEntry: (entryXdr) => signAuthEntryFn(entryXdr, { networkPassphrase, sign: signer }),\n };\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\n\n/**\n * A ready-to-sign `SorobanAuthorizationEntry` (base64 XDR) for a demo call on\n * `contractId`. A convenience for smoke tests and examples, so you do not hand-\n * build auth-entry XDR just to have something to sign. The nonce and expiration\n * are fixed placeholders, so this is for local verification, not production.\n *\n * Requires `@stellar/stellar-sdk >=12 <17` (the package's peer range): version 17\n * reworked the XDR API this builds against.\n */\nexport function sampleAuthEntry(contractId: string, functionName = 'protected'): string {\n const address = new Address(contractId).toScAddress();\n const entry = new xdr.SorobanAuthorizationEntry({\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(\n new xdr.SorobanAddressCredentials({\n address,\n nonce: new xdr.Int64(1),\n signatureExpirationLedger: 1000,\n signature: xdr.ScVal.scvVoid(),\n }),\n ),\n rootInvocation: new xdr.SorobanAuthorizedInvocation({\n function: xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(\n new xdr.InvokeContractArgs({ contractAddress: address, functionName, args: [] }),\n ),\n subInvocations: [],\n }),\n });\n return entry.toXDR('base64');\n}\n"]}
@@ -88,6 +88,9 @@ declare function createInMemoryBackend(): InMemoryBackend;
88
88
  * `contractId`. A convenience for smoke tests and examples, so you do not hand-
89
89
  * build auth-entry XDR just to have something to sign. The nonce and expiration
90
90
  * are fixed placeholders, so this is for local verification, not production.
91
+ *
92
+ * Requires `@stellar/stellar-sdk >=12 <17` (the package's peer range): version 17
93
+ * reworked the XDR API this builds against.
91
94
  */
92
95
  declare function sampleAuthEntry(contractId: string, functionName?: string): string;
93
96
 
package/dist/testing.d.ts CHANGED
@@ -88,6 +88,9 @@ declare function createInMemoryBackend(): InMemoryBackend;
88
88
  * `contractId`. A convenience for smoke tests and examples, so you do not hand-
89
89
  * build auth-entry XDR just to have something to sign. The nonce and expiration
90
90
  * are fixed placeholders, so this is for local verification, not production.
91
+ *
92
+ * Requires `@stellar/stellar-sdk >=12 <17` (the package's peer range): version 17
93
+ * reworked the XDR API this builds against.
91
94
  */
92
95
  declare function sampleAuthEntry(contractId: string, functionName?: string): string;
93
96
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/cborEncode.ts","../src/testing/mockAuthenticator.ts","../src/testing/inMemory.ts","../src/testing/kit.ts","../src/testing/sampleAuthEntry.ts"],"names":[],"mappings":"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","file":"testing.js","sourcesContent":["import type { CborValue } from './cbor';\nimport { utf8ToBytes } from './encoding';\n\n/**\n * Minimal CBOR encoder — the inverse of `cbor.ts`, supporting the same major\n * types (uint, negint, byte string, text string, array, map). Used by the\n * deterministic mock authenticator (S15) to synthesize real attestationObject /\n * COSE-key bytes, so the mock create path goes through the exact same\n * `extractPublicKeyFromAttestationObject` as production. Not canonical-ordered\n * (our decoder is order-agnostic) and intentionally narrow.\n */\nfunction head(major: number, arg: number): number[] {\n const m = major << 5;\n if (arg < 24) return [m | arg];\n if (arg < 0x100) return [m | 24, arg];\n if (arg < 0x10000) return [m | 25, (arg >> 8) & 0xff, arg & 0xff];\n return [m | 26, (arg >>> 24) & 0xff, (arg >> 16) & 0xff, (arg >> 8) & 0xff, arg & 0xff];\n}\n\nfunction write(value: CborValue, out: number[]): void {\n if (typeof value === 'number' && Number.isInteger(value)) {\n if (value >= 0) out.push(...head(0, value));\n else out.push(...head(1, -1 - value));\n } else if (value instanceof Uint8Array) {\n out.push(...head(2, value.length));\n for (const b of value) out.push(b);\n } else if (typeof value === 'string') {\n const bytes = utf8ToBytes(value);\n out.push(...head(3, bytes.length));\n for (const b of bytes) out.push(b);\n } else if (Array.isArray(value)) {\n out.push(...head(4, value.length));\n for (const item of value) write(item, out);\n } else if (value instanceof Map) {\n out.push(...head(5, value.size));\n for (const [k, v] of value) {\n write(k, out);\n write(v, out);\n }\n } else {\n throw new Error('CBOR encode: unsupported value');\n }\n}\n\nexport function encodeCbor(value: CborValue): Uint8Array {\n const out: number[] = [];\n write(value, out);\n return Uint8Array.from(out);\n}\n","import { p256 } from '@noble/curves/nist';\nimport { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\nimport { encodeCbor } from '../internal/cborEncode';\nimport type { CborValue } from '../internal/cbor';\nimport type {\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from '../ceremonies/types';\nimport type { AssertionResult } from '../soroban/sign';\n\nexport interface MockAuthenticatorOptions {\n rpId: string;\n origin?: string;\n /** Deterministic seed → keypair + credentialId. */\n seed?: string;\n /** Emit high-S signatures, to exercise the perpetual low-S guard (S04). */\n forceHighS?: boolean;\n}\n\nexport interface MockAuthenticator extends WebAuthnClient {\n readonly publicKey: Uint8Array; // 65-byte SEC-1\n readonly credentialId: string; // base64url\n readonly privateKey: Uint8Array;\n /** WebAuthnSigner for the Soroban sign path (challenge already base64url). */\n sign(challenge: string): AssertionResult;\n}\n\nfunction deriveScalar(seed: string): Uint8Array {\n const n = p256.CURVE.n;\n let scalar = BigInt('0x' + bytesToHexLocal(sha256(utf8ToBytes('priv:' + seed)))) % n;\n if (scalar === 0n) scalar = 1n;\n const hex = scalar.toString(16).padStart(64, '0');\n return Uint8Array.from((hex.match(/../g) ?? []).map((h) => parseInt(h, 16)));\n}\nfunction bytesToHexLocal(bytes: Uint8Array): string {\n let hex = '';\n for (const b of bytes) hex += b.toString(16).padStart(2, '0');\n return hex;\n}\n\n/**\n * A deterministic, in-memory WebAuthn authenticator for the mock kit (S15). It\n * synthesizes a REAL attestationObject / COSE key (so `createPasskey` runs the\n * exact production extraction path) and signs assertions with the same P-256\n * key — optionally as high-S to prove the low-S normalization guard.\n */\nexport function mockAuthenticator(options: MockAuthenticatorOptions): MockAuthenticator {\n const seed = options.seed ?? 'mock-authenticator';\n const origin = options.origin ?? `https://${options.rpId}`;\n const privateKey = deriveScalar(seed);\n const publicKey = p256.getPublicKey(privateKey, false); // 0x04 ‖ X ‖ Y\n const x = publicKey.slice(1, 33);\n const y = publicKey.slice(33, 65);\n const credIdBytes = sha256(utf8ToBytes('cred:' + seed)).slice(0, 16);\n const credentialId = bytesToBase64Url(credIdBytes);\n const rpIdHash = sha256(utf8ToBytes(options.rpId));\n\n const coseKey = encodeCbor(\n new Map<number | string, CborValue>([\n [1, 2], // kty EC2\n [3, -7], // alg ES256\n [-1, 1], // crv P-256\n [-2, x],\n [-3, y],\n ]),\n );\n\n const attestedAuthData = concatBytes(\n rpIdHash,\n new Uint8Array([0x45]), // UP | UV | AT\n new Uint8Array([0, 0, 0, 0]), // signCount\n new Uint8Array(16), // aaguid\n new Uint8Array([0, credIdBytes.length]),\n credIdBytes,\n coseKey,\n );\n const attestationObject = encodeCbor(\n new Map<number | string, CborValue>([\n ['fmt', 'none'],\n ['attStmt', new Map<number | string, CborValue>()],\n ['authData', attestedAuthData],\n ]),\n );\n\n function signAssertion(challengeB64: string): {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n signatureDer: Uint8Array;\n } {\n const authenticatorData = concatBytes(\n rpIdHash,\n new Uint8Array([0x05]),\n new Uint8Array([0, 0, 0, 1]),\n );\n const clientDataJSON = utf8ToBytes(\n JSON.stringify({ type: 'webauthn.get', challenge: challengeB64, origin }),\n );\n const payload = sha256(concatBytes(authenticatorData, sha256(clientDataJSON)));\n const sig = p256.sign(payload, privateKey); // low-S by default\n const s = options.forceHighS ? p256.CURVE.n - sig.s : sig.s;\n const signatureDer = new p256.Signature(sig.r, s).toDERRawBytes();\n return { authenticatorData, clientDataJSON, signatureDer };\n }\n\n return {\n publicKey,\n credentialId,\n privateKey,\n create(): Promise<WebAuthnCreateResult> {\n return Promise.resolve({ id: credentialId, rawId: credIdBytes, attestationObject });\n },\n get(getOptions: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const challengeB64 = getOptions.challenge ? bytesToBase64Url(getOptions.challenge) : 'mock';\n const a = signAssertion(challengeB64);\n return Promise.resolve({\n id: credentialId,\n rawId: credIdBytes,\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n });\n },\n sign(challenge: string): AssertionResult {\n const a = signAssertion(challenge);\n return {\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n credentialId: credIdBytes,\n publicKey,\n };\n },\n };\n}\n","import { StrKey } from '@stellar/stellar-sdk';\nimport { sha256 } from '../internal/sha256';\nimport { utf8ToBytes } from '../internal/encoding';\nimport type { AccountDeployer } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\n\nexport interface InMemoryBackend {\n deployer: AccountDeployer;\n indexer: IndexerAdapter;\n submission: SubmissionAdapter;\n /** credentialId → { contractId, publicKey } — shared so create/connect/recover agree. */\n registry: Map<string, { contractId: string; publicKey: Uint8Array }>;\n}\n\n/**\n * Deterministic, zero-IO backend for the mock kit: the deployer derives a stable\n * C-address from the credentialId and records it; the indexer resolves from the\n * same registry; submission is a no-op SUCCESS.\n *\n * The address is a real StrKey contract id (checksummed, decodable), so a mock\n * account can be fed straight into `new Address(...)` / auth-entry XDR the same way\n * a deployed one is. It is deterministic but arbitrary: it is not the address the\n * factory would deploy for this credential (that is {@link deriveAccountAddress}).\n */\nexport function createInMemoryBackend(): InMemoryBackend {\n const registry = new Map<string, { contractId: string; publicKey: Uint8Array }>();\n let nonce = 0;\n return {\n registry,\n deployer: {\n deploy({ publicKey, credentialId }) {\n const contractId = StrKey.encodeContract(\n Buffer.from(sha256(utf8ToBytes('account:' + credentialId))),\n );\n registry.set(credentialId, { contractId, publicKey });\n return Promise.resolve({ contractId, txHash: `mock-deploy-${String(nonce++)}` });\n },\n },\n indexer: {\n resolveByCredential(credentialId) {\n const account = registry.get(credentialId);\n // Carry the founding public key the same way the real `eventsIndexer` reads it\n // off the factory `deployed` event, so mock-mode connect/recover can verify\n // enrollment and recover the signing key (no mock/live divergence).\n return Promise.resolve(\n account ? [{ contractId: account.contractId, publicKey: account.publicKey }] : [],\n );\n },\n },\n submission: {\n send: () => Promise.resolve({ status: 'SUCCESS', hash: 'mock-tx' }),\n },\n };\n}\n","import { createPasskey as createPasskeyCeremony } from '../ceremonies/create';\nimport { connect as connectCeremony, type ConnectResult } from '../ceremonies/connect';\nimport { recover as recoverCeremony, type RecoverResult } from '../ceremonies/recover';\nimport { signAuthEntry as signAuthEntryFn, type WebAuthnSigner } from '../soroban/sign';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\nimport type { PasskeyCredential } from '../types';\nimport { mockAuthenticator } from './mockAuthenticator';\nimport { createInMemoryBackend } from './inMemory';\n\nconst TESTNET = 'Test SDF Network ; September 2015';\n\nexport interface CreatePasskeyKitOptions {\n mode: 'mock' | 'live';\n rpId: string;\n rpName?: string;\n networkPassphrase?: string;\n // mock-mode knobs\n seed?: string;\n forceHighS?: boolean;\n // live-mode dependencies\n webauthn?: WebAuthnClient;\n deployer?: AccountDeployer;\n indexer?: IndexerAdapter;\n submission?: SubmissionAdapter;\n storage?: CredentialStorage;\n signer?: WebAuthnSigner;\n}\n\nexport interface PasskeyKit {\n readonly mode: 'mock' | 'live';\n readonly rpId: string;\n createPasskey(input?: { userName?: string }): Promise<PasskeyCredential>;\n connect(): Promise<ConnectResult | null>;\n recover(): Promise<RecoverResult[]>;\n signAuthEntry(entryXdr: string): Promise<string>;\n}\n\nfunction inMemoryStorage(): CredentialStorage {\n const map = new Map<string, string>();\n return { get: (rpId) => map.get(rpId) ?? null, set: (rpId, id) => void map.set(rpId, id) };\n}\n\n/**\n * The downstream-adopter kit (S15, Deliverable #6). `mode:'mock'` wires a\n * deterministic in-memory authenticator + backend (zero network IO) so the\n * happy path matches the live path's SHAPE — swap `mock → live` and the demo\n * stays green. `mode:'live'` takes real adapters + a WebAuthn signer.\n */\nexport function createPasskeyKit(options: CreatePasskeyKitOptions): PasskeyKit {\n const networkPassphrase = options.networkPassphrase ?? TESTNET;\n const rpName = options.rpName ?? options.rpId;\n\n let webauthn: WebAuthnClient;\n let deployer: AccountDeployer;\n let indexer: IndexerAdapter;\n let storage: CredentialStorage;\n let signer: WebAuthnSigner;\n\n if (options.mode === 'mock') {\n const auth = mockAuthenticator({\n rpId: options.rpId,\n seed: options.seed,\n forceHighS: options.forceHighS,\n });\n const backend = createInMemoryBackend();\n webauthn = auth;\n deployer = backend.deployer;\n indexer = backend.indexer;\n signer = auth.sign;\n storage = inMemoryStorage();\n } else {\n if (!options.webauthn || !options.deployer || !options.indexer || !options.signer) {\n throw new Error('live mode requires webauthn, deployer, indexer and signer');\n }\n webauthn = options.webauthn;\n deployer = options.deployer;\n indexer = options.indexer;\n signer = options.signer;\n storage = options.storage ?? inMemoryStorage();\n }\n\n return {\n mode: options.mode,\n rpId: options.rpId,\n createPasskey: (input) =>\n createPasskeyCeremony({\n rpId: options.rpId,\n rpName,\n userName: input?.userName ?? 'user',\n deployer,\n webauthn,\n storage,\n }),\n connect: () =>\n connectCeremony({\n rpId: options.rpId,\n indexer,\n webauthn,\n storage,\n silentMediationSupported: false,\n }),\n recover: () => recoverCeremony({ rpId: options.rpId, indexer, webauthn }),\n signAuthEntry: (entryXdr) => signAuthEntryFn(entryXdr, { networkPassphrase, sign: signer }),\n };\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\n\n/**\n * A ready-to-sign `SorobanAuthorizationEntry` (base64 XDR) for a demo call on\n * `contractId`. A convenience for smoke tests and examples, so you do not hand-\n * build auth-entry XDR just to have something to sign. The nonce and expiration\n * are fixed placeholders, so this is for local verification, not production.\n */\nexport function sampleAuthEntry(contractId: string, functionName = 'protected'): string {\n const address = new Address(contractId).toScAddress();\n const entry = new xdr.SorobanAuthorizationEntry({\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(\n new xdr.SorobanAddressCredentials({\n address,\n nonce: new xdr.Int64(1),\n signatureExpirationLedger: 1000,\n signature: xdr.ScVal.scvVoid(),\n }),\n ),\n rootInvocation: new xdr.SorobanAuthorizedInvocation({\n function: xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(\n new xdr.InvokeContractArgs({ contractAddress: address, functionName, args: [] }),\n ),\n subInvocations: [],\n }),\n });\n return entry.toXDR('base64');\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/cborEncode.ts","../src/testing/mockAuthenticator.ts","../src/testing/inMemory.ts","../src/testing/kit.ts","../src/testing/sampleAuthEntry.ts"],"names":[],"mappings":"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","file":"testing.js","sourcesContent":["import type { CborValue } from './cbor';\nimport { utf8ToBytes } from './encoding';\n\n/**\n * Minimal CBOR encoder — the inverse of `cbor.ts`, supporting the same major\n * types (uint, negint, byte string, text string, array, map). Used by the\n * deterministic mock authenticator (S15) to synthesize real attestationObject /\n * COSE-key bytes, so the mock create path goes through the exact same\n * `extractPublicKeyFromAttestationObject` as production. Not canonical-ordered\n * (our decoder is order-agnostic) and intentionally narrow.\n */\nfunction head(major: number, arg: number): number[] {\n const m = major << 5;\n if (arg < 24) return [m | arg];\n if (arg < 0x100) return [m | 24, arg];\n if (arg < 0x10000) return [m | 25, (arg >> 8) & 0xff, arg & 0xff];\n return [m | 26, (arg >>> 24) & 0xff, (arg >> 16) & 0xff, (arg >> 8) & 0xff, arg & 0xff];\n}\n\nfunction write(value: CborValue, out: number[]): void {\n if (typeof value === 'number' && Number.isInteger(value)) {\n if (value >= 0) out.push(...head(0, value));\n else out.push(...head(1, -1 - value));\n } else if (value instanceof Uint8Array) {\n out.push(...head(2, value.length));\n for (const b of value) out.push(b);\n } else if (typeof value === 'string') {\n const bytes = utf8ToBytes(value);\n out.push(...head(3, bytes.length));\n for (const b of bytes) out.push(b);\n } else if (Array.isArray(value)) {\n out.push(...head(4, value.length));\n for (const item of value) write(item, out);\n } else if (value instanceof Map) {\n out.push(...head(5, value.size));\n for (const [k, v] of value) {\n write(k, out);\n write(v, out);\n }\n } else {\n throw new Error('CBOR encode: unsupported value');\n }\n}\n\nexport function encodeCbor(value: CborValue): Uint8Array {\n const out: number[] = [];\n write(value, out);\n return Uint8Array.from(out);\n}\n","import { p256 } from '@noble/curves/nist';\nimport { sha256 } from '../internal/sha256';\nimport { concatBytes } from '../internal/bytes';\nimport { bytesToBase64Url, utf8ToBytes } from '../internal/encoding';\nimport { encodeCbor } from '../internal/cborEncode';\nimport type { CborValue } from '../internal/cbor';\nimport type {\n WebAuthnClient,\n WebAuthnCreateResult,\n WebAuthnGetOptions,\n WebAuthnGetResult,\n} from '../ceremonies/types';\nimport type { AssertionResult } from '../soroban/sign';\n\nexport interface MockAuthenticatorOptions {\n rpId: string;\n origin?: string;\n /** Deterministic seed → keypair + credentialId. */\n seed?: string;\n /** Emit high-S signatures, to exercise the perpetual low-S guard (S04). */\n forceHighS?: boolean;\n}\n\nexport interface MockAuthenticator extends WebAuthnClient {\n readonly publicKey: Uint8Array; // 65-byte SEC-1\n readonly credentialId: string; // base64url\n readonly privateKey: Uint8Array;\n /** WebAuthnSigner for the Soroban sign path (challenge already base64url). */\n sign(challenge: string): AssertionResult;\n}\n\nfunction deriveScalar(seed: string): Uint8Array {\n const n = p256.CURVE.n;\n let scalar = BigInt('0x' + bytesToHexLocal(sha256(utf8ToBytes('priv:' + seed)))) % n;\n if (scalar === 0n) scalar = 1n;\n const hex = scalar.toString(16).padStart(64, '0');\n return Uint8Array.from((hex.match(/../g) ?? []).map((h) => parseInt(h, 16)));\n}\nfunction bytesToHexLocal(bytes: Uint8Array): string {\n let hex = '';\n for (const b of bytes) hex += b.toString(16).padStart(2, '0');\n return hex;\n}\n\n/**\n * A deterministic, in-memory WebAuthn authenticator for the mock kit (S15). It\n * synthesizes a REAL attestationObject / COSE key (so `createPasskey` runs the\n * exact production extraction path) and signs assertions with the same P-256\n * key — optionally as high-S to prove the low-S normalization guard.\n */\nexport function mockAuthenticator(options: MockAuthenticatorOptions): MockAuthenticator {\n const seed = options.seed ?? 'mock-authenticator';\n const origin = options.origin ?? `https://${options.rpId}`;\n const privateKey = deriveScalar(seed);\n const publicKey = p256.getPublicKey(privateKey, false); // 0x04 ‖ X ‖ Y\n const x = publicKey.slice(1, 33);\n const y = publicKey.slice(33, 65);\n const credIdBytes = sha256(utf8ToBytes('cred:' + seed)).slice(0, 16);\n const credentialId = bytesToBase64Url(credIdBytes);\n const rpIdHash = sha256(utf8ToBytes(options.rpId));\n\n const coseKey = encodeCbor(\n new Map<number | string, CborValue>([\n [1, 2], // kty EC2\n [3, -7], // alg ES256\n [-1, 1], // crv P-256\n [-2, x],\n [-3, y],\n ]),\n );\n\n const attestedAuthData = concatBytes(\n rpIdHash,\n new Uint8Array([0x45]), // UP | UV | AT\n new Uint8Array([0, 0, 0, 0]), // signCount\n new Uint8Array(16), // aaguid\n new Uint8Array([0, credIdBytes.length]),\n credIdBytes,\n coseKey,\n );\n const attestationObject = encodeCbor(\n new Map<number | string, CborValue>([\n ['fmt', 'none'],\n ['attStmt', new Map<number | string, CborValue>()],\n ['authData', attestedAuthData],\n ]),\n );\n\n function signAssertion(challengeB64: string): {\n authenticatorData: Uint8Array;\n clientDataJSON: Uint8Array;\n signatureDer: Uint8Array;\n } {\n const authenticatorData = concatBytes(\n rpIdHash,\n new Uint8Array([0x05]),\n new Uint8Array([0, 0, 0, 1]),\n );\n const clientDataJSON = utf8ToBytes(\n JSON.stringify({ type: 'webauthn.get', challenge: challengeB64, origin }),\n );\n const payload = sha256(concatBytes(authenticatorData, sha256(clientDataJSON)));\n const sig = p256.sign(payload, privateKey); // low-S by default\n const s = options.forceHighS ? p256.CURVE.n - sig.s : sig.s;\n const signatureDer = new p256.Signature(sig.r, s).toDERRawBytes();\n return { authenticatorData, clientDataJSON, signatureDer };\n }\n\n return {\n publicKey,\n credentialId,\n privateKey,\n create(): Promise<WebAuthnCreateResult> {\n return Promise.resolve({ id: credentialId, rawId: credIdBytes, attestationObject });\n },\n get(getOptions: WebAuthnGetOptions): Promise<WebAuthnGetResult> {\n const challengeB64 = getOptions.challenge ? bytesToBase64Url(getOptions.challenge) : 'mock';\n const a = signAssertion(challengeB64);\n return Promise.resolve({\n id: credentialId,\n rawId: credIdBytes,\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n });\n },\n sign(challenge: string): AssertionResult {\n const a = signAssertion(challenge);\n return {\n authenticatorData: a.authenticatorData,\n clientDataJSON: a.clientDataJSON,\n signature: a.signatureDer,\n credentialId: credIdBytes,\n publicKey,\n };\n },\n };\n}\n","import { StrKey } from '@stellar/stellar-sdk';\nimport { sha256 } from '../internal/sha256';\nimport { utf8ToBytes } from '../internal/encoding';\nimport type { AccountDeployer } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\n\nexport interface InMemoryBackend {\n deployer: AccountDeployer;\n indexer: IndexerAdapter;\n submission: SubmissionAdapter;\n /** credentialId → { contractId, publicKey } — shared so create/connect/recover agree. */\n registry: Map<string, { contractId: string; publicKey: Uint8Array }>;\n}\n\n/**\n * Deterministic, zero-IO backend for the mock kit: the deployer derives a stable\n * C-address from the credentialId and records it; the indexer resolves from the\n * same registry; submission is a no-op SUCCESS.\n *\n * The address is a real StrKey contract id (checksummed, decodable), so a mock\n * account can be fed straight into `new Address(...)` / auth-entry XDR the same way\n * a deployed one is. It is deterministic but arbitrary: it is not the address the\n * factory would deploy for this credential (that is {@link deriveAccountAddress}).\n */\nexport function createInMemoryBackend(): InMemoryBackend {\n const registry = new Map<string, { contractId: string; publicKey: Uint8Array }>();\n let nonce = 0;\n return {\n registry,\n deployer: {\n deploy({ publicKey, credentialId }) {\n const contractId = StrKey.encodeContract(\n Buffer.from(sha256(utf8ToBytes('account:' + credentialId))),\n );\n registry.set(credentialId, { contractId, publicKey });\n return Promise.resolve({ contractId, txHash: `mock-deploy-${String(nonce++)}` });\n },\n },\n indexer: {\n resolveByCredential(credentialId) {\n const account = registry.get(credentialId);\n // Carry the founding public key the same way the real `eventsIndexer` reads it\n // off the factory `deployed` event, so mock-mode connect/recover can verify\n // enrollment and recover the signing key (no mock/live divergence).\n return Promise.resolve(\n account ? [{ contractId: account.contractId, publicKey: account.publicKey }] : [],\n );\n },\n },\n submission: {\n send: () => Promise.resolve({ status: 'SUCCESS', hash: 'mock-tx' }),\n },\n };\n}\n","import { createPasskey as createPasskeyCeremony } from '../ceremonies/create';\nimport { connect as connectCeremony, type ConnectResult } from '../ceremonies/connect';\nimport { recover as recoverCeremony, type RecoverResult } from '../ceremonies/recover';\nimport { signAuthEntry as signAuthEntryFn, type WebAuthnSigner } from '../soroban/sign';\nimport type { AccountDeployer, CredentialStorage, WebAuthnClient } from '../ceremonies/types';\nimport type { IndexerAdapter, SubmissionAdapter } from '../adapters/types';\nimport type { PasskeyCredential } from '../types';\nimport { mockAuthenticator } from './mockAuthenticator';\nimport { createInMemoryBackend } from './inMemory';\n\nconst TESTNET = 'Test SDF Network ; September 2015';\n\nexport interface CreatePasskeyKitOptions {\n mode: 'mock' | 'live';\n rpId: string;\n rpName?: string;\n networkPassphrase?: string;\n // mock-mode knobs\n seed?: string;\n forceHighS?: boolean;\n // live-mode dependencies\n webauthn?: WebAuthnClient;\n deployer?: AccountDeployer;\n indexer?: IndexerAdapter;\n submission?: SubmissionAdapter;\n storage?: CredentialStorage;\n signer?: WebAuthnSigner;\n}\n\nexport interface PasskeyKit {\n readonly mode: 'mock' | 'live';\n readonly rpId: string;\n createPasskey(input?: { userName?: string }): Promise<PasskeyCredential>;\n connect(): Promise<ConnectResult | null>;\n recover(): Promise<RecoverResult[]>;\n signAuthEntry(entryXdr: string): Promise<string>;\n}\n\nfunction inMemoryStorage(): CredentialStorage {\n const map = new Map<string, string>();\n return { get: (rpId) => map.get(rpId) ?? null, set: (rpId, id) => void map.set(rpId, id) };\n}\n\n/**\n * The downstream-adopter kit (S15, Deliverable #6). `mode:'mock'` wires a\n * deterministic in-memory authenticator + backend (zero network IO) so the\n * happy path matches the live path's SHAPE — swap `mock → live` and the demo\n * stays green. `mode:'live'` takes real adapters + a WebAuthn signer.\n */\nexport function createPasskeyKit(options: CreatePasskeyKitOptions): PasskeyKit {\n const networkPassphrase = options.networkPassphrase ?? TESTNET;\n const rpName = options.rpName ?? options.rpId;\n\n let webauthn: WebAuthnClient;\n let deployer: AccountDeployer;\n let indexer: IndexerAdapter;\n let storage: CredentialStorage;\n let signer: WebAuthnSigner;\n\n if (options.mode === 'mock') {\n const auth = mockAuthenticator({\n rpId: options.rpId,\n seed: options.seed,\n forceHighS: options.forceHighS,\n });\n const backend = createInMemoryBackend();\n webauthn = auth;\n deployer = backend.deployer;\n indexer = backend.indexer;\n signer = auth.sign;\n storage = inMemoryStorage();\n } else {\n if (!options.webauthn || !options.deployer || !options.indexer || !options.signer) {\n throw new Error('live mode requires webauthn, deployer, indexer and signer');\n }\n webauthn = options.webauthn;\n deployer = options.deployer;\n indexer = options.indexer;\n signer = options.signer;\n storage = options.storage ?? inMemoryStorage();\n }\n\n return {\n mode: options.mode,\n rpId: options.rpId,\n createPasskey: (input) =>\n createPasskeyCeremony({\n rpId: options.rpId,\n rpName,\n userName: input?.userName ?? 'user',\n deployer,\n webauthn,\n storage,\n }),\n connect: () =>\n connectCeremony({\n rpId: options.rpId,\n indexer,\n webauthn,\n storage,\n silentMediationSupported: false,\n }),\n recover: () => recoverCeremony({ rpId: options.rpId, indexer, webauthn }),\n signAuthEntry: (entryXdr) => signAuthEntryFn(entryXdr, { networkPassphrase, sign: signer }),\n };\n}\n","import { Address, xdr } from '@stellar/stellar-sdk';\n\n/**\n * A ready-to-sign `SorobanAuthorizationEntry` (base64 XDR) for a demo call on\n * `contractId`. A convenience for smoke tests and examples, so you do not hand-\n * build auth-entry XDR just to have something to sign. The nonce and expiration\n * are fixed placeholders, so this is for local verification, not production.\n *\n * Requires `@stellar/stellar-sdk >=12 <17` (the package's peer range): version 17\n * reworked the XDR API this builds against.\n */\nexport function sampleAuthEntry(contractId: string, functionName = 'protected'): string {\n const address = new Address(contractId).toScAddress();\n const entry = new xdr.SorobanAuthorizationEntry({\n credentials: xdr.SorobanCredentials.sorobanCredentialsAddress(\n new xdr.SorobanAddressCredentials({\n address,\n nonce: new xdr.Int64(1),\n signatureExpirationLedger: 1000,\n signature: xdr.ScVal.scvVoid(),\n }),\n ),\n rootInvocation: new xdr.SorobanAuthorizedInvocation({\n function: xdr.SorobanAuthorizedFunction.sorobanAuthorizedFunctionTypeContractFn(\n new xdr.InvokeContractArgs({ contractAddress: address, functionName, args: [] }),\n ),\n subInvocations: [],\n }),\n });\n return entry.toXDR('base64');\n}\n"]}
package/package.json CHANGED
@@ -1,8 +1,29 @@
1
1
  {
2
2
  "name": "@soropass/core",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Minimal, headless, ES256-only passkey SDK for Stellar smart accounts.",
5
5
  "license": "Apache-2.0",
6
+ "keywords": [
7
+ "passkey",
8
+ "passkeys",
9
+ "webauthn",
10
+ "es256",
11
+ "secp256r1",
12
+ "stellar",
13
+ "soroban",
14
+ "smart-account",
15
+ "smart-wallet",
16
+ "sdk"
17
+ ],
18
+ "homepage": "https://docs.soropass.dev",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/justmert/soropass.git",
22
+ "directory": "packages/core"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/justmert/soropass/issues"
26
+ },
6
27
  "publishConfig": {
7
28
  "access": "public"
8
29
  },
@@ -95,7 +116,7 @@
95
116
  "lint": "eslint src"
96
117
  },
97
118
  "peerDependencies": {
98
- "@stellar/stellar-sdk": ">=12"
119
+ "@stellar/stellar-sdk": ">=12 <17"
99
120
  },
100
121
  "peerDependenciesMeta": {
101
122
  "@stellar/stellar-sdk": {