@soropass/core 0.1.0

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.
Files changed (83) hide show
  1. package/dist/checkAuth-C2AcXqFe.d.cts +110 -0
  2. package/dist/checkAuth-C2AcXqFe.d.ts +110 -0
  3. package/dist/chunk-AHFGTIBY.js +36 -0
  4. package/dist/chunk-AHFGTIBY.js.map +1 -0
  5. package/dist/chunk-AMYFJQAC.js +29 -0
  6. package/dist/chunk-AMYFJQAC.js.map +1 -0
  7. package/dist/chunk-BIRF5I6I.js +265 -0
  8. package/dist/chunk-BIRF5I6I.js.map +1 -0
  9. package/dist/chunk-JNJ2FY45.js +209 -0
  10. package/dist/chunk-JNJ2FY45.js.map +1 -0
  11. package/dist/chunk-LB4HOTLV.js +135 -0
  12. package/dist/chunk-LB4HOTLV.js.map +1 -0
  13. package/dist/chunk-LM2AZXKZ.js +108 -0
  14. package/dist/chunk-LM2AZXKZ.js.map +1 -0
  15. package/dist/chunk-LUDXP56M.js +3 -0
  16. package/dist/chunk-LUDXP56M.js.map +1 -0
  17. package/dist/chunk-MMB4ZIW3.js +48 -0
  18. package/dist/chunk-MMB4ZIW3.js.map +1 -0
  19. package/dist/chunk-MOLZIRIH.js +22 -0
  20. package/dist/chunk-MOLZIRIH.js.map +1 -0
  21. package/dist/chunk-OGSUGATA.js +3 -0
  22. package/dist/chunk-OGSUGATA.js.map +1 -0
  23. package/dist/chunk-TPBBZNPP.js +30 -0
  24. package/dist/chunk-TPBBZNPP.js.map +1 -0
  25. package/dist/chunk-UQKNPO44.js +32 -0
  26. package/dist/chunk-UQKNPO44.js.map +1 -0
  27. package/dist/chunk-UV5HORMF.js +175 -0
  28. package/dist/chunk-UV5HORMF.js.map +1 -0
  29. package/dist/chunk-W75OQKHR.js +133 -0
  30. package/dist/chunk-W75OQKHR.js.map +1 -0
  31. package/dist/connect.cjs +166 -0
  32. package/dist/connect.cjs.map +1 -0
  33. package/dist/connect.d.cts +24 -0
  34. package/dist/connect.d.ts +24 -0
  35. package/dist/connect.js +6 -0
  36. package/dist/connect.js.map +1 -0
  37. package/dist/create.cjs +483 -0
  38. package/dist/create.cjs.map +1 -0
  39. package/dist/create.d.cts +106 -0
  40. package/dist/create.d.ts +106 -0
  41. package/dist/create.js +8 -0
  42. package/dist/create.js.map +1 -0
  43. package/dist/index.cjs +1542 -0
  44. package/dist/index.cjs.map +1 -0
  45. package/dist/index.d.cts +197 -0
  46. package/dist/index.d.ts +197 -0
  47. package/dist/index.js +354 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/recover-0wbOXDjR.d.cts +23 -0
  50. package/dist/recover-COnsxhYk.d.ts +23 -0
  51. package/dist/recover.cjs +802 -0
  52. package/dist/recover.cjs.map +1 -0
  53. package/dist/recover.d.cts +49 -0
  54. package/dist/recover.d.ts +49 -0
  55. package/dist/recover.js +10 -0
  56. package/dist/recover.js.map +1 -0
  57. package/dist/sign-Cfg0NM0T.d.cts +73 -0
  58. package/dist/sign-Cfg0NM0T.d.ts +73 -0
  59. package/dist/sign.cjs +883 -0
  60. package/dist/sign.cjs.map +1 -0
  61. package/dist/sign.d.cts +143 -0
  62. package/dist/sign.d.ts +143 -0
  63. package/dist/sign.js +8 -0
  64. package/dist/sign.js.map +1 -0
  65. package/dist/submit-BDKADQq0.d.cts +112 -0
  66. package/dist/submit-BO0Nh49I.d.ts +112 -0
  67. package/dist/testing.cjs +955 -0
  68. package/dist/testing.cjs.map +1 -0
  69. package/dist/testing.d.cts +86 -0
  70. package/dist/testing.d.ts +86 -0
  71. package/dist/testing.js +235 -0
  72. package/dist/testing.js.map +1 -0
  73. package/dist/types--WNl-Sda.d.cts +125 -0
  74. package/dist/types--WNl-Sda.d.ts +125 -0
  75. package/dist/types-dMRWEEo0.d.cts +73 -0
  76. package/dist/types-lW2h8Uxn.d.ts +73 -0
  77. package/dist/types.cjs +44 -0
  78. package/dist/types.cjs.map +1 -0
  79. package/dist/types.d.cts +5 -0
  80. package/dist/types.d.ts +5 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/package.json +117 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,1542 @@
1
+ 'use strict';
2
+
3
+ var nist = require('@noble/curves/nist');
4
+ var sha256 = require('@noble/hashes/sha256');
5
+ var stellarSdk = require('@stellar/stellar-sdk');
6
+
7
+ // src/errors.ts
8
+ var KIT_ERROR_CODES = Object.freeze([
9
+ "USER_CANCELLED",
10
+ "ES256_NOT_SUPPORTED",
11
+ "RP_ID_MISMATCH",
12
+ "ORIGIN_MISMATCH",
13
+ "CHALLENGE_MISMATCH",
14
+ "INVALID_SIGNATURE_DER",
15
+ "INVALID_PUBLIC_KEY",
16
+ "CONTRACT_AUTH_FAILED",
17
+ "NETWORK_ERROR",
18
+ "UNSUPPORTED_AUTHENTICATOR"
19
+ ]);
20
+ var KitError = class _KitError extends Error {
21
+ code;
22
+ name = "KitError";
23
+ constructor(code, message, options) {
24
+ super(message ?? code, options);
25
+ this.code = code;
26
+ Object.setPrototypeOf(this, _KitError.prototype);
27
+ }
28
+ };
29
+ function isKitError(value) {
30
+ return value instanceof KitError;
31
+ }
32
+
33
+ // src/anchors.ts
34
+ var BATTLE_TESTED_ANCHORS = Object.freeze({
35
+ /** Apple Touch ID/Face ID emit high-S ~50% of the time; we normalize to low-S. */
36
+ LOW_S_NORMALIZATION: "low-s-normalization",
37
+ /** Non-ES256 credentials (e.g. some Windows Hello configs) cannot verify on-chain. */
38
+ RS256_HARD_FAIL: "rs256-hard-fail",
39
+ /** Safari requires create/get inside a user activation or it silently rejects. */
40
+ APPLE_USER_GESTURE: "apple-user-gesture"
41
+ });
42
+ var ALG_ES256 = -7;
43
+ function assertES256(alg) {
44
+ if (alg !== ALG_ES256) {
45
+ throw new KitError("ES256_NOT_SUPPORTED", `COSE alg ${alg} is not ES256 (-7)`);
46
+ }
47
+ }
48
+ function assertUserActivation(activation) {
49
+ const ua = activation ?? globalThis.navigator?.userActivation;
50
+ if (ua && !ua.isActive) {
51
+ throw new KitError(
52
+ "USER_CANCELLED",
53
+ "WebAuthn ceremony must be invoked inside a user activation (click/tap)"
54
+ );
55
+ }
56
+ }
57
+
58
+ // src/internal/encoding.ts
59
+ function bytesToBase64Url(bytes) {
60
+ let binary = "";
61
+ for (const byte of bytes) binary += String.fromCharCode(byte);
62
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
63
+ }
64
+ function base64UrlToBytes(input) {
65
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
66
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
67
+ const binary = atob(padded);
68
+ const out = new Uint8Array(new ArrayBuffer(binary.length));
69
+ for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
70
+ return out;
71
+ }
72
+ function utf8ToBytes(text) {
73
+ return new TextEncoder().encode(text);
74
+ }
75
+ function bytesToUtf8(bytes) {
76
+ return new TextDecoder().decode(bytes);
77
+ }
78
+
79
+ // src/webauthn/createOptions.ts
80
+ function buildCreateOptions(input) {
81
+ const residentKey = input.residentKey ?? "required";
82
+ return {
83
+ rp: { id: input.rpId, name: input.rpName },
84
+ user: {
85
+ id: bytesToBase64Url(input.userId ?? utf8ToBytes(input.userName)),
86
+ name: input.userName,
87
+ displayName: input.userDisplayName ?? input.userName
88
+ },
89
+ challenge: bytesToBase64Url(input.challenge),
90
+ pubKeyCredParams: [{ type: "public-key", alg: -7 }],
91
+ authenticatorSelection: {
92
+ residentKey,
93
+ requireResidentKey: residentKey === "required",
94
+ userVerification: input.userVerification ?? "preferred"
95
+ },
96
+ attestation: "none",
97
+ timeout: input.timeout ?? 6e4
98
+ };
99
+ }
100
+
101
+ // src/internal/bytes.ts
102
+ function concatBytes(...arrays) {
103
+ const total = arrays.reduce((n, a) => n + a.length, 0);
104
+ const out = new Uint8Array(total);
105
+ let offset = 0;
106
+ for (const a of arrays) {
107
+ out.set(a, offset);
108
+ offset += a.length;
109
+ }
110
+ return out;
111
+ }
112
+ function equalBytes(a, b) {
113
+ if (a.length !== b.length) return false;
114
+ let diff = 0;
115
+ for (let i = 0; i < a.length; i += 1) diff |= (a[i] ?? 0) ^ (b[i] ?? 0);
116
+ return diff === 0;
117
+ }
118
+
119
+ // src/internal/cbor.ts
120
+ function byteAt(bytes, index) {
121
+ const value = bytes[index];
122
+ if (value === void 0) throw new Error(`CBOR: unexpected end of input at byte ${index}`);
123
+ return value;
124
+ }
125
+ var MAX_DEPTH = 16;
126
+ function decodeCbor(bytes, offset = 0, depth = 0) {
127
+ if (depth > MAX_DEPTH) throw new Error("CBOR: maximum nesting depth exceeded");
128
+ const first = byteAt(bytes, offset);
129
+ const major = first >> 5;
130
+ const info = first & 31;
131
+ let pos = offset + 1;
132
+ let argument;
133
+ if (info < 24) {
134
+ argument = info;
135
+ } else if (info === 24) {
136
+ argument = byteAt(bytes, pos);
137
+ pos += 1;
138
+ } else if (info === 25) {
139
+ argument = byteAt(bytes, pos) << 8 | byteAt(bytes, pos + 1);
140
+ pos += 2;
141
+ } else if (info === 26) {
142
+ argument = byteAt(bytes, pos) * 16777216 + (byteAt(bytes, pos + 1) << 16) + (byteAt(bytes, pos + 2) << 8) + byteAt(bytes, pos + 3);
143
+ pos += 4;
144
+ } else {
145
+ throw new Error(`CBOR: unsupported length encoding (additional info ${info})`);
146
+ }
147
+ switch (major) {
148
+ case 0:
149
+ return { value: argument, length: pos - offset };
150
+ case 1:
151
+ return { value: -1 - argument, length: pos - offset };
152
+ case 2: {
153
+ const end = pos + argument;
154
+ if (end > bytes.length) throw new Error("CBOR: byte string exceeds input");
155
+ return { value: bytes.slice(pos, end), length: end - offset };
156
+ }
157
+ case 3: {
158
+ const end = pos + argument;
159
+ if (end > bytes.length) throw new Error("CBOR: text string exceeds input");
160
+ return { value: new TextDecoder().decode(bytes.slice(pos, end)), length: end - offset };
161
+ }
162
+ case 4: {
163
+ const items = [];
164
+ let cursor = pos;
165
+ for (let i = 0; i < argument; i += 1) {
166
+ const item = decodeCbor(bytes, cursor, depth + 1);
167
+ items.push(item.value);
168
+ cursor += item.length;
169
+ }
170
+ return { value: items, length: cursor - offset };
171
+ }
172
+ case 5: {
173
+ const map = /* @__PURE__ */ new Map();
174
+ let cursor = pos;
175
+ for (let i = 0; i < argument; i += 1) {
176
+ const key = decodeCbor(bytes, cursor, depth + 1);
177
+ cursor += key.length;
178
+ const val = decodeCbor(bytes, cursor, depth + 1);
179
+ cursor += val.length;
180
+ if (typeof key.value !== "number" && typeof key.value !== "string") {
181
+ throw new Error("CBOR: unsupported map key type");
182
+ }
183
+ if (map.has(key.value)) {
184
+ throw new Error("CBOR: duplicate map key (non-canonical)");
185
+ }
186
+ map.set(key.value, val.value);
187
+ }
188
+ return { value: map, length: cursor - offset };
189
+ }
190
+ default:
191
+ throw new Error(`CBOR: unsupported major type ${major}`);
192
+ }
193
+ }
194
+ function decodeCborFirst(bytes) {
195
+ return decodeCbor(bytes, 0).value;
196
+ }
197
+
198
+ // src/webauthn/authData.ts
199
+ var MIN_LENGTH = 37;
200
+ function parseAuthenticatorData(authData) {
201
+ if (authData.length < MIN_LENGTH) {
202
+ throw new KitError(
203
+ "UNSUPPORTED_AUTHENTICATOR",
204
+ `authenticatorData is ${authData.length} bytes, expected at least ${MIN_LENGTH}`
205
+ );
206
+ }
207
+ const view = new DataView(authData.buffer, authData.byteOffset, authData.byteLength);
208
+ const rpIdHash = authData.slice(0, 32);
209
+ const bits = authData[32] ?? 0;
210
+ const flags = {
211
+ up: (bits & 1) !== 0,
212
+ uv: (bits & 4) !== 0,
213
+ be: (bits & 8) !== 0,
214
+ bs: (bits & 16) !== 0,
215
+ at: (bits & 64) !== 0,
216
+ ed: (bits & 128) !== 0,
217
+ bits
218
+ };
219
+ const signCount = view.getUint32(33, false);
220
+ const result = { rpIdHash, flags, signCount };
221
+ if (flags.at) {
222
+ if (authData.length < 55) {
223
+ throw new KitError(
224
+ "UNSUPPORTED_AUTHENTICATOR",
225
+ "authenticatorData truncated in attested data"
226
+ );
227
+ }
228
+ result.aaguid = authData.slice(37, 53);
229
+ const credIdLength = view.getUint16(53, false);
230
+ const credIdEnd = 55 + credIdLength;
231
+ if (authData.length < credIdEnd) {
232
+ throw new KitError(
233
+ "UNSUPPORTED_AUTHENTICATOR",
234
+ "authenticatorData truncated in credentialId"
235
+ );
236
+ }
237
+ result.credentialId = authData.slice(55, credIdEnd);
238
+ const rest = authData.slice(credIdEnd);
239
+ const { length } = decodeCbor(rest, 0);
240
+ result.credentialPublicKey = rest.slice(0, length);
241
+ }
242
+ return result;
243
+ }
244
+ function verifyRpIdHash(authData, rpId) {
245
+ const actual = parseAuthenticatorData(authData).rpIdHash;
246
+ const expected = sha256.sha256(utf8ToBytes(rpId));
247
+ if (!equalBytes(actual, expected)) {
248
+ throw new KitError(
249
+ "RP_ID_MISMATCH",
250
+ `authenticatorData rpIdHash does not match SHA-256("${rpId}")`
251
+ );
252
+ }
253
+ }
254
+
255
+ // src/webauthn/publicKey.ts
256
+ var COSE_KTY = 1;
257
+ var COSE_ALG = 3;
258
+ var COSE_CRV = -1;
259
+ var COSE_X = -2;
260
+ var COSE_Y = -3;
261
+ var KTY_EC2 = 2;
262
+ var CRV_P256 = 1;
263
+ function coseKeyToSec1(coseKey) {
264
+ let decoded;
265
+ try {
266
+ decoded = decodeCborFirst(coseKey);
267
+ } catch (cause) {
268
+ throw new KitError("INVALID_PUBLIC_KEY", "failed to CBOR-decode COSE key", { cause });
269
+ }
270
+ if (!(decoded instanceof Map)) {
271
+ throw new KitError("INVALID_PUBLIC_KEY", "COSE key is not a CBOR map");
272
+ }
273
+ const map = decoded;
274
+ const alg = map.get(COSE_ALG);
275
+ if (typeof alg !== "number") {
276
+ throw new KitError("ES256_NOT_SUPPORTED", `COSE alg ${String(alg)} is not ES256 (-7)`);
277
+ }
278
+ assertES256(alg);
279
+ if (map.get(COSE_KTY) !== KTY_EC2) {
280
+ throw new KitError(
281
+ "INVALID_PUBLIC_KEY",
282
+ `COSE kty ${String(map.get(COSE_KTY))} is not EC2 (2)`
283
+ );
284
+ }
285
+ if (map.get(COSE_CRV) !== CRV_P256) {
286
+ throw new KitError(
287
+ "INVALID_PUBLIC_KEY",
288
+ `COSE crv ${String(map.get(COSE_CRV))} is not P-256 (1)`
289
+ );
290
+ }
291
+ const x = map.get(COSE_X);
292
+ const y = map.get(COSE_Y);
293
+ if (!(x instanceof Uint8Array) || x.length !== 32) {
294
+ throw new KitError("INVALID_PUBLIC_KEY", "COSE key X coordinate is not 32 bytes");
295
+ }
296
+ if (!(y instanceof Uint8Array) || y.length !== 32) {
297
+ throw new KitError("INVALID_PUBLIC_KEY", "COSE key Y coordinate is not 32 bytes");
298
+ }
299
+ const sec1 = concatBytes(new Uint8Array([4]), x, y);
300
+ try {
301
+ nist.p256.Point.fromHex(sec1);
302
+ } catch (cause) {
303
+ throw new KitError("INVALID_PUBLIC_KEY", "public key is not a valid P-256 point", { cause });
304
+ }
305
+ return sec1;
306
+ }
307
+ function extractPublicKeyFromAuthData(authData) {
308
+ const parsed = parseAuthenticatorData(authData);
309
+ if (!parsed.credentialPublicKey) {
310
+ throw new KitError(
311
+ "INVALID_PUBLIC_KEY",
312
+ "authenticatorData has no attested credential public key"
313
+ );
314
+ }
315
+ return coseKeyToSec1(parsed.credentialPublicKey);
316
+ }
317
+ function extractPublicKeyFromAttestationObject(attestationObject) {
318
+ let decoded;
319
+ try {
320
+ decoded = decodeCborFirst(attestationObject);
321
+ } catch (cause) {
322
+ throw new KitError("INVALID_PUBLIC_KEY", "failed to CBOR-decode attestationObject", { cause });
323
+ }
324
+ if (!(decoded instanceof Map)) {
325
+ throw new KitError("INVALID_PUBLIC_KEY", "attestationObject is not a CBOR map");
326
+ }
327
+ const authData = decoded.get("authData");
328
+ if (!(authData instanceof Uint8Array)) {
329
+ throw new KitError("INVALID_PUBLIC_KEY", "attestationObject has no authData byte string");
330
+ }
331
+ return extractPublicKeyFromAuthData(authData);
332
+ }
333
+
334
+ // src/ceremonies/random.ts
335
+ function randomBytes(length) {
336
+ const webcrypto = globalThis.crypto;
337
+ if (typeof webcrypto?.getRandomValues !== "function") {
338
+ throw new KitError(
339
+ "UNSUPPORTED_AUTHENTICATOR",
340
+ "no secure random source (globalThis.crypto.getRandomValues) is available in this environment"
341
+ );
342
+ }
343
+ const out = new Uint8Array(new ArrayBuffer(length));
344
+ webcrypto.getRandomValues(out);
345
+ return out;
346
+ }
347
+
348
+ // src/ceremonies/browserClient.ts
349
+ function asKitError(error) {
350
+ if (error instanceof KitError) return error;
351
+ const name = typeof error === "object" && error !== null && "name" in error ? error.name : void 0;
352
+ if (name === "NotAllowedError") {
353
+ return new KitError("USER_CANCELLED", "The passkey prompt was dismissed.", { cause: error });
354
+ }
355
+ const message = error instanceof Error ? error.message : "WebAuthn request failed";
356
+ const detail = typeof name === "string" ? `${name}: ${message}` : message;
357
+ return new KitError("UNSUPPORTED_AUTHENTICATOR", detail, { cause: error });
358
+ }
359
+ function browserWebAuthnClient() {
360
+ const credentials = globalThis.navigator?.credentials;
361
+ if (!credentials) {
362
+ throw new KitError("UNSUPPORTED_AUTHENTICATOR", "navigator.credentials is unavailable");
363
+ }
364
+ return {
365
+ async create(options) {
366
+ const publicKey = {
367
+ challenge: base64UrlToBytes(options.challenge),
368
+ rp: options.rp,
369
+ user: {
370
+ id: base64UrlToBytes(options.user.id),
371
+ name: options.user.name,
372
+ displayName: options.user.displayName
373
+ },
374
+ pubKeyCredParams: options.pubKeyCredParams,
375
+ authenticatorSelection: options.authenticatorSelection,
376
+ attestation: options.attestation,
377
+ timeout: options.timeout
378
+ };
379
+ let credential;
380
+ try {
381
+ credential = await credentials.create({ publicKey });
382
+ } catch (error) {
383
+ throw asKitError(error);
384
+ }
385
+ if (!credential) throw new KitError("USER_CANCELLED", "credential creation returned null");
386
+ const response = credential.response;
387
+ return {
388
+ id: credential.id,
389
+ rawId: new Uint8Array(credential.rawId),
390
+ attestationObject: new Uint8Array(response.attestationObject)
391
+ };
392
+ },
393
+ async get(options) {
394
+ const publicKey = {
395
+ rpId: options.rpId,
396
+ challenge: options.challenge ? new Uint8Array(options.challenge) : randomBytes(32),
397
+ allowCredentials: (options.allowCredentials ?? []).map((id) => ({
398
+ type: "public-key",
399
+ id: base64UrlToBytes(id)
400
+ })),
401
+ userVerification: options.userVerification
402
+ };
403
+ const request = { publicKey };
404
+ if (options.mediation) request.mediation = options.mediation;
405
+ let credential;
406
+ try {
407
+ credential = await credentials.get(request);
408
+ } catch (error) {
409
+ throw asKitError(error);
410
+ }
411
+ if (!credential) throw new KitError("USER_CANCELLED", "assertion returned null");
412
+ const response = credential.response;
413
+ return {
414
+ id: credential.id,
415
+ rawId: new Uint8Array(credential.rawId),
416
+ authenticatorData: new Uint8Array(response.authenticatorData),
417
+ clientDataJSON: new Uint8Array(response.clientDataJSON),
418
+ signature: new Uint8Array(response.signature)
419
+ };
420
+ }
421
+ };
422
+ }
423
+ function defaultCredentialStorage() {
424
+ const key = (rpId) => `stellar-passkey:${rpId}`;
425
+ const ls = globalThis.localStorage;
426
+ if (ls) {
427
+ return {
428
+ get: (rpId) => ls.getItem(key(rpId)),
429
+ set: (rpId, credentialId) => {
430
+ ls.setItem(key(rpId), credentialId);
431
+ }
432
+ };
433
+ }
434
+ const memory = /* @__PURE__ */ new Map();
435
+ return {
436
+ get: (rpId) => memory.get(rpId) ?? null,
437
+ set: (rpId, credentialId) => {
438
+ memory.set(rpId, credentialId);
439
+ }
440
+ };
441
+ }
442
+
443
+ // src/ceremonies/create.ts
444
+ async function registerPasskey(options) {
445
+ assertUserActivation(options.userActivation);
446
+ const webauthn = options.webauthn ?? browserWebAuthnClient();
447
+ const creationOptions = buildCreateOptions({
448
+ rpId: options.rpId,
449
+ rpName: options.rpName,
450
+ userName: options.userName,
451
+ userId: options.userId,
452
+ challenge: options.challenge ?? randomBytes(32),
453
+ residentKey: options.residentKey,
454
+ userVerification: options.userVerification
455
+ });
456
+ const credential = await webauthn.create(creationOptions);
457
+ const publicKey = extractPublicKeyFromAttestationObject(credential.attestationObject);
458
+ return { credentialId: credential.id, publicKey };
459
+ }
460
+ async function createPasskey(options) {
461
+ const storage = options.storage ?? defaultCredentialStorage();
462
+ const { credentialId, publicKey } = await registerPasskey(options);
463
+ const { contractId } = await options.deployer.deploy({ publicKey, credentialId });
464
+ storage.set(options.rpId, credentialId);
465
+ return { contractId, credentialId, publicKey };
466
+ }
467
+
468
+ // src/webauthn/clientData.ts
469
+ function encodeChallenge(challenge) {
470
+ return bytesToBase64Url(challenge);
471
+ }
472
+ function decodeChallenge(challenge) {
473
+ return base64UrlToBytes(challenge);
474
+ }
475
+ function parseClientDataJSON(clientDataJSON) {
476
+ let raw;
477
+ try {
478
+ raw = JSON.parse(bytesToUtf8(clientDataJSON));
479
+ } catch (cause) {
480
+ throw new KitError("UNSUPPORTED_AUTHENTICATOR", "clientDataJSON is not valid JSON", { cause });
481
+ }
482
+ if (typeof raw !== "object" || raw === null) {
483
+ throw new KitError("UNSUPPORTED_AUTHENTICATOR", "clientDataJSON is not a JSON object");
484
+ }
485
+ const obj = raw;
486
+ const { type, challenge, origin, crossOrigin } = obj;
487
+ if (typeof type !== "string" || typeof challenge !== "string" || typeof origin !== "string") {
488
+ throw new KitError("UNSUPPORTED_AUTHENTICATOR", "clientDataJSON is missing required fields");
489
+ }
490
+ return {
491
+ type,
492
+ challenge,
493
+ origin,
494
+ crossOrigin: typeof crossOrigin === "boolean" ? crossOrigin : void 0
495
+ };
496
+ }
497
+ function verifyClientDataJSON(clientDataJSON, expected) {
498
+ const data = parseClientDataJSON(clientDataJSON);
499
+ if (data.type !== "webauthn.get") {
500
+ throw new KitError(
501
+ "UNSUPPORTED_AUTHENTICATOR",
502
+ `clientDataJSON.type "${data.type}" is not "webauthn.get"`
503
+ );
504
+ }
505
+ const allowed = Array.isArray(expected.origin) ? expected.origin : [expected.origin];
506
+ if (!allowed.includes(data.origin)) {
507
+ throw new KitError("ORIGIN_MISMATCH", `origin "${data.origin}" not in [${allowed.join(", ")}]`);
508
+ }
509
+ if (data.challenge !== expected.challenge) {
510
+ throw new KitError("CHALLENGE_MISMATCH", "clientDataJSON challenge does not match expected");
511
+ }
512
+ return data;
513
+ }
514
+
515
+ // src/soroban/address.ts
516
+ function contractIdFromDeployerSalt(deployer, salt, networkPassphrase) {
517
+ let address;
518
+ try {
519
+ address = stellarSdk.Address.fromString(deployer).toScAddress();
520
+ } catch (cause) {
521
+ throw new KitError("CONTRACT_AUTH_FAILED", `invalid deployer address "${deployer}"`, { cause });
522
+ }
523
+ const preimage = stellarSdk.xdr.HashIdPreimage.envelopeTypeContractId(
524
+ new stellarSdk.xdr.HashIdPreimageContractId({
525
+ networkId: stellarSdk.hash(Buffer.from(networkPassphrase)),
526
+ contractIdPreimage: stellarSdk.xdr.ContractIdPreimage.contractIdPreimageFromAddress(
527
+ new stellarSdk.xdr.ContractIdPreimageFromAddress({
528
+ address,
529
+ salt: Buffer.from(salt)
530
+ })
531
+ )
532
+ })
533
+ );
534
+ return stellarSdk.StrKey.encodeContract(stellarSdk.hash(preimage.toXDR()));
535
+ }
536
+ function deriveAccountAddress(options) {
537
+ const { factoryContractId, credentialId, networkPassphrase } = options;
538
+ if (credentialId.length === 0) {
539
+ throw new KitError("CONTRACT_AUTH_FAILED", "deriveAccountAddress: empty credential id");
540
+ }
541
+ return contractIdFromDeployerSalt(
542
+ factoryContractId,
543
+ stellarSdk.hash(Buffer.from(credentialId)),
544
+ // e.crypto().sha256(credential_id)
545
+ networkPassphrase
546
+ );
547
+ }
548
+ function deriveSmartWalletAddress(options) {
549
+ const raw = decodeChallenge(options.credentialId);
550
+ if (raw.length === 0) {
551
+ throw new KitError("CONTRACT_AUTH_FAILED", "deriveSmartWalletAddress: empty credential id");
552
+ }
553
+ return contractIdFromDeployerSalt(options.deployer, sha256.sha256(raw), options.networkPassphrase);
554
+ }
555
+ var MAX_DER_LENGTH = 72;
556
+ function derToCompact(der) {
557
+ if (der.length > MAX_DER_LENGTH) {
558
+ throw new KitError(
559
+ "INVALID_SIGNATURE_DER",
560
+ `DER signature is ${der.length} bytes, exceeds max ${MAX_DER_LENGTH}`
561
+ );
562
+ }
563
+ try {
564
+ return nist.p256.Signature.fromDER(der).toCompactRawBytes();
565
+ } catch (cause) {
566
+ throw new KitError("INVALID_SIGNATURE_DER", "failed to parse DER signature", { cause });
567
+ }
568
+ }
569
+ function assertCompactLength(compactSignature) {
570
+ if (compactSignature.length !== 64) {
571
+ throw new KitError(
572
+ "INVALID_SIGNATURE_DER",
573
+ `compact signature must be 64 bytes, got ${compactSignature.length}`
574
+ );
575
+ }
576
+ }
577
+ function isLowS(compactSignature) {
578
+ assertCompactLength(compactSignature);
579
+ return !nist.p256.Signature.fromCompact(compactSignature).hasHighS();
580
+ }
581
+ function normalizeLowS(compactSignature) {
582
+ assertCompactLength(compactSignature);
583
+ return nist.p256.Signature.fromCompact(compactSignature).normalizeS().toCompactRawBytes();
584
+ }
585
+ function derToCompactLowS(der) {
586
+ return normalizeLowS(derToCompact(der));
587
+ }
588
+
589
+ // src/webauthn/payload.ts
590
+ function reconstructSignedPayload(input) {
591
+ const clientDataHash = sha256.sha256(input.clientDataJSON);
592
+ return sha256.sha256(concatBytes(input.authenticatorData, clientDataHash));
593
+ }
594
+ function verifyAssertionSignature(input) {
595
+ const payload = reconstructSignedPayload(input);
596
+ const compact = input.signature.length === 64 ? input.signature : derToCompact(input.signature);
597
+ return nist.p256.verify(compact, payload, input.publicKey, { lowS: false, format: "compact" });
598
+ }
599
+
600
+ // src/ceremonies/browserSigner.ts
601
+ function browserPasskeySigner(options) {
602
+ const webauthn = options.webauthn ?? browserWebAuthnClient();
603
+ return async (challenge) => {
604
+ const assertion = await webauthn.get({
605
+ rpId: options.rpId,
606
+ challenge: base64UrlToBytes(challenge),
607
+ allowCredentials: options.allowCredentials ?? [],
608
+ userVerification: options.userVerification ?? "preferred"
609
+ });
610
+ return {
611
+ authenticatorData: assertion.authenticatorData,
612
+ clientDataJSON: assertion.clientDataJSON,
613
+ signature: assertion.signature,
614
+ credentialId: assertion.rawId
615
+ };
616
+ };
617
+ }
618
+ function authEntryChallengeBytes(entry, networkPassphrase) {
619
+ const credentials = entry.credentials();
620
+ if (credentials.switch().name !== "sorobanCredentialsAddress") {
621
+ throw new KitError("CONTRACT_AUTH_FAILED", "auth entry has no address credentials to sign");
622
+ }
623
+ const address = credentials.address();
624
+ const preimage = stellarSdk.xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(
625
+ new stellarSdk.xdr.HashIdPreimageSorobanAuthorization({
626
+ networkId: Buffer.from(stellarSdk.hash(Buffer.from(utf8ToBytes(networkPassphrase)))),
627
+ nonce: address.nonce(),
628
+ signatureExpirationLedger: address.signatureExpirationLedger(),
629
+ invocation: entry.rootInvocation()
630
+ })
631
+ );
632
+ return new Uint8Array(stellarSdk.hash(preimage.toXDR()));
633
+ }
634
+ function authEntryChallenge(entry, networkPassphrase) {
635
+ return bytesToBase64Url(authEntryChallengeBytes(entry, networkPassphrase));
636
+ }
637
+ function applyAssertionToEntry(entry, assertion) {
638
+ entry.credentials().address().signature(buildSignatureScVal(assertion));
639
+ return entry;
640
+ }
641
+ function buildSignatureScVal(assertion) {
642
+ return stellarSdk.xdr.ScVal.scvMap([
643
+ bytesField("authenticator_data", assertion.authenticatorData),
644
+ bytesField("client_data_json", assertion.clientDataJSON),
645
+ bytesField("signature", assertion.signature)
646
+ ]);
647
+ }
648
+ function bytesField(name, bytes) {
649
+ return new stellarSdk.xdr.ScMapEntry({
650
+ key: stellarSdk.xdr.ScVal.scvSymbol(name),
651
+ val: stellarSdk.xdr.ScVal.scvBytes(Buffer.from(bytes))
652
+ });
653
+ }
654
+ function buildSignerKeyScVal(credentialId) {
655
+ return stellarSdk.xdr.ScVal.scvVec([
656
+ stellarSdk.xdr.ScVal.scvSymbol("Secp256r1"),
657
+ stellarSdk.xdr.ScVal.scvBytes(Buffer.from(credentialId))
658
+ ]);
659
+ }
660
+ function buildSmartWalletSignatureVariant(assertion) {
661
+ return stellarSdk.xdr.ScVal.scvVec([stellarSdk.xdr.ScVal.scvSymbol("Secp256r1"), buildSignatureScVal(assertion)]);
662
+ }
663
+ function decomposeSignerKey(key) {
664
+ const vec = key.vec();
665
+ if (!vec || vec.length < 2) {
666
+ throw new KitError("CONTRACT_AUTH_FAILED", "malformed SignerKey (expected an enum vec)");
667
+ }
668
+ const variant = vec[0].sym().toString();
669
+ const el = vec[1];
670
+ const payload = el.switch().name === "scvBytes" ? new Uint8Array(el.bytes()) : new Uint8Array(el.toXDR());
671
+ return { variant, payload };
672
+ }
673
+ function compareBytes(a, b) {
674
+ const n = Math.min(a.length, b.length);
675
+ for (let i = 0; i < n; i++) {
676
+ if (a[i] !== b[i]) return a[i] < b[i] ? -1 : 1;
677
+ }
678
+ return a.length - b.length;
679
+ }
680
+ function compareSignerKeyScVal(a, b) {
681
+ const ka = decomposeSignerKey(a);
682
+ const kb = decomposeSignerKey(b);
683
+ if (ka.variant !== kb.variant) return ka.variant < kb.variant ? -1 : 1;
684
+ return compareBytes(ka.payload, kb.payload);
685
+ }
686
+ function applyAssertionToSmartWalletEntry(entry, assertion) {
687
+ const credentials = entry.credentials();
688
+ if (credentials.switch().name !== "sorobanCredentialsAddress") {
689
+ throw new KitError("CONTRACT_AUTH_FAILED", "auth entry has no address credentials to sign");
690
+ }
691
+ const key = buildSignerKeyScVal(assertion.credentialId);
692
+ const newEntry = new stellarSdk.xdr.ScMapEntry({ key, val: buildSmartWalletSignatureVariant(assertion) });
693
+ const current = credentials.address().signature();
694
+ let mapEntries;
695
+ switch (current.switch().name) {
696
+ case "scvVoid":
697
+ mapEntries = [newEntry];
698
+ break;
699
+ case "scvVec": {
700
+ const existing = current.vec()?.[0]?.map() ?? [];
701
+ mapEntries = existing.filter((e) => compareSignerKeyScVal(e.key(), key) !== 0);
702
+ mapEntries.push(newEntry);
703
+ break;
704
+ }
705
+ default:
706
+ throw new KitError(
707
+ "CONTRACT_AUTH_FAILED",
708
+ "unexpected existing signature shape for a smart-wallet entry"
709
+ );
710
+ }
711
+ mapEntries.sort((a, b) => compareSignerKeyScVal(a.key(), b.key()));
712
+ credentials.address().signature(stellarSdk.xdr.ScVal.scvVec([stellarSdk.xdr.ScVal.scvMap(mapEntries)]));
713
+ return entry;
714
+ }
715
+
716
+ // src/soroban/sign.ts
717
+ function preflightAssertion(assertion, challenge, verify) {
718
+ let clientData;
719
+ if (verify.origin !== void 0) {
720
+ clientData = verifyClientDataJSON(assertion.clientDataJSON, {
721
+ origin: verify.origin,
722
+ challenge
723
+ });
724
+ } else {
725
+ clientData = parseClientDataJSON(assertion.clientDataJSON);
726
+ if (clientData.type !== "webauthn.get") {
727
+ throw new KitError(
728
+ "UNSUPPORTED_AUTHENTICATOR",
729
+ `clientDataJSON.type "${clientData.type}" is not "webauthn.get"`
730
+ );
731
+ }
732
+ if (clientData.challenge !== challenge) {
733
+ throw new KitError("CHALLENGE_MISMATCH", "assertion challenge does not match the auth entry");
734
+ }
735
+ }
736
+ if (clientData.crossOrigin === true && !verify.allowCrossOrigin) {
737
+ throw new KitError(
738
+ "ORIGIN_MISMATCH",
739
+ "assertion was made in a cross-origin context (crossOrigin=true)"
740
+ );
741
+ }
742
+ const parsed = parseAuthenticatorData(assertion.authenticatorData);
743
+ if (!parsed.flags.up) {
744
+ throw new KitError(
745
+ "UNSUPPORTED_AUTHENTICATOR",
746
+ "assertion is missing the User-Present (UP) flag"
747
+ );
748
+ }
749
+ if (verify.requireUserVerification && !parsed.flags.uv) {
750
+ throw new KitError(
751
+ "UNSUPPORTED_AUTHENTICATOR",
752
+ "assertion is missing the required User-Verified (UV) flag"
753
+ );
754
+ }
755
+ if (verify.rpId !== void 0) {
756
+ verifyRpIdHash(assertion.authenticatorData, verify.rpId);
757
+ }
758
+ if (verify.publicKey !== void 0) {
759
+ const ok = verifyAssertionSignature({
760
+ publicKey: verify.publicKey,
761
+ authenticatorData: assertion.authenticatorData,
762
+ clientDataJSON: assertion.clientDataJSON,
763
+ signature: assertion.signature
764
+ });
765
+ if (!ok) {
766
+ throw new KitError(
767
+ "CONTRACT_AUTH_FAILED",
768
+ "assertion signature failed pre-flight verification"
769
+ );
770
+ }
771
+ }
772
+ }
773
+ async function signEntryInPlace(entry, options) {
774
+ if (options.signatureExpirationLedger !== void 0) {
775
+ const creds = entry.credentials();
776
+ if (creds.switch().name === "sorobanCredentialsAddress") {
777
+ creds.address().signatureExpirationLedger(options.signatureExpirationLedger);
778
+ }
779
+ }
780
+ const challenge = authEntryChallenge(entry, options.networkPassphrase);
781
+ const assertion = await options.sign(challenge);
782
+ if (options.verify) preflightAssertion(assertion, challenge, options.verify);
783
+ const signature = assertion.signature.length === 64 ? assertion.signature : derToCompactLowS(assertion.signature);
784
+ const normalized = {
785
+ credentialId: assertion.credentialId,
786
+ authenticatorData: assertion.authenticatorData,
787
+ clientDataJSON: assertion.clientDataJSON,
788
+ signature
789
+ };
790
+ if (options.target === "smart-wallet") {
791
+ applyAssertionToSmartWalletEntry(entry, normalized);
792
+ } else {
793
+ applyAssertionToEntry(entry, normalized);
794
+ }
795
+ }
796
+ async function signAuthEntry(entryXdr, options) {
797
+ const entry = stellarSdk.xdr.SorobanAuthorizationEntry.fromXDR(entryXdr, "base64");
798
+ await signEntryInPlace(entry, options);
799
+ return entry.toXDR("base64");
800
+ }
801
+ function operationsForSigning(envelope) {
802
+ const kind = envelope.switch().name;
803
+ if (kind === "envelopeTypeTx") return envelope.v1().tx().operations();
804
+ if (kind === "envelopeTypeTxFeeBump") {
805
+ const inner = envelope.feeBump().tx().innerTx();
806
+ if (inner.switch().name !== "envelopeTypeTx") {
807
+ throw new KitError(
808
+ "CONTRACT_AUTH_FAILED",
809
+ "signTransaction: fee-bump inner transaction is not a v1 transaction"
810
+ );
811
+ }
812
+ return inner.v1().tx().operations();
813
+ }
814
+ throw new KitError(
815
+ "CONTRACT_AUTH_FAILED",
816
+ `signTransaction: unsupported envelope type "${kind}" (expected v1 or fee-bump)`
817
+ );
818
+ }
819
+ async function signTransaction(txXdr, options) {
820
+ const envelope = stellarSdk.xdr.TransactionEnvelope.fromXDR(txXdr, "base64");
821
+ for (const op of operationsForSigning(envelope)) {
822
+ if (op.body().switch().name !== "invokeHostFunction") continue;
823
+ const entries = op.body().invokeHostFunctionOp().auth();
824
+ for (const entry of entries) {
825
+ if (entry.credentials().switch().name !== "sorobanCredentialsAddress") continue;
826
+ await signEntryInPlace(entry, options);
827
+ }
828
+ }
829
+ return envelope.toXDR("base64");
830
+ }
831
+ function noneTuple() {
832
+ return stellarSdk.xdr.ScVal.scvVec([stellarSdk.xdr.ScVal.scvVoid()]);
833
+ }
834
+ function expirationScVal(expiration) {
835
+ if (expiration === void 0) return noneTuple();
836
+ const ts = BigInt(expiration);
837
+ if (ts < 0n) {
838
+ throw new KitError(
839
+ "CONTRACT_AUTH_FAILED",
840
+ "signer expiration must be a non-negative UNIX-seconds timestamp (v1)"
841
+ );
842
+ }
843
+ return stellarSdk.xdr.ScVal.scvVec([stellarSdk.nativeToScVal(ts, { type: "u64" })]);
844
+ }
845
+ function storageScVal(storage = "Persistent") {
846
+ return stellarSdk.xdr.ScVal.scvVec([stellarSdk.xdr.ScVal.scvSymbol(storage)]);
847
+ }
848
+ function buildSecp256r1Signer(spec) {
849
+ if (spec.credentialId.length === 0) {
850
+ throw new KitError("CONTRACT_AUTH_FAILED", "buildSecp256r1Signer: empty credential id");
851
+ }
852
+ if (spec.publicKey.length !== 65 || spec.publicKey[0] !== 4) {
853
+ throw new KitError(
854
+ "INVALID_PUBLIC_KEY",
855
+ "buildSecp256r1Signer: publicKey must be a 65-byte SEC-1 uncompressed point (0x04-prefixed)"
856
+ );
857
+ }
858
+ return stellarSdk.xdr.ScVal.scvVec([
859
+ stellarSdk.xdr.ScVal.scvSymbol("Secp256r1"),
860
+ stellarSdk.xdr.ScVal.scvBytes(Buffer.from(spec.credentialId)),
861
+ stellarSdk.xdr.ScVal.scvBytes(Buffer.from(spec.publicKey)),
862
+ expirationScVal(spec.expiration),
863
+ // SignerExpiration
864
+ noneTuple(),
865
+ // SignerLimits(None)
866
+ storageScVal(spec.storage)
867
+ // SignerStorage
868
+ ]);
869
+ }
870
+ function contractCall(contractId, method, ...args) {
871
+ let contract;
872
+ try {
873
+ contract = new stellarSdk.Contract(contractId);
874
+ } catch (cause) {
875
+ throw new KitError("CONTRACT_AUTH_FAILED", `invalid smart-wallet contract id "${contractId}"`, {
876
+ cause
877
+ });
878
+ }
879
+ return contract.call(method, ...args);
880
+ }
881
+ function buildAddSignerOperation(options) {
882
+ const signerScVal = options.signer instanceof stellarSdk.xdr.ScVal ? options.signer : buildSecp256r1Signer(options.signer);
883
+ return contractCall(options.walletContractId, "add_signer", signerScVal);
884
+ }
885
+ function buildRemoveSignerOperation(options) {
886
+ if (options.credentialId.length === 0) {
887
+ throw new KitError("CONTRACT_AUTH_FAILED", "buildRemoveSignerOperation: empty credential id");
888
+ }
889
+ return contractCall(
890
+ options.walletContractId,
891
+ "remove_signer",
892
+ buildSignerKeyScVal(options.credentialId)
893
+ );
894
+ }
895
+ function fail(reason) {
896
+ return { success: false, challengeBound: false, signatureValid: false, reason };
897
+ }
898
+ function verifySecp256r1StructMap(structMap, publicKey, signaturePayload) {
899
+ const field = (name) => {
900
+ const e = structMap.find((x) => x.key().sym().toString() === name);
901
+ return e ? new Uint8Array(e.val().bytes()) : void 0;
902
+ };
903
+ const authenticatorData = field("authenticator_data");
904
+ const clientDataJSON = field("client_data_json");
905
+ const signature = field("signature");
906
+ if (!authenticatorData || !clientDataJSON || !signature) {
907
+ return { ok: false, challengeBound: false, signatureValid: false, reason: "missing fields" };
908
+ }
909
+ if (signature.length !== 64) {
910
+ return {
911
+ ok: false,
912
+ challengeBound: false,
913
+ signatureValid: false,
914
+ reason: "not 64-byte compact"
915
+ };
916
+ }
917
+ let challengeBound = false;
918
+ try {
919
+ const cdj = JSON.parse(bytesToUtf8(clientDataJSON));
920
+ challengeBound = cdj.challenge === bytesToBase64Url(signaturePayload);
921
+ } catch {
922
+ challengeBound = false;
923
+ }
924
+ const digest = sha256.sha256(concatBytes(authenticatorData, sha256.sha256(clientDataJSON)));
925
+ const signatureValid = nist.p256.verify(signature, digest, publicKey, {
926
+ lowS: false,
927
+ format: "compact"
928
+ });
929
+ return { ok: challengeBound && signatureValid, challengeBound, signatureValid };
930
+ }
931
+ function referenceCheckAuth(entry, publicKey, networkPassphrase) {
932
+ if (entry.credentials().switch().name !== "sorobanCredentialsAddress") {
933
+ return fail("no address credentials");
934
+ }
935
+ const structMap = entry.credentials().address().signature().map();
936
+ if (!structMap) return fail("signature is not a Secp256r1Signature map");
937
+ const signaturePayload = authEntryChallengeBytes(entry, networkPassphrase);
938
+ const r = verifySecp256r1StructMap(structMap, publicKey, signaturePayload);
939
+ return { success: r.ok, challengeBound: r.challengeBound, signatureValid: r.signatureValid };
940
+ }
941
+ function referenceSmartWalletCheckAuth(entry, publicKeyFor, networkPassphrase) {
942
+ if (entry.credentials().switch().name !== "sorobanCredentialsAddress") {
943
+ return { success: false, signers: [], reason: "no address credentials" };
944
+ }
945
+ const sig = entry.credentials().address().signature();
946
+ const map = sig.switch().name === "scvVec" ? sig.vec()?.[0]?.map() : void 0;
947
+ if (!map) {
948
+ return { success: false, signers: [], reason: "signature is not a Signatures(Map) vec" };
949
+ }
950
+ if (map.length === 0) return { success: false, signers: [], reason: "empty signatures map" };
951
+ const signaturePayload = authEntryChallengeBytes(entry, networkPassphrase);
952
+ const signers = [];
953
+ let allOk = true;
954
+ for (const e of map) {
955
+ const keyVec = e.key().vec();
956
+ const idBytes = keyVec?.[1]?.bytes();
957
+ const credentialId = idBytes ? Buffer.from(idBytes).toString("hex") : "";
958
+ const structMap = e.val().vec()?.[1]?.map();
959
+ const publicKey = publicKeyFor(credentialId);
960
+ if (!structMap || !publicKey) {
961
+ allOk = false;
962
+ signers.push({ credentialId, challengeBound: false, signatureValid: false });
963
+ continue;
964
+ }
965
+ const r = verifySecp256r1StructMap(structMap, publicKey, signaturePayload);
966
+ if (!r.ok) allOk = false;
967
+ signers.push({
968
+ credentialId,
969
+ challengeBound: r.challengeBound,
970
+ signatureValid: r.signatureValid
971
+ });
972
+ }
973
+ return { success: allOk, signers };
974
+ }
975
+ function directSubmission(options) {
976
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
977
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
978
+ });
979
+ const attempts = options.pollAttempts ?? 30;
980
+ const intervalMs = options.pollIntervalMs ?? 1e3;
981
+ return {
982
+ async send(signedTxXdr) {
983
+ const tx = stellarSdk.TransactionBuilder.fromXDR(signedTxXdr, options.networkPassphrase);
984
+ let sent;
985
+ try {
986
+ sent = await server.sendTransaction(tx);
987
+ } catch (cause) {
988
+ throw new KitError("NETWORK_ERROR", "failed to submit transaction to soroban-rpc", {
989
+ cause
990
+ });
991
+ }
992
+ if (sent.status === "ERROR") {
993
+ return {
994
+ status: "FAILED",
995
+ hash: sent.hash,
996
+ errorResultXdr: sent.errorResult?.toXDR("base64")
997
+ };
998
+ }
999
+ let final;
1000
+ try {
1001
+ final = await server.pollTransaction(sent.hash, {
1002
+ attempts,
1003
+ sleepStrategy: () => intervalMs
1004
+ });
1005
+ } catch (cause) {
1006
+ throw new KitError(
1007
+ "NETWORK_ERROR",
1008
+ `transaction ${sent.hash} was not confirmed after ${String(attempts)} polls`,
1009
+ { cause }
1010
+ );
1011
+ }
1012
+ if (final.status === stellarSdk.rpc.Api.GetTransactionStatus.NOT_FOUND) {
1013
+ throw new KitError(
1014
+ "NETWORK_ERROR",
1015
+ `transaction ${sent.hash} still NOT_FOUND after ${String(attempts)} polls`
1016
+ );
1017
+ }
1018
+ const success = final.status === stellarSdk.rpc.Api.GetTransactionStatus.SUCCESS;
1019
+ return {
1020
+ status: success ? "SUCCESS" : "FAILED",
1021
+ hash: sent.hash,
1022
+ returnValue: success ? final.returnValue : void 0
1023
+ };
1024
+ }
1025
+ };
1026
+ }
1027
+
1028
+ // src/soroban/submit.ts
1029
+ var DEFAULT_EXPIRATION_OFFSET = 60;
1030
+ async function sendSmartWalletTx(options) {
1031
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
1032
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
1033
+ });
1034
+ let source;
1035
+ try {
1036
+ source = stellarSdk.Keypair.fromSecret(options.sourceSecret);
1037
+ } catch (cause) {
1038
+ throw new KitError("CONTRACT_AUTH_FAILED", "invalid fee-source secret", { cause });
1039
+ }
1040
+ const account = await server.getAccount(source.publicKey());
1041
+ const tx = new stellarSdk.TransactionBuilder(account, {
1042
+ fee: options.fee ?? "2000000",
1043
+ networkPassphrase: options.networkPassphrase
1044
+ }).addOperation(options.operation).setTimeout(options.timeoutSeconds ?? 120).build();
1045
+ const recSim = await server.simulateTransaction(tx);
1046
+ if (!stellarSdk.rpc.Api.isSimulationSuccess(recSim)) {
1047
+ const detail = "error" in recSim ? String(recSim.error) : "unknown simulation error";
1048
+ throw new KitError(
1049
+ "CONTRACT_AUTH_FAILED",
1050
+ `smart-wallet tx simulation failed: ${detail.slice(0, 300)}`
1051
+ );
1052
+ }
1053
+ const prepared = stellarSdk.rpc.assembleTransaction(tx, recSim).build();
1054
+ const signatureExpirationLedger = (await server.getLatestLedger()).sequence + (options.signatureExpirationLedgerOffset ?? DEFAULT_EXPIRATION_OFFSET);
1055
+ const signedAuthXdr = await signTransaction(prepared.toXDR(), {
1056
+ networkPassphrase: options.networkPassphrase,
1057
+ sign: options.sign,
1058
+ target: "smart-wallet",
1059
+ signatureExpirationLedger,
1060
+ verify: options.verify
1061
+ });
1062
+ const signedTx = stellarSdk.TransactionBuilder.fromXDR(signedAuthXdr, options.networkPassphrase);
1063
+ const enfSim = await server.simulateTransaction(signedTx);
1064
+ if (!stellarSdk.rpc.Api.isSimulationSuccess(enfSim)) {
1065
+ const detail = "error" in enfSim ? String(enfSim.error) : "unknown simulation error";
1066
+ throw new KitError(
1067
+ "CONTRACT_AUTH_FAILED",
1068
+ `signed smart-wallet tx failed enforcing simulation (auth rejected?): ${detail.slice(0, 300)}`
1069
+ );
1070
+ }
1071
+ const finalTx = stellarSdk.rpc.assembleTransaction(signedTx, enfSim).build();
1072
+ finalTx.sign(source);
1073
+ const submission = options.submission ?? directSubmission({
1074
+ rpcUrl: options.rpcUrl,
1075
+ networkPassphrase: options.networkPassphrase,
1076
+ allowHttp: options.allowHttp
1077
+ });
1078
+ return submission.send(finalTx.toXDR());
1079
+ }
1080
+
1081
+ // src/ceremonies/connect.ts
1082
+ async function probeConditionalMediation() {
1083
+ const pkc = globalThis.PublicKeyCredential;
1084
+ if (!pkc?.isConditionalMediationAvailable) return false;
1085
+ try {
1086
+ return await pkc.isConditionalMediationAvailable();
1087
+ } catch {
1088
+ return false;
1089
+ }
1090
+ }
1091
+ async function connect(options) {
1092
+ const storage = options.storage ?? defaultCredentialStorage();
1093
+ const credentialId = storage.get(options.rpId);
1094
+ if (!credentialId) return null;
1095
+ const silentSupported = options.silentMediationSupported ?? await probeConditionalMediation();
1096
+ if (silentSupported) {
1097
+ const webauthn = options.webauthn ?? browserWebAuthnClient();
1098
+ try {
1099
+ await webauthn.get({
1100
+ rpId: options.rpId,
1101
+ allowCredentials: [credentialId],
1102
+ mediation: "silent"
1103
+ });
1104
+ } catch {
1105
+ }
1106
+ }
1107
+ const accounts = await options.indexer.resolveByCredential(credentialId);
1108
+ const contractId = accounts[0]?.contractId;
1109
+ return contractId ? { contractId, credentialId } : null;
1110
+ }
1111
+
1112
+ // src/ceremonies/recover.ts
1113
+ async function recover(options) {
1114
+ assertUserActivation(options.userActivation);
1115
+ const webauthn = options.webauthn ?? browserWebAuthnClient();
1116
+ const assertion = await webauthn.get({
1117
+ rpId: options.rpId,
1118
+ allowCredentials: [],
1119
+ challenge: options.challenge ?? randomBytes(32)
1120
+ });
1121
+ const accounts = await options.indexer.resolveByCredential(assertion.id);
1122
+ return accounts.map((account) => ({
1123
+ contractId: account.contractId,
1124
+ credentialId: assertion.id
1125
+ }));
1126
+ }
1127
+
1128
+ // src/ceremonies/addDevice.ts
1129
+ function toRawCredentialId(id) {
1130
+ return typeof id === "string" ? decodeChallenge(id) : id;
1131
+ }
1132
+ async function addSigner(options) {
1133
+ const { walletContractId, newSigner, ...wiring } = options;
1134
+ const operation = buildAddSignerOperation({
1135
+ walletContractId,
1136
+ signer: {
1137
+ credentialId: toRawCredentialId(newSigner.credentialId),
1138
+ publicKey: newSigner.publicKey,
1139
+ expiration: newSigner.expiration,
1140
+ storage: newSigner.storage
1141
+ }
1142
+ });
1143
+ return sendSmartWalletTx({ ...wiring, operation });
1144
+ }
1145
+ async function removeSigner(options) {
1146
+ const { walletContractId, credentialId, ...wiring } = options;
1147
+ const operation = buildRemoveSignerOperation({
1148
+ walletContractId,
1149
+ credentialId: toRawCredentialId(credentialId)
1150
+ });
1151
+ return sendSmartWalletTx({ ...wiring, operation });
1152
+ }
1153
+
1154
+ // src/adapters/http.ts
1155
+ var sleep = (ms) => ms > 0 ? new Promise((resolve) => setTimeout(resolve, ms)) : Promise.resolve();
1156
+ function isTransientStatus(status) {
1157
+ return status === 429 || status >= 500;
1158
+ }
1159
+ async function httpPost(url, init, retry) {
1160
+ const attempts = Math.max(1, retry?.retries ?? 1);
1161
+ const backoffMs = retry?.backoffMs ?? 300;
1162
+ for (let i = 1; i <= attempts; i++) {
1163
+ try {
1164
+ const response = await fetch(url, {
1165
+ method: "POST",
1166
+ headers: init.headers,
1167
+ body: init.body
1168
+ });
1169
+ if (isTransientStatus(response.status) && i < attempts) {
1170
+ await sleep(backoffMs * i);
1171
+ continue;
1172
+ }
1173
+ return response;
1174
+ } catch (cause) {
1175
+ if (i < attempts) {
1176
+ await sleep(backoffMs * i);
1177
+ continue;
1178
+ }
1179
+ throw new KitError("NETWORK_ERROR", `POST to ${url} failed`, { cause });
1180
+ }
1181
+ }
1182
+ throw new KitError("NETWORK_ERROR", `POST to ${url} failed`);
1183
+ }
1184
+
1185
+ // src/adapters/launchtube.ts
1186
+ function launchtubeSubmission(options) {
1187
+ return {
1188
+ async send(signedTxXdr) {
1189
+ const headers = {
1190
+ "content-type": "application/x-www-form-urlencoded"
1191
+ };
1192
+ if (options.token) headers["authorization"] = `Bearer ${options.token}`;
1193
+ const response = await httpPost(
1194
+ options.url,
1195
+ { headers, body: new URLSearchParams({ xdr: signedTxXdr }).toString() },
1196
+ options.retry
1197
+ );
1198
+ const body = await response.json().catch(() => ({}));
1199
+ if (!response.ok || body.status === "FAILED" || body.error) {
1200
+ return { status: "FAILED", hash: body.hash ?? "", errorResultXdr: body.errorResultXdr };
1201
+ }
1202
+ return { status: "SUCCESS", hash: body.hash ?? "", returnValue: body };
1203
+ }
1204
+ };
1205
+ }
1206
+
1207
+ // src/adapters/ozRelayer.ts
1208
+ function openzeppelinRelayerSubmission(options) {
1209
+ return {
1210
+ async send(signedTxXdr) {
1211
+ const headers = { "content-type": "application/json" };
1212
+ if (options.apiKey) headers["authorization"] = `Bearer ${options.apiKey}`;
1213
+ const response = await httpPost(
1214
+ options.url,
1215
+ { headers, body: JSON.stringify({ transaction_xdr: signedTxXdr }) },
1216
+ options.retry
1217
+ );
1218
+ const body = await response.json().catch(() => ({}));
1219
+ if (!response.ok || body.status === "failed") {
1220
+ return { status: "FAILED", hash: body.hash ?? "", errorResultXdr: body.errorResultXdr };
1221
+ }
1222
+ return { status: "SUCCESS", hash: body.hash ?? "", returnValue: body };
1223
+ }
1224
+ };
1225
+ }
1226
+
1227
+ // src/adapters/eventsPaging.ts
1228
+ var EVENTS_PAGE_LIMIT = 1e4;
1229
+ var MAX_EVENT_PAGES = 40;
1230
+ function cursorLedger(cursor) {
1231
+ try {
1232
+ const toid = cursor.split("-")[0];
1233
+ if (!toid) return null;
1234
+ return Number(BigInt(toid) >> 32n);
1235
+ } catch {
1236
+ return null;
1237
+ }
1238
+ }
1239
+ function parseOldestLedger(error) {
1240
+ const raw = typeof error === "object" && error !== null && "message" in error ? error.message : error;
1241
+ const message = typeof raw === "string" ? raw : String(raw);
1242
+ const match = /ledger range:\s*(\d+)\s*-\s*\d+/.exec(message);
1243
+ return match ? Number(match[1]) : null;
1244
+ }
1245
+ async function collectEventsToTip(server, filters, startLedger) {
1246
+ const events = [];
1247
+ let start = startLedger;
1248
+ let cursor;
1249
+ let previousCursor;
1250
+ for (let page = 0; page < MAX_EVENT_PAGES; page++) {
1251
+ let response;
1252
+ try {
1253
+ response = await server.getEvents(
1254
+ cursor ? { filters, cursor, limit: EVENTS_PAGE_LIMIT } : { filters, startLedger: start, limit: EVENTS_PAGE_LIMIT }
1255
+ );
1256
+ } catch (error) {
1257
+ const oldest = parseOldestLedger(error);
1258
+ if (!cursor && oldest != null && start <= oldest) {
1259
+ start = oldest + 2;
1260
+ continue;
1261
+ }
1262
+ throw error;
1263
+ }
1264
+ events.push(...response.events);
1265
+ previousCursor = cursor;
1266
+ cursor = response.cursor;
1267
+ if (!cursor || cursor === previousCursor) break;
1268
+ const scanned = cursorLedger(cursor);
1269
+ if (scanned != null && scanned >= response.latestLedger) break;
1270
+ }
1271
+ return events;
1272
+ }
1273
+
1274
+ // src/adapters/events.ts
1275
+ function decodeNative(scv) {
1276
+ try {
1277
+ return stellarSdk.scValToNative(scv);
1278
+ } catch {
1279
+ return void 0;
1280
+ }
1281
+ }
1282
+ var LEDGERS_PER_DAY = 17280;
1283
+ function defaultMatch(event, credentialId) {
1284
+ try {
1285
+ const topics = event.topic ?? [];
1286
+ if (topics.length >= 2) {
1287
+ const tag = decodeNative(topics[0]);
1288
+ const credRaw = decodeNative(topics[1]);
1289
+ const cred = credRaw instanceof Uint8Array ? new TextDecoder().decode(credRaw) : String(credRaw ?? "");
1290
+ if (tag === "deployed" && cred === credentialId) {
1291
+ const addr2 = decodeNative(event.value);
1292
+ if (typeof addr2 === "string" && addr2.startsWith("C")) return { contractId: addr2 };
1293
+ }
1294
+ }
1295
+ const haystack = [event.value, ...topics].map((v) => v.toXDR("base64")).join("|");
1296
+ if (!haystack.includes(credentialId)) return null;
1297
+ const addr = decodeNative(event.value);
1298
+ if (typeof addr === "string" && addr.startsWith("C")) return { contractId: addr };
1299
+ return event.contractId ? { contractId: event.contractId.toString() } : null;
1300
+ } catch {
1301
+ return null;
1302
+ }
1303
+ }
1304
+ function eventsIndexer(options) {
1305
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
1306
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
1307
+ });
1308
+ const match = options.matchEvent ?? defaultMatch;
1309
+ return {
1310
+ async resolveByCredential(credentialId) {
1311
+ const startLedger = options.startLedger ?? Math.max(1, (await server.getLatestLedger()).sequence - LEDGERS_PER_DAY);
1312
+ const events = await collectEventsToTip(
1313
+ server,
1314
+ [{ type: "contract", contractIds: [options.factoryContractId] }],
1315
+ startLedger
1316
+ );
1317
+ const accounts = [];
1318
+ for (const event of events) {
1319
+ const resolved = match(event, credentialId);
1320
+ if (resolved) accounts.push(resolved);
1321
+ }
1322
+ return accounts;
1323
+ }
1324
+ };
1325
+ }
1326
+
1327
+ // src/adapters/mercury.ts
1328
+ function mercuryIndexer(options) {
1329
+ const parse = options.parse ?? ((json) => {
1330
+ const rows = json.accounts ?? [];
1331
+ return rows.flatMap((r) => r.contractId ? [{ contractId: r.contractId }] : []);
1332
+ });
1333
+ return {
1334
+ async resolveByCredential(credentialId) {
1335
+ const headers = { "content-type": "application/json" };
1336
+ if (options.token) headers["authorization"] = `Bearer ${options.token}`;
1337
+ const response = await httpPost(
1338
+ options.url,
1339
+ { headers, body: JSON.stringify({ credentialId }) },
1340
+ options.retry
1341
+ );
1342
+ if (!response.ok) {
1343
+ throw new KitError(
1344
+ "NETWORK_ERROR",
1345
+ `mercury indexer returned HTTP ${String(response.status)}`
1346
+ );
1347
+ }
1348
+ return parse(await response.json().catch(() => ({})));
1349
+ }
1350
+ };
1351
+ }
1352
+
1353
+ // src/adapters/defaults.ts
1354
+ function defaultAdapters(options) {
1355
+ return {
1356
+ submission: directSubmission({
1357
+ rpcUrl: options.rpcUrl,
1358
+ networkPassphrase: options.networkPassphrase,
1359
+ allowHttp: options.allowHttp
1360
+ }),
1361
+ indexer: eventsIndexer({
1362
+ rpcUrl: options.rpcUrl,
1363
+ factoryContractId: options.factoryContractId,
1364
+ allowHttp: options.allowHttp
1365
+ })
1366
+ };
1367
+ }
1368
+ function factoryDeployer(options) {
1369
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
1370
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
1371
+ });
1372
+ const source = stellarSdk.Keypair.fromSecret(options.sourceSecret);
1373
+ return {
1374
+ async deploy(input) {
1375
+ const pk = stellarSdk.nativeToScVal(Buffer.from(input.publicKey), { type: "bytes" });
1376
+ const cred = stellarSdk.nativeToScVal(Buffer.from(new TextEncoder().encode(input.credentialId)), {
1377
+ type: "bytes"
1378
+ });
1379
+ const account = await server.getAccount(source.publicKey());
1380
+ const tx = new stellarSdk.TransactionBuilder(account, {
1381
+ fee: options.fee ?? "2000000",
1382
+ networkPassphrase: options.networkPassphrase
1383
+ }).addOperation(new stellarSdk.Contract(options.factoryContractId).call("deploy", pk, cred)).setTimeout(120).build();
1384
+ const sim = await server.simulateTransaction(tx);
1385
+ if (!stellarSdk.rpc.Api.isSimulationSuccess(sim)) {
1386
+ throw new KitError("CONTRACT_AUTH_FAILED", "factory deploy simulation failed");
1387
+ }
1388
+ const prepared = stellarSdk.rpc.assembleTransaction(tx, sim).build();
1389
+ prepared.sign(source);
1390
+ const sent = await server.sendTransaction(prepared);
1391
+ if (sent.status === "ERROR") {
1392
+ throw new KitError("NETWORK_ERROR", "factory deploy submit error");
1393
+ }
1394
+ const final = await server.pollTransaction(sent.hash);
1395
+ if (final.status !== stellarSdk.rpc.Api.GetTransactionStatus.SUCCESS) {
1396
+ throw new KitError("CONTRACT_AUTH_FAILED", `factory deploy ${final.status}`);
1397
+ }
1398
+ const ret = final.returnValue;
1399
+ const contractId = ret ? String(stellarSdk.scValToNative(ret)) : "";
1400
+ return { contractId, txHash: sent.hash };
1401
+ }
1402
+ };
1403
+ }
1404
+ var SMART_WALLET_V1_WASM_HASH = "84924c53a413318df2ce753e30de53ec651404c916d30e861718ad155c94b319";
1405
+ function smartWalletV1Deployer(options) {
1406
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
1407
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
1408
+ });
1409
+ const source = stellarSdk.Keypair.fromSecret(options.deployerSecret);
1410
+ const wasmHash = options.wasmHash ?? SMART_WALLET_V1_WASM_HASH;
1411
+ return {
1412
+ async deploy(input) {
1413
+ const raw = decodeChallenge(input.credentialId);
1414
+ const contractId = deriveSmartWalletAddress({
1415
+ deployer: source.publicKey(),
1416
+ credentialId: input.credentialId,
1417
+ networkPassphrase: options.networkPassphrase
1418
+ });
1419
+ const op = stellarSdk.Operation.createCustomContract({
1420
+ address: stellarSdk.Address.fromString(source.publicKey()),
1421
+ wasmHash: Buffer.from(wasmHash, "hex"),
1422
+ salt: Buffer.from(sha256.sha256(raw)),
1423
+ constructorArgs: [buildSecp256r1Signer({ credentialId: raw, publicKey: input.publicKey })]
1424
+ });
1425
+ const account = await server.getAccount(source.publicKey());
1426
+ const tx = new stellarSdk.TransactionBuilder(account, {
1427
+ fee: options.fee ?? "10000000",
1428
+ networkPassphrase: options.networkPassphrase
1429
+ }).addOperation(op).setTimeout(120).build();
1430
+ const sim = await server.simulateTransaction(tx);
1431
+ if (!stellarSdk.rpc.Api.isSimulationSuccess(sim)) {
1432
+ throw new KitError("CONTRACT_AUTH_FAILED", "smart-wallet v1 deploy simulation failed");
1433
+ }
1434
+ const prepared = stellarSdk.rpc.assembleTransaction(tx, sim).build();
1435
+ prepared.sign(source);
1436
+ const sent = await server.sendTransaction(prepared);
1437
+ if (sent.status === "ERROR") {
1438
+ throw new KitError("NETWORK_ERROR", "smart-wallet v1 deploy submit error");
1439
+ }
1440
+ const final = await server.pollTransaction(sent.hash);
1441
+ if (final.status !== stellarSdk.rpc.Api.GetTransactionStatus.SUCCESS) {
1442
+ throw new KitError("CONTRACT_AUTH_FAILED", `smart-wallet v1 deploy ${final.status}`);
1443
+ }
1444
+ return { contractId, txHash: sent.hash };
1445
+ }
1446
+ };
1447
+ }
1448
+ var LEDGERS_PER_DAY2 = 17280;
1449
+ function smartWalletV1Indexer(options) {
1450
+ const server = new stellarSdk.rpc.Server(options.rpcUrl, {
1451
+ allowHttp: options.allowHttp ?? options.rpcUrl.startsWith("http://")
1452
+ });
1453
+ return {
1454
+ async resolveByCredential(credentialId) {
1455
+ const raw = decodeChallenge(credentialId);
1456
+ const filters = [
1457
+ {
1458
+ type: "contract",
1459
+ topics: [
1460
+ [
1461
+ stellarSdk.xdr.ScVal.scvSymbol("signer_added").toXDR("base64"),
1462
+ buildSignerKeyScVal(raw).toXDR("base64")
1463
+ ]
1464
+ ]
1465
+ }
1466
+ ];
1467
+ const startLedger = options.startLedger ?? Math.max(1, (await server.getLatestLedger()).sequence - LEDGERS_PER_DAY2);
1468
+ const events = await collectEventsToTip(server, filters, startLedger);
1469
+ const seen = /* @__PURE__ */ new Set();
1470
+ const accounts = [];
1471
+ for (const event of events) {
1472
+ const contractId = event.contractId?.toString();
1473
+ if (contractId && !seen.has(contractId)) {
1474
+ seen.add(contractId);
1475
+ accounts.push({ contractId });
1476
+ }
1477
+ }
1478
+ return accounts;
1479
+ }
1480
+ };
1481
+ }
1482
+
1483
+ exports.BATTLE_TESTED_ANCHORS = BATTLE_TESTED_ANCHORS;
1484
+ exports.KIT_ERROR_CODES = KIT_ERROR_CODES;
1485
+ exports.KitError = KitError;
1486
+ exports.SMART_WALLET_V1_WASM_HASH = SMART_WALLET_V1_WASM_HASH;
1487
+ exports.addSigner = addSigner;
1488
+ exports.applyAssertionToEntry = applyAssertionToEntry;
1489
+ exports.applyAssertionToSmartWalletEntry = applyAssertionToSmartWalletEntry;
1490
+ exports.assertES256 = assertES256;
1491
+ exports.assertUserActivation = assertUserActivation;
1492
+ exports.authEntryChallenge = authEntryChallenge;
1493
+ exports.authEntryChallengeBytes = authEntryChallengeBytes;
1494
+ exports.browserPasskeySigner = browserPasskeySigner;
1495
+ exports.browserWebAuthnClient = browserWebAuthnClient;
1496
+ exports.buildAddSignerOperation = buildAddSignerOperation;
1497
+ exports.buildCreateOptions = buildCreateOptions;
1498
+ exports.buildRemoveSignerOperation = buildRemoveSignerOperation;
1499
+ exports.buildSecp256r1Signer = buildSecp256r1Signer;
1500
+ exports.buildSignerKeyScVal = buildSignerKeyScVal;
1501
+ exports.buildSmartWalletSignatureVariant = buildSmartWalletSignatureVariant;
1502
+ exports.compareSignerKeyScVal = compareSignerKeyScVal;
1503
+ exports.connect = connect;
1504
+ exports.coseKeyToSec1 = coseKeyToSec1;
1505
+ exports.createPasskey = createPasskey;
1506
+ exports.decodeChallenge = decodeChallenge;
1507
+ exports.defaultAdapters = defaultAdapters;
1508
+ exports.defaultCredentialStorage = defaultCredentialStorage;
1509
+ exports.derToCompact = derToCompact;
1510
+ exports.derToCompactLowS = derToCompactLowS;
1511
+ exports.deriveAccountAddress = deriveAccountAddress;
1512
+ exports.deriveSmartWalletAddress = deriveSmartWalletAddress;
1513
+ exports.directSubmission = directSubmission;
1514
+ exports.encodeChallenge = encodeChallenge;
1515
+ exports.eventsIndexer = eventsIndexer;
1516
+ exports.extractPublicKeyFromAttestationObject = extractPublicKeyFromAttestationObject;
1517
+ exports.extractPublicKeyFromAuthData = extractPublicKeyFromAuthData;
1518
+ exports.factoryDeployer = factoryDeployer;
1519
+ exports.isKitError = isKitError;
1520
+ exports.isLowS = isLowS;
1521
+ exports.launchtubeSubmission = launchtubeSubmission;
1522
+ exports.mercuryIndexer = mercuryIndexer;
1523
+ exports.normalizeLowS = normalizeLowS;
1524
+ exports.openzeppelinRelayerSubmission = openzeppelinRelayerSubmission;
1525
+ exports.parseAuthenticatorData = parseAuthenticatorData;
1526
+ exports.parseClientDataJSON = parseClientDataJSON;
1527
+ exports.reconstructSignedPayload = reconstructSignedPayload;
1528
+ exports.recover = recover;
1529
+ exports.referenceCheckAuth = referenceCheckAuth;
1530
+ exports.referenceSmartWalletCheckAuth = referenceSmartWalletCheckAuth;
1531
+ exports.registerPasskey = registerPasskey;
1532
+ exports.removeSigner = removeSigner;
1533
+ exports.sendSmartWalletTx = sendSmartWalletTx;
1534
+ exports.signAuthEntry = signAuthEntry;
1535
+ exports.signTransaction = signTransaction;
1536
+ exports.smartWalletV1Deployer = smartWalletV1Deployer;
1537
+ exports.smartWalletV1Indexer = smartWalletV1Indexer;
1538
+ exports.verifyAssertionSignature = verifyAssertionSignature;
1539
+ exports.verifyClientDataJSON = verifyClientDataJSON;
1540
+ exports.verifyRpIdHash = verifyRpIdHash;
1541
+ //# sourceMappingURL=index.cjs.map
1542
+ //# sourceMappingURL=index.cjs.map