@cantonconnect/core 0.2.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,756 @@
1
+ // src/types.ts
2
+ function toWalletId(id) {
3
+ return id;
4
+ }
5
+ function toPartyId(id) {
6
+ return id;
7
+ }
8
+ function toSessionId(id) {
9
+ return id;
10
+ }
11
+ function toTransactionHash(hash) {
12
+ return hash;
13
+ }
14
+ function toSignature(sig) {
15
+ return sig;
16
+ }
17
+
18
+ // src/errors.ts
19
+ var CantonConnectError = class _CantonConnectError extends Error {
20
+ code;
21
+ cause;
22
+ details;
23
+ isOperational;
24
+ constructor(message, code, options) {
25
+ super(message);
26
+ this.name = "CantonConnectError";
27
+ this.code = code;
28
+ this.cause = options?.cause;
29
+ this.details = options?.details;
30
+ this.isOperational = options?.isOperational ?? true;
31
+ if (Error.captureStackTrace) {
32
+ Error.captureStackTrace(this, _CantonConnectError);
33
+ }
34
+ }
35
+ /**
36
+ * Serialize error to JSON for telemetry/logging
37
+ */
38
+ toJSON() {
39
+ return {
40
+ name: this.name,
41
+ message: this.message,
42
+ code: this.code,
43
+ isOperational: this.isOperational,
44
+ details: this.details,
45
+ cause: this.cause instanceof Error ? {
46
+ name: this.cause.name,
47
+ message: this.cause.message,
48
+ stack: this.cause.stack
49
+ } : this.cause
50
+ };
51
+ }
52
+ };
53
+ var WalletNotFoundError = class extends CantonConnectError {
54
+ constructor(walletId) {
55
+ super(`Wallet "${walletId}" not found`, "WALLET_NOT_FOUND", {
56
+ details: { walletId }
57
+ });
58
+ this.name = "WalletNotFoundError";
59
+ }
60
+ };
61
+ var WalletNotInstalledError = class extends CantonConnectError {
62
+ constructor(walletId, reason) {
63
+ super(
64
+ `Wallet "${walletId}" is not installed${reason ? `: ${reason}` : ""}`,
65
+ "WALLET_NOT_INSTALLED",
66
+ {
67
+ details: { walletId, reason }
68
+ }
69
+ );
70
+ this.name = "WalletNotInstalledError";
71
+ }
72
+ };
73
+ var UserRejectedError = class extends CantonConnectError {
74
+ constructor(operation, details) {
75
+ super(`User rejected ${operation}`, "USER_REJECTED", {
76
+ details: { operation, ...details }
77
+ });
78
+ this.name = "UserRejectedError";
79
+ }
80
+ };
81
+ var OriginNotAllowedError = class extends CantonConnectError {
82
+ constructor(origin, allowedOrigins) {
83
+ super(
84
+ `Origin "${origin}" is not allowed`,
85
+ "ORIGIN_NOT_ALLOWED",
86
+ {
87
+ details: { origin, allowedOrigins }
88
+ }
89
+ );
90
+ this.name = "OriginNotAllowedError";
91
+ }
92
+ };
93
+ var SessionExpiredError = class extends CantonConnectError {
94
+ constructor(sessionId) {
95
+ super(`Session "${sessionId}" has expired`, "SESSION_EXPIRED", {
96
+ details: { sessionId }
97
+ });
98
+ this.name = "SessionExpiredError";
99
+ }
100
+ };
101
+ var CapabilityNotSupportedError = class extends CantonConnectError {
102
+ constructor(walletId, capability) {
103
+ super(
104
+ `Wallet "${walletId}" does not support capability "${capability}"`,
105
+ "CAPABILITY_NOT_SUPPORTED",
106
+ {
107
+ details: { walletId, capability }
108
+ }
109
+ );
110
+ this.name = "CapabilityNotSupportedError";
111
+ }
112
+ };
113
+ var TransportError = class extends CantonConnectError {
114
+ constructor(message, cause, details) {
115
+ super(message, "TRANSPORT_ERROR", {
116
+ cause,
117
+ details
118
+ });
119
+ this.name = "TransportError";
120
+ }
121
+ };
122
+ var RegistryFetchFailedError = class extends CantonConnectError {
123
+ constructor(url, cause) {
124
+ super(`Failed to fetch registry from "${url}"`, "REGISTRY_FETCH_FAILED", {
125
+ cause,
126
+ details: { url }
127
+ });
128
+ this.name = "RegistryFetchFailedError";
129
+ }
130
+ };
131
+ var RegistryVerificationFailedError = class extends CantonConnectError {
132
+ constructor(reason, details) {
133
+ super(`Registry verification failed: ${reason}`, "REGISTRY_VERIFICATION_FAILED", {
134
+ details: { reason, ...details }
135
+ });
136
+ this.name = "RegistryVerificationFailedError";
137
+ }
138
+ };
139
+ var RegistrySchemaInvalidError = class extends CantonConnectError {
140
+ constructor(reason, details) {
141
+ super(`Registry schema invalid: ${reason}`, "REGISTRY_SCHEMA_INVALID", {
142
+ details: { reason, ...details }
143
+ });
144
+ this.name = "RegistrySchemaInvalidError";
145
+ }
146
+ };
147
+ var InternalError = class extends CantonConnectError {
148
+ constructor(message, cause, details) {
149
+ super(message, "INTERNAL_ERROR", {
150
+ cause,
151
+ details,
152
+ isOperational: false
153
+ });
154
+ this.name = "InternalError";
155
+ }
156
+ };
157
+ var TimeoutError = class extends CantonConnectError {
158
+ constructor(operation, timeoutMs) {
159
+ super(
160
+ `Operation "${operation}" timed out after ${timeoutMs}ms`,
161
+ "TIMEOUT",
162
+ {
163
+ details: { operation, timeoutMs }
164
+ }
165
+ );
166
+ this.name = "TimeoutError";
167
+ }
168
+ };
169
+ function mapUnknownErrorToCantonConnectError(err, context) {
170
+ if (err instanceof CantonConnectError) {
171
+ return err;
172
+ }
173
+ if (err instanceof Error) {
174
+ const message = err.message.toLowerCase();
175
+ if (message.includes("rejected") || message.includes("denied") || message.includes("cancelled") || message.includes("canceled") || err.name === "UserRejectedError") {
176
+ return new UserRejectedError(context.phase, {
177
+ walletId: context.walletId,
178
+ transport: context.transport,
179
+ originalMessage: err.message
180
+ });
181
+ }
182
+ if (message.includes("timeout") || message.includes("timed out") || err.name === "TimeoutError") {
183
+ let timeoutMs = context.timeoutMs ?? 0;
184
+ if (timeoutMs === 0) {
185
+ const msMatch = err.message.match(/(\d+)\s*ms/i);
186
+ const secMatch = err.message.match(/(\d+)\s*(?:sec|second)/i);
187
+ if (msMatch) {
188
+ timeoutMs = parseInt(msMatch[1], 10);
189
+ } else if (secMatch) {
190
+ timeoutMs = parseInt(secMatch[1], 10) * 1e3;
191
+ }
192
+ }
193
+ return new TimeoutError(context.phase, timeoutMs);
194
+ }
195
+ if (message.includes("network") || message.includes("fetch") || message.includes("connection") || err.name === "NetworkError" || err.name === "TypeError") {
196
+ return new TransportError(err.message, err, {
197
+ walletId: context.walletId,
198
+ phase: context.phase,
199
+ transport: context.transport
200
+ });
201
+ }
202
+ return new TransportError(err.message, err, {
203
+ walletId: context.walletId,
204
+ phase: context.phase,
205
+ transport: context.transport,
206
+ originalError: err.name
207
+ });
208
+ }
209
+ if (typeof err === "string") {
210
+ return new TransportError(err, void 0, {
211
+ walletId: context.walletId,
212
+ phase: context.phase,
213
+ transport: context.transport
214
+ });
215
+ }
216
+ return new InternalError(
217
+ `Unknown error in ${context.phase}`,
218
+ err,
219
+ {
220
+ walletId: context.walletId,
221
+ transport: context.transport,
222
+ errorType: typeof err
223
+ }
224
+ );
225
+ }
226
+
227
+ // src/adapters.ts
228
+ function capabilityGuard(adapter, requiredCapabilities) {
229
+ const supported = adapter.getCapabilities();
230
+ const missing = requiredCapabilities.filter((cap) => !supported.includes(cap));
231
+ if (missing.length > 0) {
232
+ throw new CapabilityNotSupportedError(
233
+ adapter.walletId,
234
+ missing.join(", ")
235
+ );
236
+ }
237
+ }
238
+ async function installGuard(adapter) {
239
+ const detect = await adapter.detectInstalled();
240
+ if (!detect.installed) {
241
+ throw new WalletNotInstalledError(adapter.walletId, detect.reason);
242
+ }
243
+ }
244
+
245
+ // src/session.ts
246
+ function generateSessionId() {
247
+ return toSessionId(`session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`);
248
+ }
249
+ function validateSession(session) {
250
+ if (typeof session !== "object" || session === null) {
251
+ return false;
252
+ }
253
+ const s = session;
254
+ return typeof s.sessionId === "string" && typeof s.walletId === "string" && typeof s.partyId === "string" && typeof s.network === "string" && typeof s.createdAt === "number" && typeof s.origin === "string" && Array.isArray(s.capabilitiesSnapshot);
255
+ }
256
+ function isSessionExpired(session) {
257
+ if (!session.expiresAt) {
258
+ return false;
259
+ }
260
+ return Date.now() >= session.expiresAt;
261
+ }
262
+ function createSession(walletId, partyId, network, origin, capabilities = [], expiresInMs) {
263
+ const now = Date.now();
264
+ return {
265
+ sessionId: generateSessionId(),
266
+ walletId,
267
+ partyId,
268
+ network,
269
+ createdAt: now,
270
+ expiresAt: expiresInMs ? now + expiresInMs : void 0,
271
+ origin,
272
+ capabilitiesSnapshot: capabilities
273
+ };
274
+ }
275
+
276
+ // src/transport/deeplink.ts
277
+ var DeepLinkTransport = class {
278
+ /**
279
+ * Generate a random state nonce
280
+ */
281
+ generateState() {
282
+ const array = new Uint8Array(32);
283
+ crypto.getRandomValues(array);
284
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
285
+ }
286
+ /**
287
+ * Build deep link URL with query parameters
288
+ */
289
+ buildDeepLinkUrl(baseUrl, request) {
290
+ const url = new URL(baseUrl);
291
+ Object.entries(request).forEach(([key, value]) => {
292
+ if (value !== void 0) {
293
+ if (Array.isArray(value)) {
294
+ url.searchParams.set(key, JSON.stringify(value));
295
+ } else if (typeof value === "object") {
296
+ url.searchParams.set(key, JSON.stringify(value));
297
+ } else {
298
+ url.searchParams.set(key, String(value));
299
+ }
300
+ }
301
+ });
302
+ return url.toString();
303
+ }
304
+ /**
305
+ * Validate callback origin
306
+ */
307
+ validateOrigin(origin, options) {
308
+ if (options.allowedOrigins && options.allowedOrigins.length > 0) {
309
+ if (!options.allowedOrigins.includes(origin)) {
310
+ throw new Error(`Origin ${origin} not allowed`);
311
+ }
312
+ }
313
+ }
314
+ /**
315
+ * Wait for callback via postMessage or redirect
316
+ */
317
+ async waitForCallback(state, options, timeoutMs) {
318
+ return new Promise((resolve, reject) => {
319
+ const timeout = setTimeout(() => {
320
+ cleanup();
321
+ reject(new Error("Transport timeout"));
322
+ }, timeoutMs);
323
+ const messageHandler = (event) => {
324
+ try {
325
+ this.validateOrigin(event.origin, options);
326
+ } catch (err) {
327
+ return;
328
+ }
329
+ const data = event.data;
330
+ if (data && data.state === state) {
331
+ cleanup();
332
+ resolve(data);
333
+ }
334
+ };
335
+ const redirectHandler = () => {
336
+ if (typeof window !== "undefined") {
337
+ const hash = window.location.hash.substring(1);
338
+ const params = new URLSearchParams(hash);
339
+ const callbackState = params.get("state");
340
+ if (callbackState === state) {
341
+ const data = {};
342
+ params.forEach((value, key) => {
343
+ data[key] = value;
344
+ });
345
+ cleanup();
346
+ resolve(data);
347
+ }
348
+ }
349
+ };
350
+ const cleanup = () => {
351
+ clearTimeout(timeout);
352
+ if (typeof window !== "undefined") {
353
+ window.removeEventListener("message", messageHandler);
354
+ window.removeEventListener("hashchange", redirectHandler);
355
+ }
356
+ };
357
+ if (typeof window !== "undefined") {
358
+ window.addEventListener("message", messageHandler);
359
+ window.addEventListener("hashchange", redirectHandler);
360
+ redirectHandler();
361
+ }
362
+ });
363
+ }
364
+ /**
365
+ * Open a connection request
366
+ */
367
+ async openConnectRequest(url, request, options) {
368
+ if (!request.state) {
369
+ request.state = this.generateState();
370
+ }
371
+ const deepLinkUrl = this.buildDeepLinkUrl(url, request);
372
+ if (typeof window !== "undefined") {
373
+ window.location.href = deepLinkUrl;
374
+ const fallbackWindow = window.open(deepLinkUrl, "_blank");
375
+ if (!fallbackWindow) {
376
+ throw new Error("Failed to open deep link");
377
+ }
378
+ }
379
+ const timeout = options.timeoutMs || 6e4;
380
+ const response = await this.waitForCallback(
381
+ request.state,
382
+ options,
383
+ timeout
384
+ );
385
+ if (response.state !== request.state) {
386
+ throw new Error("State mismatch in callback");
387
+ }
388
+ return response;
389
+ }
390
+ /**
391
+ * Open a sign request
392
+ */
393
+ async openSignRequest(url, request, options) {
394
+ if (!request.state) {
395
+ request.state = this.generateState();
396
+ }
397
+ const deepLinkUrl = this.buildDeepLinkUrl(url, request);
398
+ if (typeof window !== "undefined") {
399
+ window.location.href = deepLinkUrl;
400
+ }
401
+ const timeout = options.timeoutMs || 6e4;
402
+ const response = await this.waitForCallback(
403
+ request.state,
404
+ options,
405
+ timeout
406
+ );
407
+ if (response.state !== request.state) {
408
+ throw new Error("State mismatch in callback");
409
+ }
410
+ return response;
411
+ }
412
+ };
413
+
414
+ // src/transport/popup.ts
415
+ var PopupTransport = class {
416
+ /**
417
+ * Generate a random state nonce
418
+ */
419
+ generateState() {
420
+ const array = new Uint8Array(32);
421
+ crypto.getRandomValues(array);
422
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
423
+ }
424
+ /**
425
+ * Build URL with query parameters
426
+ */
427
+ buildUrl(baseUrl, request) {
428
+ const url = new URL(baseUrl);
429
+ Object.entries(request).forEach(([key, value]) => {
430
+ if (value !== void 0) {
431
+ if (Array.isArray(value)) {
432
+ url.searchParams.set(key, JSON.stringify(value));
433
+ } else if (typeof value === "object") {
434
+ url.searchParams.set(key, JSON.stringify(value));
435
+ } else {
436
+ url.searchParams.set(key, String(value));
437
+ }
438
+ }
439
+ });
440
+ return url.toString();
441
+ }
442
+ /**
443
+ * Validate message origin
444
+ */
445
+ validateOrigin(origin, options) {
446
+ if (options.allowedOrigins && options.allowedOrigins.length > 0) {
447
+ if (!options.allowedOrigins.includes(origin)) {
448
+ throw new Error(`Origin ${origin} not allowed`);
449
+ }
450
+ }
451
+ }
452
+ /**
453
+ * Open popup window
454
+ */
455
+ openPopup(url, _options) {
456
+ if (typeof window === "undefined") {
457
+ return null;
458
+ }
459
+ const width = 500;
460
+ const height = 600;
461
+ const left = window.screenX + (window.outerWidth - width) / 2;
462
+ const top = window.screenY + (window.outerHeight - height) / 2;
463
+ return window.open(
464
+ url,
465
+ "CantonConnect",
466
+ `width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`
467
+ );
468
+ }
469
+ /**
470
+ * Wait for postMessage callback
471
+ */
472
+ async waitForCallback(popup, state, options, timeoutMs) {
473
+ return new Promise((resolve, reject) => {
474
+ const timeout = setTimeout(() => {
475
+ cleanup();
476
+ popup.close();
477
+ reject(new Error("Transport timeout"));
478
+ }, timeoutMs);
479
+ const checkClosed = setInterval(() => {
480
+ if (popup.closed) {
481
+ cleanup();
482
+ reject(new Error("Popup closed by user"));
483
+ }
484
+ }, 500);
485
+ const messageHandler = (event) => {
486
+ try {
487
+ this.validateOrigin(event.origin, options);
488
+ } catch (err) {
489
+ return;
490
+ }
491
+ const data = event.data;
492
+ if (data && data.state === state) {
493
+ cleanup();
494
+ popup.close();
495
+ resolve(data);
496
+ }
497
+ };
498
+ const cleanup = () => {
499
+ clearTimeout(timeout);
500
+ clearInterval(checkClosed);
501
+ if (typeof window !== "undefined") {
502
+ window.removeEventListener("message", messageHandler);
503
+ }
504
+ };
505
+ if (typeof window !== "undefined") {
506
+ window.addEventListener("message", messageHandler);
507
+ }
508
+ });
509
+ }
510
+ /**
511
+ * Open a connection request
512
+ */
513
+ async openConnectRequest(url, request, options) {
514
+ if (!request.state) {
515
+ request.state = this.generateState();
516
+ }
517
+ const fullUrl = this.buildUrl(url, request);
518
+ const popup = this.openPopup(fullUrl, options);
519
+ if (!popup) {
520
+ throw new Error("Failed to open popup window");
521
+ }
522
+ const timeout = options.timeoutMs || 6e4;
523
+ const response = await this.waitForCallback(
524
+ popup,
525
+ request.state,
526
+ options,
527
+ timeout
528
+ );
529
+ if (response.state !== request.state) {
530
+ throw new Error("State mismatch in callback");
531
+ }
532
+ return response;
533
+ }
534
+ /**
535
+ * Open a sign request
536
+ */
537
+ async openSignRequest(url, request, options) {
538
+ if (!request.state) {
539
+ request.state = this.generateState();
540
+ }
541
+ const fullUrl = this.buildUrl(url, request);
542
+ const popup = this.openPopup(fullUrl, options);
543
+ if (!popup) {
544
+ throw new Error("Failed to open popup window");
545
+ }
546
+ const timeout = options.timeoutMs || 6e4;
547
+ const response = await this.waitForCallback(
548
+ popup,
549
+ request.state,
550
+ options,
551
+ timeout
552
+ );
553
+ if (response.state !== request.state) {
554
+ throw new Error("State mismatch in callback");
555
+ }
556
+ return response;
557
+ }
558
+ };
559
+
560
+ // src/transport/postmessage.ts
561
+ var PostMessageTransport = class {
562
+ /**
563
+ * Generate a random state nonce
564
+ */
565
+ generateState() {
566
+ const array = new Uint8Array(32);
567
+ crypto.getRandomValues(array);
568
+ return Array.from(array, (byte) => byte.toString(16).padStart(2, "0")).join("");
569
+ }
570
+ /**
571
+ * Validate message origin
572
+ */
573
+ validateOrigin(origin, options) {
574
+ if (options.allowedOrigins && options.allowedOrigins.length > 0) {
575
+ if (!options.allowedOrigins.includes(origin)) {
576
+ throw new Error(`Origin ${origin} not allowed`);
577
+ }
578
+ }
579
+ }
580
+ /**
581
+ * Send message and wait for response
582
+ */
583
+ async sendAndWait(target, targetOrigin, message, options, timeoutMs) {
584
+ return new Promise((resolve, reject) => {
585
+ const timeout = setTimeout(() => {
586
+ cleanup();
587
+ reject(new Error("Transport timeout"));
588
+ }, timeoutMs);
589
+ const messageHandler = (event) => {
590
+ try {
591
+ this.validateOrigin(event.origin, options);
592
+ } catch (err) {
593
+ return;
594
+ }
595
+ const data = event.data;
596
+ if (data && data.state === message.state) {
597
+ cleanup();
598
+ resolve(data);
599
+ }
600
+ };
601
+ const cleanup = () => {
602
+ clearTimeout(timeout);
603
+ if (typeof window !== "undefined") {
604
+ window.removeEventListener("message", messageHandler);
605
+ }
606
+ };
607
+ if (typeof window !== "undefined") {
608
+ window.addEventListener("message", messageHandler);
609
+ target.postMessage(message, targetOrigin);
610
+ }
611
+ });
612
+ }
613
+ /**
614
+ * Open a connection request
615
+ */
616
+ async openConnectRequest(url, request, options) {
617
+ if (typeof window === "undefined") {
618
+ throw new Error("PostMessage transport requires browser environment");
619
+ }
620
+ if (!request.state) {
621
+ request.state = this.generateState();
622
+ }
623
+ const targetUrl = new URL(url);
624
+ const targetOrigin = targetUrl.origin;
625
+ const target = window.opener || window.parent;
626
+ if (!target || target === window) {
627
+ throw new Error("No target window available for postMessage");
628
+ }
629
+ const timeout = options.timeoutMs || 6e4;
630
+ const response = await this.sendAndWait(
631
+ target,
632
+ targetOrigin,
633
+ request,
634
+ options,
635
+ timeout
636
+ );
637
+ if (response.state !== request.state) {
638
+ throw new Error("State mismatch in callback");
639
+ }
640
+ return response;
641
+ }
642
+ /**
643
+ * Open a sign request
644
+ */
645
+ async openSignRequest(url, request, options) {
646
+ if (typeof window === "undefined") {
647
+ throw new Error("PostMessage transport requires browser environment");
648
+ }
649
+ if (!request.state) {
650
+ request.state = this.generateState();
651
+ }
652
+ const targetUrl = new URL(url);
653
+ const targetOrigin = targetUrl.origin;
654
+ const target = window.opener || window.parent;
655
+ if (!target || target === window) {
656
+ throw new Error("No target window available for postMessage");
657
+ }
658
+ const timeout = options.timeoutMs || 6e4;
659
+ const response = await this.sendAndWait(
660
+ target,
661
+ targetOrigin,
662
+ request,
663
+ options,
664
+ timeout
665
+ );
666
+ if (response.state !== request.state) {
667
+ throw new Error("State mismatch in callback");
668
+ }
669
+ return response;
670
+ }
671
+ };
672
+
673
+ // src/transport/mock.ts
674
+ var MockTransport = class {
675
+ mockResponses = /* @__PURE__ */ new Map();
676
+ mockJobs = /* @__PURE__ */ new Map();
677
+ /**
678
+ * Set mock response for a state
679
+ */
680
+ setMockResponse(state, response) {
681
+ this.mockResponses.set(state, response);
682
+ }
683
+ /**
684
+ * Set mock job status
685
+ */
686
+ setMockJob(jobId, status) {
687
+ this.mockJobs.set(jobId, status);
688
+ }
689
+ /**
690
+ * Clear all mocks
691
+ */
692
+ clearMocks() {
693
+ this.mockResponses.clear();
694
+ this.mockJobs.clear();
695
+ }
696
+ /**
697
+ * Open a connection request (mock)
698
+ */
699
+ async openConnectRequest(_url, request, _options) {
700
+ const mockResponse = this.mockResponses.get(request.state);
701
+ if (mockResponse && "partyId" in mockResponse) {
702
+ return mockResponse;
703
+ }
704
+ return new Promise((resolve) => {
705
+ setTimeout(() => {
706
+ resolve({
707
+ state: request.state,
708
+ partyId: toPartyId("mock-party-" + Date.now()),
709
+ sessionToken: "mock-token",
710
+ expiresAt: Date.now() + 36e5,
711
+ // 1 hour
712
+ capabilities: request.requestedCapabilities || ["connect", "signMessage"]
713
+ });
714
+ }, 100);
715
+ });
716
+ }
717
+ /**
718
+ * Open a sign request (mock)
719
+ */
720
+ async openSignRequest(_url, request, _options) {
721
+ const mockResponse = this.mockResponses.get(request.state);
722
+ if (mockResponse && ("signature" in mockResponse || "jobId" in mockResponse)) {
723
+ return mockResponse;
724
+ }
725
+ return new Promise((resolve) => {
726
+ setTimeout(() => {
727
+ resolve({
728
+ state: request.state,
729
+ signature: "mock-signature-" + Date.now(),
730
+ transactionHash: request.transaction ? "mock-tx-hash" : void 0
731
+ });
732
+ }, 100);
733
+ });
734
+ }
735
+ /**
736
+ * Poll job status (mock)
737
+ */
738
+ async pollJobStatus(jobId, _statusUrl, _options) {
739
+ const mockJob = this.mockJobs.get(jobId);
740
+ if (mockJob) {
741
+ return mockJob;
742
+ }
743
+ return {
744
+ jobId,
745
+ status: "approved",
746
+ result: {
747
+ signature: "mock-signature",
748
+ transactionHash: "mock-tx-hash"
749
+ }
750
+ };
751
+ }
752
+ };
753
+
754
+ export { CantonConnectError, CapabilityNotSupportedError, DeepLinkTransport, InternalError, MockTransport, OriginNotAllowedError, PopupTransport, PostMessageTransport, RegistryFetchFailedError, RegistrySchemaInvalidError, RegistryVerificationFailedError, SessionExpiredError, TimeoutError, TransportError, UserRejectedError, WalletNotFoundError, WalletNotInstalledError, capabilityGuard, createSession, generateSessionId, installGuard, isSessionExpired, mapUnknownErrorToCantonConnectError, toPartyId, toSessionId, toSignature, toTransactionHash, toWalletId, validateSession };
755
+ //# sourceMappingURL=index.mjs.map
756
+ //# sourceMappingURL=index.mjs.map