@naculus/connect-appkit-vue 0.2.4 → 0.2.6

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.js CHANGED
@@ -209,40 +209,2536 @@ function useAccounts(accounts) {
209
209
  };
210
210
  }
211
211
 
212
+ // src/useNotification.ts
213
+ import {
214
+ addInAppNotification,
215
+ channelsUpdate,
216
+ clearOneInAppNotification,
217
+ createNotificationSettingsStorage,
218
+ DEFAULT_NOTIFICATION_SETTINGS,
219
+ loadNotificationSettings,
220
+ mutedChainSettings,
221
+ saveNotificationSettings,
222
+ updateNotificationSettings
223
+ } from "@naculus/connect-appkit-core";
224
+ import {
225
+ InAppChannel
226
+ } from "@naculus/connect-core";
227
+ import { computed as computed2, onScopeDispose, shallowRef, unref } from "vue";
228
+ function useNotification(options = {}) {
229
+ const channel = unref(options.channel) ?? new InAppChannel();
230
+ const storage = unref(options.storage) ?? createNotificationSettingsStorage();
231
+ const notifications = shallowRef(channel.getHistory());
232
+ const settings = shallowRef(
233
+ DEFAULT_NOTIFICATION_SETTINGS
234
+ );
235
+ const unreadCount = computed2(
236
+ () => notifications.value.filter((item) => !item.read).length
237
+ );
238
+ let disposed = false;
239
+ void loadNotificationSettings(storage).then((saved) => {
240
+ if (!disposed && saved) settings.value = saved;
241
+ });
242
+ channel.onNotification = (item) => {
243
+ if (!disposed) notifications.value = [...notifications.value, item];
244
+ };
245
+ void channel.restore().then(() => {
246
+ if (!disposed) notifications.value = channel.getHistory();
247
+ });
248
+ onScopeDispose(() => {
249
+ disposed = true;
250
+ channel.onNotification = void 0;
251
+ });
252
+ const updateSettings = (update) => {
253
+ settings.value = updateNotificationSettings(settings.value, update);
254
+ saveNotificationSettings(storage, settings.value);
255
+ };
256
+ return {
257
+ notifications,
258
+ unreadCount,
259
+ settings,
260
+ addNotification: (item) => addInAppNotification(channel, item),
261
+ clear: () => {
262
+ channel.clear();
263
+ notifications.value = [];
264
+ },
265
+ clearOne: (id) => {
266
+ void clearOneInAppNotification(channel, id).then(() => {
267
+ if (!disposed) notifications.value = channel.getHistory();
268
+ });
269
+ },
270
+ markAsRead: (id) => {
271
+ channel.markAsRead(id);
272
+ notifications.value = notifications.value.map(
273
+ (item) => item.id === id ? { ...item, read: true } : item
274
+ );
275
+ },
276
+ markAllAsRead: () => {
277
+ channel.markAllAsRead();
278
+ notifications.value = notifications.value.map((item) => ({
279
+ ...item,
280
+ read: true
281
+ }));
282
+ },
283
+ updateSettings,
284
+ setChannels: (channels) => updateSettings(channelsUpdate(channels)),
285
+ muteChain: (chainId) => updateSettings(mutedChainSettings(settings.value, chainId, true)),
286
+ unmuteChain: (chainId) => updateSettings(mutedChainSettings(settings.value, chainId, false))
287
+ };
288
+ }
289
+
290
+ // src/useSimulateTransfer.ts
291
+ import { resolveSimulationEndpoint } from "@naculus/connect-appkit-core";
292
+ import {
293
+ SimulationManager
294
+ } from "@naculus/connect-core";
295
+ import { onScopeDispose as onScopeDispose2, shallowRef as shallowRef2, unref as unref2 } from "vue";
296
+ function useSimulateTransfer(options = {}) {
297
+ const result = shallowRef2(null);
298
+ const loading = shallowRef2(false);
299
+ const error = shallowRef2(null);
300
+ let manager;
301
+ let generation = 0;
302
+ let disposed = false;
303
+ const simulate = async (tokenAddress, from, to, amount, callOptions) => {
304
+ const own = ++generation;
305
+ loading.value = true;
306
+ error.value = null;
307
+ try {
308
+ const fallbackRpcUrl = unref2(options.rpcUrl);
309
+ const endpoint = resolveSimulationEndpoint(
310
+ callOptions?.chainId,
311
+ unref2(options.chainId),
312
+ callOptions?.rpcUrl,
313
+ fallbackRpcUrl
314
+ );
315
+ manager ??= new SimulationManager({
316
+ enabled: true,
317
+ rpcUrl: fallbackRpcUrl,
318
+ autoSimulate: false
319
+ });
320
+ const value = await manager.simulateERC20Transfer(
321
+ tokenAddress,
322
+ from,
323
+ to,
324
+ amount,
325
+ endpoint.chainId,
326
+ callOptions?.decimals,
327
+ endpoint.rpcUrl
328
+ );
329
+ if (!disposed && own === generation) result.value = value;
330
+ return value;
331
+ } catch (cause) {
332
+ const normalized = cause instanceof Error ? cause : new Error(String(cause));
333
+ if (!disposed && own === generation) error.value = normalized;
334
+ throw normalized;
335
+ } finally {
336
+ if (!disposed && own === generation) loading.value = false;
337
+ }
338
+ };
339
+ const reset = () => {
340
+ generation++;
341
+ result.value = null;
342
+ error.value = null;
343
+ loading.value = false;
344
+ };
345
+ onScopeDispose2(() => {
346
+ disposed = true;
347
+ generation++;
348
+ });
349
+ return { result, loading, error, simulate, reset };
350
+ }
351
+
352
+ // src/useTransactionSimulation.ts
353
+ import {
354
+ simulateTransactionPreview
355
+ } from "@naculus/connect-appkit-core";
356
+ import { onScopeDispose as onScopeDispose3, shallowRef as shallowRef3, toValue as toValue2, unref as unref3, watch } from "vue";
357
+ function useTransactionSimulation(tx, options = {}) {
358
+ const result = shallowRef3(void 0);
359
+ const isSimulating = shallowRef3(false);
360
+ const error = shallowRef3(null);
361
+ let timer;
362
+ let generation = 0;
363
+ let disposed = false;
364
+ const simulate = async () => {
365
+ const own = ++generation;
366
+ const transaction = toValue2(tx);
367
+ if (transaction) {
368
+ isSimulating.value = true;
369
+ error.value = null;
370
+ }
371
+ try {
372
+ const value = await simulateTransactionPreview(transaction, {
373
+ chainId: unref3(options.chainId),
374
+ currentChain: unref3(options.currentChain),
375
+ publicClient: unref3(options.publicClient),
376
+ evmAccount: unref3(options.evmAccount)
377
+ });
378
+ if (!disposed && own === generation) result.value = value;
379
+ return value;
380
+ } catch (cause) {
381
+ const normalized = cause instanceof Error ? cause : new Error("Simulation failed");
382
+ if (!disposed && own === generation) error.value = normalized;
383
+ throw normalized;
384
+ } finally {
385
+ if (transaction && !disposed && own === generation)
386
+ isSimulating.value = false;
387
+ }
388
+ };
389
+ watch(
390
+ [
391
+ () => toValue2(tx),
392
+ () => unref3(options.chainId),
393
+ () => unref3(options.currentChain),
394
+ () => unref3(options.publicClient),
395
+ () => unref3(options.evmAccount)
396
+ ],
397
+ ([transaction]) => {
398
+ generation++;
399
+ if (timer) clearTimeout(timer);
400
+ if (!transaction) return;
401
+ timer = setTimeout(() => {
402
+ timer = void 0;
403
+ void simulate().catch(() => {
404
+ });
405
+ }, 300);
406
+ },
407
+ { immediate: true }
408
+ );
409
+ const reset = () => {
410
+ generation++;
411
+ result.value = void 0;
412
+ error.value = null;
413
+ isSimulating.value = false;
414
+ };
415
+ onScopeDispose3(() => {
416
+ disposed = true;
417
+ generation++;
418
+ if (timer) clearTimeout(timer);
419
+ });
420
+ return { result, isSimulating, error, simulate, reset };
421
+ }
422
+
423
+ // src/useERC20Transfer.ts
424
+ import {
425
+ createDecimalsCache,
426
+ encodeErc20Transfer,
427
+ readDecimals,
428
+ writeDecimals
429
+ } from "@naculus/connect-appkit-core";
430
+ import {
431
+ ERC20_MIN_ABI,
432
+ parseUnits,
433
+ WalletError as WalletError2
434
+ } from "@naculus/connect-core";
435
+ import { onScopeDispose as onScopeDispose4, shallowRef as shallowRef4, toValue as toValue3, unref as unref4, watch as watch2 } from "vue";
436
+
437
+ // src/erc20.ts
438
+ import {
439
+ bareEvmAddress,
440
+ tokenChainMismatch
441
+ } from "@naculus/connect-appkit-core";
442
+ import { WalletError } from "@naculus/connect-core";
443
+ function assertErc20Context(token, chainId, account, connected) {
444
+ if (!connected || !account) {
445
+ throw new WalletError("wallet_unavailable", "No connected account");
446
+ }
447
+ const mismatch = tokenChainMismatch(token, chainId);
448
+ if (mismatch) throw mismatch;
449
+ const bare = bareEvmAddress(account);
450
+ if (!bare) {
451
+ throw new WalletError("wallet_unavailable", "No valid EVM account");
452
+ }
453
+ return bare;
454
+ }
455
+
456
+ // src/useERC20Transfer.ts
457
+ function useERC20Transfer(options) {
458
+ const initialToken = toValue3(options.token);
459
+ const decimals = createDecimalsCache(initialToken, initialToken.decimals);
460
+ const isSending = shallowRef4(false);
461
+ const error = shallowRef4(null);
462
+ let generation = 0;
463
+ let disposed = false;
464
+ watch2(
465
+ [
466
+ () => toValue3(options.token).address,
467
+ () => toValue3(options.token).chainId,
468
+ () => toValue3(options.token).decimals,
469
+ () => toValue3(options.account),
470
+ () => toValue3(options.chainId),
471
+ () => toValue3(options.connected),
472
+ () => toValue3(options.publicClient),
473
+ () => unref4(options.sendTransaction)
474
+ ],
475
+ () => {
476
+ generation++;
477
+ isSending.value = false;
478
+ error.value = null;
479
+ },
480
+ { flush: "sync" }
481
+ );
482
+ const sendTransfer = async (to, amount) => {
483
+ const own = ++generation;
484
+ const token = toValue3(options.token);
485
+ const reader = toValue3(options.publicClient);
486
+ const stillCurrent = () => !disposed && own === generation;
487
+ error.value = null;
488
+ isSending.value = true;
489
+ try {
490
+ assertErc20Context(
491
+ token,
492
+ toValue3(options.chainId),
493
+ toValue3(options.account),
494
+ toValue3(options.connected)
495
+ );
496
+ if (!reader) {
497
+ throw new WalletError2(
498
+ "wallet_unavailable",
499
+ "No public client available"
500
+ );
501
+ }
502
+ let precision = readDecimals(decimals, token, token.decimals);
503
+ if (precision === void 0) {
504
+ precision = Number(
505
+ await reader.readContract({
506
+ address: token.address,
507
+ abi: ERC20_MIN_ABI,
508
+ functionName: "decimals"
509
+ })
510
+ );
511
+ if (!stillCurrent()) {
512
+ throw new WalletError2(
513
+ "session_inactive",
514
+ "Wallet or token context changed. Retry the transfer."
515
+ );
516
+ }
517
+ writeDecimals(decimals, token, precision);
518
+ }
519
+ const data = encodeErc20Transfer(to, parseUnits(amount, precision));
520
+ return await unref4(options.sendTransaction)({
521
+ to: token.address,
522
+ data,
523
+ value: "0"
524
+ });
525
+ } catch (cause) {
526
+ const normalized = cause instanceof Error ? cause : new Error("Transfer failed");
527
+ if (stillCurrent()) error.value = normalized;
528
+ throw normalized;
529
+ } finally {
530
+ if (stillCurrent()) isSending.value = false;
531
+ }
532
+ };
533
+ onScopeDispose4(() => {
534
+ disposed = true;
535
+ generation++;
536
+ });
537
+ return { sendTransfer, isSending, error };
538
+ }
539
+
540
+ // src/useERC20Approve.ts
541
+ import {
542
+ createDecimalsCache as createDecimalsCache2,
543
+ encodeErc20Approve,
544
+ readDecimals as readDecimals2,
545
+ writeDecimals as writeDecimals2
546
+ } from "@naculus/connect-appkit-core";
547
+ import {
548
+ ERC20_MIN_ABI as ERC20_MIN_ABI2,
549
+ formatUnits,
550
+ parseUnits as parseUnits2,
551
+ WalletError as WalletError3
552
+ } from "@naculus/connect-core";
553
+ import {
554
+ computed as computed3,
555
+ onScopeDispose as onScopeDispose5,
556
+ shallowRef as shallowRef5,
557
+ toValue as toValue4,
558
+ unref as unref5,
559
+ watch as watch3
560
+ } from "vue";
561
+ var MAX_UINT256 = (1n << 256n) - 1n;
562
+ function useERC20Approve(options) {
563
+ const initialToken = toValue4(options.token);
564
+ const decimals = createDecimalsCache2(initialToken, initialToken.decimals);
565
+ const allowanceRaw = shallowRef5(null);
566
+ const isApproving = shallowRef5(false);
567
+ const isFetchingAllowance = shallowRef5(false);
568
+ const error = shallowRef5(null);
569
+ let generation = 0;
570
+ let allowanceGeneration = 0;
571
+ let disposed = false;
572
+ watch3(
573
+ [
574
+ () => toValue4(options.token).address,
575
+ () => toValue4(options.token).chainId,
576
+ () => toValue4(options.token).decimals,
577
+ () => toValue4(options.spender),
578
+ () => toValue4(options.account),
579
+ () => toValue4(options.chainId),
580
+ () => toValue4(options.connected),
581
+ () => toValue4(options.publicClient),
582
+ () => unref5(options.sendTransaction)
583
+ ],
584
+ () => {
585
+ generation++;
586
+ allowanceGeneration++;
587
+ allowanceRaw.value = null;
588
+ isApproving.value = false;
589
+ isFetchingAllowance.value = false;
590
+ error.value = null;
591
+ },
592
+ { flush: "sync" }
593
+ );
594
+ const context = () => {
595
+ const token = toValue4(options.token);
596
+ const account = assertErc20Context(
597
+ token,
598
+ toValue4(options.chainId),
599
+ toValue4(options.account),
600
+ toValue4(options.connected)
601
+ );
602
+ const reader = toValue4(options.publicClient);
603
+ if (!reader)
604
+ throw new WalletError3("wallet_unavailable", "No public client");
605
+ return { token, account, reader, spender: toValue4(options.spender) };
606
+ };
607
+ const readPrecision = async () => {
608
+ const { token, reader } = context();
609
+ let precision = readDecimals2(decimals, token, token.decimals);
610
+ if (precision === void 0) {
611
+ precision = Number(
612
+ await reader.readContract({
613
+ address: token.address,
614
+ abi: ERC20_MIN_ABI2,
615
+ functionName: "decimals"
616
+ })
617
+ );
618
+ writeDecimals2(decimals, token, precision);
619
+ }
620
+ return precision;
621
+ };
622
+ const refetchAllowance = async () => {
623
+ const own = ++allowanceGeneration;
624
+ allowanceRaw.value = null;
625
+ error.value = null;
626
+ isFetchingAllowance.value = true;
627
+ try {
628
+ const { token, account, reader, spender } = context();
629
+ const raw = BigInt(
630
+ await reader.readContract({
631
+ address: token.address,
632
+ abi: ERC20_MIN_ABI2,
633
+ functionName: "allowance",
634
+ args: [account, spender]
635
+ })
636
+ );
637
+ if (disposed || own !== allowanceGeneration) return null;
638
+ allowanceRaw.value = raw;
639
+ return raw;
640
+ } catch (cause) {
641
+ if (!disposed && own === allowanceGeneration) {
642
+ error.value = cause instanceof Error ? cause : new Error("Failed to fetch allowance");
643
+ }
644
+ return null;
645
+ } finally {
646
+ if (!disposed && own === allowanceGeneration)
647
+ isFetchingAllowance.value = false;
648
+ }
649
+ };
650
+ const doApprove = async (rawAmount) => {
651
+ const own = ++generation;
652
+ error.value = null;
653
+ isApproving.value = true;
654
+ try {
655
+ const { token, spender } = context();
656
+ const hash = await unref5(options.sendTransaction)({
657
+ to: token.address,
658
+ data: encodeErc20Approve(spender, rawAmount),
659
+ value: "0"
660
+ });
661
+ if (!disposed && own === generation) void refetchAllowance();
662
+ return hash;
663
+ } catch (cause) {
664
+ const normalized = cause instanceof Error ? cause : new Error("Approve failed");
665
+ if (!disposed && own === generation) error.value = normalized;
666
+ throw normalized;
667
+ } finally {
668
+ if (!disposed && own === generation) isApproving.value = false;
669
+ }
670
+ };
671
+ const approve = async (amount) => {
672
+ const contextGeneration = generation;
673
+ let rawAmount;
674
+ try {
675
+ const precision = await readPrecision();
676
+ if (contextGeneration !== generation || disposed) {
677
+ throw new WalletError3(
678
+ "session_inactive",
679
+ "Wallet or token context changed. Retry the approval."
680
+ );
681
+ }
682
+ rawAmount = parseUnits2(amount, precision);
683
+ } catch (cause) {
684
+ const normalized = cause instanceof Error ? cause : new Error("Approve failed");
685
+ if (!disposed && contextGeneration === generation)
686
+ error.value = normalized;
687
+ throw normalized;
688
+ }
689
+ return doApprove(rawAmount);
690
+ };
691
+ const approveMax = () => doApprove(MAX_UINT256);
692
+ const hasAllowance = async (required) => {
693
+ const raw = allowanceRaw.value ?? await refetchAllowance();
694
+ if (raw === null) return false;
695
+ return raw >= parseUnits2(required, await readPrecision());
696
+ };
697
+ const allowance = computed3(() => {
698
+ if (allowanceRaw.value === null) return null;
699
+ const token = toValue4(options.token);
700
+ const precision = readDecimals2(decimals, token, token.decimals);
701
+ return precision === void 0 ? null : formatUnits(allowanceRaw.value, precision);
702
+ });
703
+ onScopeDispose5(() => {
704
+ disposed = true;
705
+ generation++;
706
+ allowanceGeneration++;
707
+ });
708
+ return {
709
+ approve,
710
+ approveMax,
711
+ allowanceRaw,
712
+ allowance,
713
+ hasAllowance,
714
+ isApproving,
715
+ isFetchingAllowance,
716
+ error,
717
+ refetchAllowance
718
+ };
719
+ }
720
+
721
+ // src/useERC20TransferSimulation.ts
722
+ import { chainNumber, encodeErc20Transfer as encodeErc20Transfer2 } from "@naculus/connect-appkit-core";
723
+ import { parseUnits as parseUnits3 } from "@naculus/connect-core";
724
+ import { computed as computed4, toValue as toValue5 } from "vue";
725
+ function useERC20TransferSimulation(options) {
726
+ const transaction = computed4(() => {
727
+ const token = toValue5(options.token);
728
+ if (!toValue5(options.connected) || !toValue5(options.evmAccount))
729
+ return void 0;
730
+ try {
731
+ if (token.decimals === void 0) return void 0;
732
+ return {
733
+ to: token.address,
734
+ data: encodeErc20Transfer2(
735
+ toValue5(options.to),
736
+ parseUnits3(toValue5(options.amount), token.decimals)
737
+ ),
738
+ value: "0"
739
+ };
740
+ } catch {
741
+ return void 0;
742
+ }
743
+ });
744
+ const chainId = computed4(() => {
745
+ const token = toValue5(options.token);
746
+ if (token.chainId !== void 0) return token.chainId;
747
+ const currentChain = toValue5(options.currentChain);
748
+ return currentChain ? chainNumber(currentChain) ?? void 0 : void 0;
749
+ });
750
+ const simulation = useTransactionSimulation(transaction, {
751
+ chainId,
752
+ currentChain: options.currentChain,
753
+ publicClient: options.publicClient,
754
+ evmAccount: options.evmAccount
755
+ });
756
+ return {
757
+ result: computed4(
758
+ () => transaction.value ? simulation.result.value : void 0
759
+ ),
760
+ isSimulating: computed4(
761
+ () => !!transaction.value && simulation.isSimulating.value
762
+ ),
763
+ error: computed4(() => transaction.value ? simulation.error.value : null),
764
+ reSimulate: simulation.simulate,
765
+ reset: simulation.reset
766
+ };
767
+ }
768
+
769
+ // src/useAccount.ts
770
+ import { computed as computed5, toValue as toValue6 } from "vue";
771
+ function useAccount(accounts, connected) {
772
+ const parsed = useAccounts(accounts);
773
+ const isConnected = computed5(() => toValue6(connected));
774
+ const accountList = computed5(() => toValue6(accounts) ?? []);
775
+ return {
776
+ accounts: computed5(
777
+ () => isConnected.value && accountList.value.length > 0 ? parsed.accounts.value : null
778
+ ),
779
+ evmAccount: computed5(
780
+ () => isConnected.value ? parsed.evmAccount.value : null
781
+ ),
782
+ primaryAccount: computed5(() => accountList.value[0] ?? null),
783
+ isConnected,
784
+ count: computed5(() => accountList.value.length)
785
+ };
786
+ }
787
+
788
+ // src/useSession.ts
789
+ import { computed as computed6, shallowRef as shallowRef6, toValue as toValue7, watch as watch4 } from "vue";
790
+ function readSession(manager) {
791
+ const bundle = manager?.getActiveBundle();
792
+ if (!bundle) {
793
+ return {
794
+ session: null,
795
+ chainSessions: [],
796
+ activeChainId: null,
797
+ connectorId: null
798
+ };
799
+ }
800
+ return {
801
+ session: bundle.walletSession,
802
+ chainSessions: Array.from(bundle.chainSessions.values()),
803
+ activeChainId: bundle.activeChainId,
804
+ connectorId: bundle.walletSession.walletType
805
+ };
806
+ }
807
+ function useSession(manager) {
808
+ const snapshot = shallowRef6(readSession(toValue7(manager)));
809
+ watch4(
810
+ () => toValue7(manager),
811
+ (current, _previous, onCleanup) => {
812
+ const update = () => {
813
+ snapshot.value = readSession(current);
814
+ };
815
+ update();
816
+ if (!current) return;
817
+ current.on("sessionConnected", update);
818
+ current.on("sessionDisconnected", update);
819
+ current.on("chainChanged", update);
820
+ onCleanup(() => {
821
+ current.off("sessionConnected", update);
822
+ current.off("sessionDisconnected", update);
823
+ current.off("chainChanged", update);
824
+ });
825
+ },
826
+ { immediate: true }
827
+ );
828
+ return {
829
+ session: computed6(() => snapshot.value.session),
830
+ chainSessions: computed6(() => snapshot.value.chainSessions),
831
+ activeChainId: computed6(() => snapshot.value.activeChainId),
832
+ isConnected: computed6(() => snapshot.value.session !== null),
833
+ connectorId: computed6(() => snapshot.value.connectorId)
834
+ };
835
+ }
836
+
837
+ // src/useConnect.ts
838
+ import { WalletError as WalletError4 } from "@naculus/connect-core";
839
+ import { computed as computed7, onScopeDispose as onScopeDispose6, shallowRef as shallowRef7, toValue as toValue8, unref as unref6 } from "vue";
840
+ function useConnect(action, status) {
841
+ const isLoading = shallowRef7(false);
842
+ const error = shallowRef7(null);
843
+ let disposed = false;
844
+ let inFlight = null;
845
+ const connect = () => {
846
+ if (inFlight) return inFlight;
847
+ const invoke = unref6(action);
848
+ isLoading.value = true;
849
+ error.value = null;
850
+ const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
851
+ if (disposed) return;
852
+ const message = cause instanceof Error ? cause.message : "Connection failed";
853
+ error.value = cause instanceof WalletError4 ? cause : new Error(message);
854
+ }).finally(() => {
855
+ if (inFlight === pending) inFlight = null;
856
+ if (!disposed) isLoading.value = false;
857
+ });
858
+ inFlight = pending;
859
+ return pending;
860
+ };
861
+ onScopeDispose6(() => {
862
+ disposed = true;
863
+ });
864
+ return {
865
+ connect,
866
+ isConnecting: computed7(
867
+ () => isLoading.value || toValue8(status) === "connecting"
868
+ ),
869
+ error
870
+ };
871
+ }
872
+
873
+ // src/useDisconnect.ts
874
+ import { onScopeDispose as onScopeDispose7, shallowRef as shallowRef8, toValue as toValue9, unref as unref7 } from "vue";
875
+ function useDisconnect(action, status) {
876
+ const isDisconnecting = shallowRef8(false);
877
+ const error = shallowRef8(null);
878
+ let disposed = false;
879
+ let inFlight = null;
880
+ const disconnect = () => {
881
+ if (inFlight) return inFlight;
882
+ if (toValue9(status) === "disconnected") return Promise.resolve();
883
+ const invoke = unref7(action);
884
+ isDisconnecting.value = true;
885
+ error.value = null;
886
+ const pending = Promise.resolve().then(() => invoke()).catch((cause) => {
887
+ if (!disposed) {
888
+ error.value = cause instanceof Error ? cause : new Error("Disconnect failed");
889
+ }
890
+ }).finally(() => {
891
+ if (inFlight === pending) inFlight = null;
892
+ if (!disposed) isDisconnecting.value = false;
893
+ });
894
+ inFlight = pending;
895
+ return pending;
896
+ };
897
+ const cleanup = () => {
898
+ disposed = true;
899
+ };
900
+ onScopeDispose7(cleanup);
901
+ return { disconnect, isDisconnecting, error, cleanup };
902
+ }
903
+
904
+ // src/useSwitchChain.ts
905
+ import { toChainSwitchError } from "@naculus/connect-appkit-core";
906
+ import { computed as computed8, onScopeDispose as onScopeDispose8, shallowRef as shallowRef9, toValue as toValue10, unref as unref8 } from "vue";
907
+ function useSwitchChain(action, chainId) {
908
+ const isSwitching = shallowRef9(false);
909
+ const error = shallowRef9(null);
910
+ let generation = 0;
911
+ let active = 0;
912
+ let disposed = false;
913
+ const switchChain = async (targetChainId) => {
914
+ const invoke = unref8(action);
915
+ const mine = ++generation;
916
+ active++;
917
+ isSwitching.value = true;
918
+ error.value = null;
919
+ try {
920
+ await invoke(targetChainId);
921
+ } catch (cause) {
922
+ const walletError = toChainSwitchError(cause);
923
+ if (!disposed && mine === generation) error.value = walletError;
924
+ throw walletError;
925
+ } finally {
926
+ active--;
927
+ if (!disposed) isSwitching.value = active > 0;
928
+ }
929
+ };
930
+ onScopeDispose8(() => {
931
+ disposed = true;
932
+ generation++;
933
+ });
934
+ return {
935
+ switchChain,
936
+ isSwitching,
937
+ currentChainId: computed8(() => toValue10(chainId) ?? null),
938
+ error,
939
+ clearError: () => {
940
+ error.value = null;
941
+ }
942
+ };
943
+ }
944
+
945
+ // src/useSignMessage.ts
946
+ import { onScopeDispose as onScopeDispose9, shallowRef as shallowRef10, unref as unref9 } from "vue";
947
+ function useSignMessage(action) {
948
+ const isSigning = shallowRef10(false);
949
+ const error = shallowRef10(null);
950
+ let active = 0;
951
+ let generation = 0;
952
+ let disposed = false;
953
+ const signMessage = async (message) => {
954
+ const invoke = unref9(action);
955
+ const own = ++generation;
956
+ active++;
957
+ isSigning.value = true;
958
+ error.value = null;
959
+ try {
960
+ return await invoke(message);
961
+ } catch (cause) {
962
+ const normalized = cause instanceof Error ? cause : new Error("Signing failed");
963
+ if (!disposed && own === generation) error.value = normalized;
964
+ throw normalized;
965
+ } finally {
966
+ active--;
967
+ if (!disposed) isSigning.value = active > 0;
968
+ }
969
+ };
970
+ const reset = () => {
971
+ generation++;
972
+ error.value = null;
973
+ };
974
+ onScopeDispose9(() => {
975
+ disposed = true;
976
+ generation++;
977
+ });
978
+ return { signMessage, isSigning, error, reset };
979
+ }
980
+
981
+ // src/useSendTransaction.ts
982
+ import { computed as computed9, onScopeDispose as onScopeDispose10, shallowRef as shallowRef11, unref as unref10 } from "vue";
983
+ function useSendTransaction(action) {
984
+ const status = shallowRef11("idle");
985
+ const error = shallowRef11(null);
986
+ let generation = 0;
987
+ let disposed = false;
988
+ const sendTransaction = async (transaction) => {
989
+ const invoke = unref10(action);
990
+ const own = ++generation;
991
+ status.value = "awaiting_approval";
992
+ error.value = null;
993
+ try {
994
+ const hash = await invoke(transaction);
995
+ if (!disposed && own === generation) status.value = "submitted";
996
+ return hash;
997
+ } catch (cause) {
998
+ const normalized = cause instanceof Error ? cause : new Error("Transaction failed");
999
+ if (!disposed && own === generation) {
1000
+ status.value = "failed";
1001
+ error.value = normalized;
1002
+ }
1003
+ throw normalized;
1004
+ }
1005
+ };
1006
+ const reset = () => {
1007
+ generation++;
1008
+ status.value = "idle";
1009
+ error.value = null;
1010
+ };
1011
+ onScopeDispose10(() => {
1012
+ disposed = true;
1013
+ generation++;
1014
+ });
1015
+ return {
1016
+ sendTransaction,
1017
+ status,
1018
+ error,
1019
+ reset,
1020
+ isSending: computed9(() => status.value === "awaiting_approval")
1021
+ };
1022
+ }
1023
+
1024
+ // src/useSolanaTransaction.ts
1025
+ import { onScopeDispose as onScopeDispose11, shallowRef as shallowRef12, unref as unref11 } from "vue";
1026
+ function useSolanaTransaction(options) {
1027
+ const isSigning = shallowRef12(false);
1028
+ const isSending = shallowRef12(false);
1029
+ const error = shallowRef12(null);
1030
+ let signing = 0;
1031
+ let sending = 0;
1032
+ let generation = 0;
1033
+ let disposed = false;
1034
+ const signTransaction = async (transaction) => {
1035
+ const invoke = unref11(options.signTransaction);
1036
+ const own = ++generation;
1037
+ signing++;
1038
+ isSigning.value = true;
1039
+ error.value = null;
1040
+ try {
1041
+ return await invoke(transaction);
1042
+ } catch (cause) {
1043
+ const normalized = cause instanceof Error ? cause : new Error("Signing failed");
1044
+ if (!disposed && own === generation) error.value = normalized;
1045
+ throw normalized;
1046
+ } finally {
1047
+ signing--;
1048
+ if (!disposed) isSigning.value = signing > 0;
1049
+ }
1050
+ };
1051
+ const sendTransaction = async (transaction) => {
1052
+ const invoke = unref11(options.sendTransaction);
1053
+ const own = ++generation;
1054
+ sending++;
1055
+ isSending.value = true;
1056
+ error.value = null;
1057
+ try {
1058
+ return await invoke(transaction);
1059
+ } catch (cause) {
1060
+ const normalized = cause instanceof Error ? cause : new Error("Send failed");
1061
+ if (!disposed && own === generation) error.value = normalized;
1062
+ throw normalized;
1063
+ } finally {
1064
+ sending--;
1065
+ if (!disposed) isSending.value = sending > 0;
1066
+ }
1067
+ };
1068
+ const getStatus = (signature) => unref11(options.getStatus)(signature);
1069
+ const reset = () => {
1070
+ generation++;
1071
+ error.value = null;
1072
+ };
1073
+ onScopeDispose11(() => {
1074
+ disposed = true;
1075
+ generation++;
1076
+ });
1077
+ return {
1078
+ signTransaction,
1079
+ sendTransaction,
1080
+ getStatus,
1081
+ isSigning,
1082
+ isSending,
1083
+ error,
1084
+ reset
1085
+ };
1086
+ }
1087
+
1088
+ // src/useSignInWithX.ts
1089
+ import { onScopeDispose as onScopeDispose12, shallowRef as shallowRef13, unref as unref12 } from "vue";
1090
+ function useSignInWithX(action) {
1091
+ const isSigningIn = shallowRef13(false);
1092
+ const result = shallowRef13(null);
1093
+ const error = shallowRef13(null);
1094
+ let generation = 0;
1095
+ let active = 0;
1096
+ let disposed = false;
1097
+ const signIn = async (options) => {
1098
+ const invoke = unref12(action);
1099
+ const own = ++generation;
1100
+ active++;
1101
+ isSigningIn.value = true;
1102
+ error.value = null;
1103
+ try {
1104
+ const next = await invoke(options);
1105
+ if (!disposed && own === generation) result.value = next;
1106
+ return next;
1107
+ } catch (cause) {
1108
+ const normalized = cause instanceof Error ? cause : new Error("SIWX sign-in failed");
1109
+ if (!disposed && own === generation) error.value = normalized;
1110
+ throw normalized;
1111
+ } finally {
1112
+ active--;
1113
+ if (!disposed) isSigningIn.value = active > 0;
1114
+ }
1115
+ };
1116
+ const clearError = () => {
1117
+ error.value = null;
1118
+ };
1119
+ const reset = () => {
1120
+ generation++;
1121
+ result.value = null;
1122
+ error.value = null;
1123
+ };
1124
+ onScopeDispose12(() => {
1125
+ disposed = true;
1126
+ generation++;
1127
+ });
1128
+ return { signIn, isSigningIn, result, error, clearError, reset };
1129
+ }
1130
+
1131
+ // src/useSignInWithEthereum.ts
1132
+ function useSignInWithEthereum(action) {
1133
+ return useSignInWithX(action);
1134
+ }
1135
+
1136
+ // src/useExecuteCalls.ts
1137
+ import { computed as computed10, onScopeDispose as onScopeDispose13, shallowRef as shallowRef14, toValue as toValue11, unref as unref13 } from "vue";
1138
+ function useExecuteCalls(options) {
1139
+ const isExecuting = shallowRef14(false);
1140
+ const error = shallowRef14(null);
1141
+ let generation = 0;
1142
+ let active = 0;
1143
+ let disposed = false;
1144
+ const preview = (callCount, atomicity) => unref13(options.preview)(callCount, atomicity);
1145
+ const execute = async (calls, atomicity) => {
1146
+ const invoke = unref13(options.execute);
1147
+ const own = ++generation;
1148
+ active++;
1149
+ isExecuting.value = true;
1150
+ error.value = null;
1151
+ try {
1152
+ return await invoke(calls, atomicity);
1153
+ } catch (cause) {
1154
+ const normalized = cause instanceof Error ? cause : new Error("Execution failed");
1155
+ if (!disposed && own === generation) error.value = normalized;
1156
+ throw normalized;
1157
+ } finally {
1158
+ active--;
1159
+ if (!disposed) isExecuting.value = active > 0;
1160
+ }
1161
+ };
1162
+ const reset = () => {
1163
+ generation++;
1164
+ error.value = null;
1165
+ unref13(options.reset)();
1166
+ };
1167
+ onScopeDispose13(() => {
1168
+ disposed = true;
1169
+ generation++;
1170
+ });
1171
+ return {
1172
+ preview,
1173
+ execute,
1174
+ isExecuting,
1175
+ error,
1176
+ lastRoute: computed10(() => toValue11(options.lastRoute)),
1177
+ reset
1178
+ };
1179
+ }
1180
+
1181
+ // src/useDelegationPolicy.ts
1182
+ import {
1183
+ bareEvmAddress as bareEvmAddress2,
1184
+ createDelegationPolicyFlow,
1185
+ getSharedSessionKeyManager as getSharedSessionKeyManager2,
1186
+ isVerifiablePolicy
1187
+ } from "@naculus/connect-appkit-core";
1188
+ import {
1189
+ computed as computed12,
1190
+ onScopeDispose as onScopeDispose16,
1191
+ shallowRef as shallowRef17,
1192
+ toValue as toValue13,
1193
+ unref as unref14,
1194
+ watch as watch6
1195
+ } from "vue";
1196
+
1197
+ // src/internal/action-guard.ts
1198
+ import { onScopeDispose as onScopeDispose14, shallowRef as shallowRef15 } from "vue";
1199
+ function useActionGuard() {
1200
+ const busy = shallowRef15(false);
1201
+ const error = shallowRef15(null);
1202
+ let active = 0;
1203
+ let generation = 0;
1204
+ let disposed = false;
1205
+ const run = async (action, fallbackMessage) => {
1206
+ const own = ++generation;
1207
+ active++;
1208
+ busy.value = true;
1209
+ error.value = null;
1210
+ try {
1211
+ return await action();
1212
+ } catch (cause) {
1213
+ const normalized = cause instanceof Error ? cause : new Error(fallbackMessage);
1214
+ if (!disposed && own === generation) error.value = normalized;
1215
+ throw normalized;
1216
+ } finally {
1217
+ active--;
1218
+ if (!disposed) busy.value = active > 0;
1219
+ }
1220
+ };
1221
+ const reset = () => {
1222
+ generation++;
1223
+ error.value = null;
1224
+ };
1225
+ onScopeDispose14(() => {
1226
+ disposed = true;
1227
+ generation++;
1228
+ });
1229
+ return { busy, error, run, reset };
1230
+ }
1231
+
1232
+ // src/useSessionKeys.ts
1233
+ import { getSharedSessionKeyManager } from "@naculus/connect-appkit-core";
1234
+ import { computed as computed11, onScopeDispose as onScopeDispose15, shallowRef as shallowRef16, toValue as toValue12, watch as watch5 } from "vue";
1235
+ function resolveManager(config, options) {
1236
+ return options.manager ?? getSharedSessionKeyManager(config);
1237
+ }
1238
+ function useSessionKeys(connected, config, options = {}) {
1239
+ const manager = resolveManager(config, options);
1240
+ const sessions = shallowRef16([]);
1241
+ const loading = shallowRef16(false);
1242
+ const error = shallowRef16(null);
1243
+ let generation = 0;
1244
+ let disposed = false;
1245
+ const refresh = async () => {
1246
+ const own = ++generation;
1247
+ if (!toValue12(connected)) {
1248
+ sessions.value = [];
1249
+ return;
1250
+ }
1251
+ loading.value = true;
1252
+ error.value = null;
1253
+ try {
1254
+ const keys = await manager.listSessions();
1255
+ if (!disposed && own === generation) sessions.value = keys;
1256
+ } catch (cause) {
1257
+ if (!disposed && own === generation) {
1258
+ error.value = cause instanceof Error ? cause : new Error("Failed to load session keys");
1259
+ }
1260
+ } finally {
1261
+ if (!disposed && own === generation) loading.value = false;
1262
+ }
1263
+ };
1264
+ watch5(
1265
+ () => toValue12(connected),
1266
+ () => {
1267
+ void refresh();
1268
+ },
1269
+ { immediate: true }
1270
+ );
1271
+ onScopeDispose15(() => {
1272
+ disposed = true;
1273
+ generation++;
1274
+ });
1275
+ return {
1276
+ sessions,
1277
+ activeSessions: computed11(
1278
+ () => sessions.value.filter((s) => s.status === "active")
1279
+ ),
1280
+ loading,
1281
+ error,
1282
+ refresh,
1283
+ clearError: () => {
1284
+ error.value = null;
1285
+ },
1286
+ storageAvailable: manager.isStorageAvailable()
1287
+ };
1288
+ }
1289
+ function useCreateSessionKey(config, options = {}) {
1290
+ const manager = resolveManager(config, options);
1291
+ const guard = useActionGuard();
1292
+ const lastCreated = shallowRef16(null);
1293
+ return {
1294
+ createSessionKey: (scope, signerAddress) => guard.run(async () => {
1295
+ const info = await manager.createSessionKey(scope, signerAddress);
1296
+ lastCreated.value = info;
1297
+ return info;
1298
+ }, "Failed to create session key"),
1299
+ lastCreated,
1300
+ isCreating: guard.busy,
1301
+ error: guard.error,
1302
+ clearError: guard.reset
1303
+ };
1304
+ }
1305
+ function useRevokeSession(config, options = {}) {
1306
+ const manager = resolveManager(config, options);
1307
+ const guard = useActionGuard();
1308
+ return {
1309
+ revokeSession: (sessionId) => guard.run(
1310
+ () => manager.revokeSession(sessionId),
1311
+ "Failed to revoke session key"
1312
+ ),
1313
+ isRevoking: guard.busy,
1314
+ error: guard.error,
1315
+ clearError: guard.reset
1316
+ };
1317
+ }
1318
+ function useSendWithSession(config, options = {}) {
1319
+ const manager = resolveManager(config, options);
1320
+ const guard = useActionGuard();
1321
+ return {
1322
+ signWithSession: (sessionId, messageHash, tx) => guard.run(
1323
+ () => manager.signWithSessionKey(sessionId, messageHash, tx),
1324
+ "Failed to sign with session key"
1325
+ ),
1326
+ checkScope: (sessionId, tx) => guard.run(
1327
+ () => manager.checkSessionScope(sessionId, tx),
1328
+ "Failed to check session scope"
1329
+ ),
1330
+ isBusy: guard.busy,
1331
+ error: guard.error,
1332
+ clearError: guard.reset
1333
+ };
1334
+ }
1335
+
1336
+ // src/useDelegationPolicy.ts
1337
+ function useDelegationPolicy(options) {
1338
+ const manager = options.manager ?? getSharedSessionKeyManager2(options.managerConfig);
1339
+ const sessionKeys = useSessionKeys(options.connected, options.managerConfig, {
1340
+ manager
1341
+ });
1342
+ const guard = useActionGuard();
1343
+ const verifiedIds = shallowRef17(/* @__PURE__ */ new Set());
1344
+ const isVerifying = shallowRef17(false);
1345
+ const verifyError = shallowRef17(null);
1346
+ let verifyGeneration = 0;
1347
+ let disposed = false;
1348
+ const origin = options.origin ?? (typeof window !== "undefined" ? window.location.origin : "unknown");
1349
+ const flow = createDelegationPolicyFlow({
1350
+ manager,
1351
+ origin,
1352
+ signer: () => bareEvmAddress2(toValue13(options.account)),
1353
+ signMessage: (message) => unref14(options.signMessage)(message),
1354
+ verifySignature: (input) => unref14(options.verifySignature)(input),
1355
+ previewExecution: (callCount, atomicity) => unref14(options.previewExecution)(callCount, atomicity),
1356
+ sponsorship: options.sponsorship,
1357
+ adapter: options.adapter,
1358
+ delegation: () => toValue13(options.delegation),
1359
+ encryptionKeyConfigured: Boolean(options.managerConfig?.encryptionKey),
1360
+ storageAvailable: () => sessionKeys.storageAvailable,
1361
+ refresh: sessionKeys.refresh
1362
+ });
1363
+ watch6(
1364
+ () => sessionKeys.sessions.value,
1365
+ (sessions) => {
1366
+ const own = ++verifyGeneration;
1367
+ const candidates = sessions.filter(isVerifiablePolicy);
1368
+ if (candidates.length === 0) {
1369
+ verifiedIds.value = /* @__PURE__ */ new Set();
1370
+ isVerifying.value = false;
1371
+ return;
1372
+ }
1373
+ isVerifying.value = true;
1374
+ void Promise.all(
1375
+ candidates.map(
1376
+ async (policy) => [policy.id, await flow.verifyStoredPolicy(policy)]
1377
+ )
1378
+ ).then((results) => {
1379
+ if (disposed || own !== verifyGeneration) return;
1380
+ verifiedIds.value = new Set(
1381
+ results.filter(([, ok]) => ok).map(([id]) => id)
1382
+ );
1383
+ }).catch((cause) => {
1384
+ if (disposed || own !== verifyGeneration) return;
1385
+ verifiedIds.value = /* @__PURE__ */ new Set();
1386
+ verifyError.value = cause instanceof Error ? cause : new Error("Policy verification failed");
1387
+ }).finally(() => {
1388
+ if (!disposed && own === verifyGeneration) isVerifying.value = false;
1389
+ });
1390
+ },
1391
+ { immediate: true }
1392
+ );
1393
+ onScopeDispose16(() => {
1394
+ disposed = true;
1395
+ verifyGeneration++;
1396
+ });
1397
+ return {
1398
+ policies: sessionKeys.sessions,
1399
+ activePolicies: computed12(
1400
+ () => sessionKeys.activeSessions.value.filter(
1401
+ (p) => verifiedIds.value.has(p.id)
1402
+ )
1403
+ ),
1404
+ storageAvailable: sessionKeys.storageAvailable,
1405
+ loading: computed12(() => sessionKeys.loading.value || isVerifying.value),
1406
+ isBusy: guard.busy,
1407
+ error: computed12(
1408
+ () => guard.error.value ?? verifyError.value ?? sessionKeys.error.value
1409
+ ),
1410
+ createPolicy: (scope) => guard.run(() => flow.createPolicy(scope), "Policy creation failed"),
1411
+ revokePolicy: (policyId) => guard.run(() => flow.revokePolicy(policyId), "Policy revocation failed"),
1412
+ previewPolicyExecution: flow.previewPolicyExecution,
1413
+ signPolicyDigest: flow.signPolicyDigest,
1414
+ executePolicy: (policyId, tx) => guard.run(
1415
+ () => flow.executePolicy(policyId, tx),
1416
+ "Policy execution failed"
1417
+ ),
1418
+ refresh: sessionKeys.refresh,
1419
+ clearError: () => {
1420
+ guard.reset();
1421
+ verifyError.value = null;
1422
+ sessionKeys.clearError();
1423
+ }
1424
+ };
1425
+ }
1426
+
1427
+ // src/useSmartAccount.ts
1428
+ import {
1429
+ bareEvmAddress as bareEvmAddress3,
1430
+ buildSmartAccountConfig,
1431
+ resolveEvmChainId
1432
+ } from "@naculus/connect-appkit-core";
1433
+ import { WalletError as WalletError5 } from "@naculus/connect-core";
1434
+ import {
1435
+ computed as computed13,
1436
+ onScopeDispose as onScopeDispose17,
1437
+ shallowRef as shallowRef18,
1438
+ toValue as toValue14,
1439
+ unref as unref15,
1440
+ watch as watch7
1441
+ } from "vue";
1442
+ function useSmartAccount(options) {
1443
+ const address = shallowRef18(null);
1444
+ const isDeployed = shallowRef18(false);
1445
+ const accountInfo = shallowRef18(null);
1446
+ const guard = useActionGuard();
1447
+ const managerRef = shallowRef18(null);
1448
+ let generation = 0;
1449
+ let inFlight = false;
1450
+ let disposed = false;
1451
+ const chainId = computed13(
1452
+ () => resolveEvmChainId(
1453
+ toValue14(options.chainId),
1454
+ toValue14(options.connectedChainId)
1455
+ )
1456
+ );
1457
+ watch7(
1458
+ [
1459
+ () => toValue14(options.manager),
1460
+ () => toValue14(options.rpcUrl),
1461
+ () => toValue14(options.bundlerUrl),
1462
+ () => chainId.value
1463
+ ],
1464
+ ([supplied, rpcUrl, bundlerUrl, chain]) => {
1465
+ const own = ++generation;
1466
+ managerRef.value = null;
1467
+ if (supplied) {
1468
+ managerRef.value = supplied;
1469
+ return;
1470
+ }
1471
+ if (!rpcUrl || !chain) return;
1472
+ import("@naculus/connect-core").then(({ SmartAccountManager }) => {
1473
+ if (disposed || own !== generation) return;
1474
+ managerRef.value = new SmartAccountManager({
1475
+ rpcUrl,
1476
+ chainId: chain,
1477
+ bundlerClient: { url: bundlerUrl ?? "" }
1478
+ });
1479
+ }).catch((cause) => {
1480
+ if (disposed || own !== generation) return;
1481
+ guard.error.value = cause instanceof Error ? cause : new Error("Failed to load account-abstraction module");
1482
+ });
1483
+ },
1484
+ { immediate: true }
1485
+ );
1486
+ const config = computed13(() => {
1487
+ const owner = bareEvmAddress3(toValue14(options.account));
1488
+ const chain = chainId.value;
1489
+ if (!owner || !chain || !managerRef.value) return null;
1490
+ return buildSmartAccountConfig(owner, chain, {
1491
+ accountType: options.accountType,
1492
+ entryPoint: options.entryPoint,
1493
+ salt: options.salt
1494
+ });
1495
+ });
1496
+ const apply = (info) => {
1497
+ address.value = info.address;
1498
+ isDeployed.value = info.isDeployed;
1499
+ accountInfo.value = info;
1500
+ };
1501
+ const operate = async (action, fallback) => {
1502
+ const cfg = config.value;
1503
+ const manager = managerRef.value;
1504
+ if (!cfg || !manager) {
1505
+ guard.error.value = new Error("Smart account not configured");
1506
+ return null;
1507
+ }
1508
+ if (inFlight) {
1509
+ guard.error.value = new Error(
1510
+ "Smart account operation already in progress"
1511
+ );
1512
+ return null;
1513
+ }
1514
+ inFlight = true;
1515
+ const own = generation;
1516
+ const current = () => !disposed && own === generation;
1517
+ const commit = (write) => {
1518
+ if (current()) write();
1519
+ };
1520
+ try {
1521
+ return await guard.run(async () => {
1522
+ const result = await action(manager, cfg, commit);
1523
+ return current() ? result : null;
1524
+ }, fallback);
1525
+ } catch {
1526
+ return null;
1527
+ } finally {
1528
+ inFlight = false;
1529
+ }
1530
+ };
1531
+ const createWallet = () => operate(async (manager, cfg, commit) => {
1532
+ const info = await manager.createAccount(cfg);
1533
+ commit(() => apply(info));
1534
+ return info;
1535
+ }, "Failed to create smart account");
1536
+ const deployWallet = () => operate(async (manager, cfg, commit) => {
1537
+ const send = unref15(options.sendTransaction);
1538
+ if (!send) {
1539
+ throw new WalletError5(
1540
+ "wallet_unavailable",
1541
+ "deployWallet needs the connected wallet's sendTransaction"
1542
+ );
1543
+ }
1544
+ const before = await manager.createAccount(cfg);
1545
+ if (before.isDeployed) {
1546
+ commit(() => apply(before));
1547
+ return before.address;
1548
+ }
1549
+ const deployTx = await manager.getDeployCallData(cfg);
1550
+ const hash = await send({
1551
+ to: deployTx.to,
1552
+ data: deployTx.data,
1553
+ value: deployTx.value.toString(),
1554
+ chainId: cfg.chainId
1555
+ });
1556
+ const after = await manager.createAccount(cfg);
1557
+ commit(() => apply(after));
1558
+ return hash;
1559
+ }, "Failed to deploy smart account");
1560
+ const getAddress = () => operate(async (manager, cfg, commit) => {
1561
+ const addr = await manager.getAccountAddress(cfg);
1562
+ commit(() => {
1563
+ address.value = addr;
1564
+ });
1565
+ return addr;
1566
+ }, "Failed to get smart account address");
1567
+ onScopeDispose17(() => {
1568
+ disposed = true;
1569
+ generation++;
1570
+ });
1571
+ return {
1572
+ address,
1573
+ isDeployed,
1574
+ accountInfo,
1575
+ isLoading: guard.busy,
1576
+ error: guard.error,
1577
+ config,
1578
+ createWallet,
1579
+ deployWallet,
1580
+ getAddress
1581
+ };
1582
+ }
1583
+
1584
+ // src/useSendUserOperation.ts
1585
+ import {
1586
+ bareEvmAddress as bareEvmAddress4,
1587
+ buildSmartAccountConfig as buildSmartAccountConfig2,
1588
+ resolveUserOpChain
1589
+ } from "@naculus/connect-appkit-core";
1590
+ import { WalletError as WalletError6 } from "@naculus/connect-core";
1591
+ import { onScopeDispose as onScopeDispose18, shallowRef as shallowRef19, toValue as toValue15, unref as unref16 } from "vue";
1592
+ function useSendUserOperation(options) {
1593
+ const userOpHash = shallowRef19(null);
1594
+ const receipt = shallowRef19(null);
1595
+ const isPending = shallowRef19(false);
1596
+ const isEstimating = shallowRef19(false);
1597
+ const error = shallowRef19(null);
1598
+ let requestId = 0;
1599
+ let inFlight = false;
1600
+ let disposed = false;
1601
+ const fail = (cause) => {
1602
+ error.value = cause;
1603
+ return null;
1604
+ };
1605
+ const sendUserOp = async (calls, opts) => {
1606
+ const rpcUrl = toValue15(options.rpcUrl);
1607
+ const bundlerUrl = toValue15(options.bundlerUrl);
1608
+ if (!rpcUrl) return fail(new Error("RPC URL not configured"));
1609
+ if (!bundlerUrl) return fail(new Error("Bundler URL not configured"));
1610
+ if (!calls.length) return fail(new Error("At least one call is required"));
1611
+ if (inFlight) {
1612
+ return fail(new Error("A UserOperation is already in progress"));
1613
+ }
1614
+ const owner = bareEvmAddress4(
1615
+ toValue15(options.owner) ?? toValue15(options.account)
1616
+ );
1617
+ if (!owner) {
1618
+ return fail(
1619
+ new WalletError6("wallet_unavailable", "No EVM account found")
1620
+ );
1621
+ }
1622
+ let targetChainId;
1623
+ try {
1624
+ targetChainId = resolveUserOpChain(
1625
+ toValue15(options.chainId),
1626
+ toValue15(options.connectedChainId)
1627
+ );
1628
+ } catch (chainError) {
1629
+ return fail(chainError);
1630
+ }
1631
+ const signer = unref16(options.signer);
1632
+ const own = ++requestId;
1633
+ inFlight = true;
1634
+ isPending.value = true;
1635
+ isEstimating.value = true;
1636
+ error.value = null;
1637
+ userOpHash.value = null;
1638
+ receipt.value = null;
1639
+ try {
1640
+ const { SmartAccountManager } = await import("@naculus/connect-core");
1641
+ const manager = new SmartAccountManager({
1642
+ rpcUrl,
1643
+ bundlerClient: { url: bundlerUrl },
1644
+ chainId: targetChainId,
1645
+ signer,
1646
+ signerMode: options.signerMode ?? "eip191"
1647
+ });
1648
+ const config = buildSmartAccountConfig2(owner, targetChainId, {
1649
+ accountType: options.accountType,
1650
+ entryPoint: options.entryPoint,
1651
+ salt: options.salt
1652
+ });
1653
+ const response = await manager.sendUserOperation(config, calls, opts);
1654
+ if (disposed || own !== requestId) return null;
1655
+ isEstimating.value = false;
1656
+ userOpHash.value = response.userOpHash;
1657
+ void manager.getUserOperationReceipt(response.userOpHash).then((next) => {
1658
+ if (!disposed && own === requestId) receipt.value = next;
1659
+ }).catch(() => void 0);
1660
+ return response;
1661
+ } catch (cause) {
1662
+ if (disposed || own !== requestId) return null;
1663
+ return fail(
1664
+ cause instanceof Error ? cause : new Error("Failed to send UserOperation")
1665
+ );
1666
+ } finally {
1667
+ inFlight = false;
1668
+ if (!disposed && own === requestId) {
1669
+ isPending.value = false;
1670
+ isEstimating.value = false;
1671
+ }
1672
+ }
1673
+ };
1674
+ const reset = () => {
1675
+ requestId++;
1676
+ userOpHash.value = null;
1677
+ receipt.value = null;
1678
+ isPending.value = false;
1679
+ isEstimating.value = false;
1680
+ error.value = null;
1681
+ };
1682
+ onScopeDispose18(() => {
1683
+ disposed = true;
1684
+ requestId++;
1685
+ });
1686
+ return {
1687
+ sendUserOp,
1688
+ userOpHash,
1689
+ receipt,
1690
+ isPending,
1691
+ isEstimating,
1692
+ error,
1693
+ reset
1694
+ };
1695
+ }
1696
+
1697
+ // src/useUserOpStatus.ts
1698
+ import {
1699
+ fetchUserOperationReceipt,
1700
+ InvalidUserOperationReceiptError
1701
+ } from "@naculus/connect-appkit-core";
1702
+ import { onScopeDispose as onScopeDispose19, shallowRef as shallowRef20, toValue as toValue16 } from "vue";
1703
+ function useUserOpStatus(options) {
1704
+ const status = shallowRef20("idle");
1705
+ const receipt = shallowRef20(null);
1706
+ const userOpHash = shallowRef20(null);
1707
+ const error = shallowRef20(null);
1708
+ const isPolling = shallowRef20(false);
1709
+ const elapsedMs = shallowRef20(0);
1710
+ const attempts = shallowRef20(0);
1711
+ const pollInterval = options.pollInterval ?? 2e3;
1712
+ const maxRetries = options.maxRetries ?? 30;
1713
+ let generation = 0;
1714
+ let startedAt = 0;
1715
+ let ticker = null;
1716
+ let timer = null;
1717
+ let controller = null;
1718
+ const clearTimers = () => {
1719
+ if (ticker) clearInterval(ticker);
1720
+ if (timer) clearTimeout(timer);
1721
+ ticker = null;
1722
+ timer = null;
1723
+ };
1724
+ const finish = (next, cause) => {
1725
+ status.value = next;
1726
+ error.value = cause;
1727
+ isPolling.value = false;
1728
+ clearTimers();
1729
+ };
1730
+ const poll = async (hash, own) => {
1731
+ const bundlerUrl = toValue16(options.bundlerUrl);
1732
+ if (!bundlerUrl || own !== generation) return;
1733
+ const attempt = ++attempts.value;
1734
+ const abort = new AbortController();
1735
+ controller = abort;
1736
+ try {
1737
+ const next = await fetchUserOperationReceipt(
1738
+ bundlerUrl,
1739
+ hash,
1740
+ abort.signal
1741
+ );
1742
+ if (own !== generation) return;
1743
+ if (next) {
1744
+ receipt.value = next;
1745
+ finish(next.success ? "confirmed" : "failed", null);
1746
+ return;
1747
+ }
1748
+ status.value = "pending";
1749
+ if (attempt <= maxRetries) {
1750
+ timer = setTimeout(() => void poll(hash, own), pollInterval);
1751
+ } else {
1752
+ finish(
1753
+ "not_found",
1754
+ new Error("UserOperation not included after maximum retries")
1755
+ );
1756
+ }
1757
+ } catch (cause) {
1758
+ if (own !== generation || abort.signal.aborted) return;
1759
+ const next = cause instanceof Error ? cause : new Error("Unknown bundler response failure");
1760
+ if (next instanceof InvalidUserOperationReceiptError) {
1761
+ finish("not_found", next);
1762
+ return;
1763
+ }
1764
+ if (attempt <= maxRetries) {
1765
+ timer = setTimeout(() => void poll(hash, own), pollInterval);
1766
+ } else {
1767
+ finish(
1768
+ "not_found",
1769
+ new Error(
1770
+ `UserOperation status unavailable after ${attempt} attempt${attempt === 1 ? "" : "s"}: ${next.message}`
1771
+ )
1772
+ );
1773
+ }
1774
+ } finally {
1775
+ if (controller === abort) controller = null;
1776
+ }
1777
+ };
1778
+ const start = (hash) => {
1779
+ const own = ++generation;
1780
+ controller?.abort();
1781
+ controller = null;
1782
+ clearTimers();
1783
+ userOpHash.value = hash;
1784
+ receipt.value = null;
1785
+ error.value = null;
1786
+ attempts.value = 0;
1787
+ elapsedMs.value = 0;
1788
+ if (!toValue16(options.bundlerUrl)) {
1789
+ finish("not_found", new Error("Bundler URL not configured"));
1790
+ return;
1791
+ }
1792
+ status.value = "pending";
1793
+ isPolling.value = true;
1794
+ startedAt = Date.now();
1795
+ ticker = setInterval(() => {
1796
+ elapsedMs.value = Date.now() - startedAt;
1797
+ }, 1e3);
1798
+ void poll(hash, own);
1799
+ };
1800
+ const stop = () => {
1801
+ generation++;
1802
+ controller?.abort();
1803
+ controller = null;
1804
+ clearTimers();
1805
+ isPolling.value = false;
1806
+ };
1807
+ const reset = () => {
1808
+ stop();
1809
+ status.value = "idle";
1810
+ receipt.value = null;
1811
+ userOpHash.value = null;
1812
+ error.value = null;
1813
+ attempts.value = 0;
1814
+ elapsedMs.value = 0;
1815
+ };
1816
+ onScopeDispose19(stop);
1817
+ return {
1818
+ status,
1819
+ receipt,
1820
+ userOpHash,
1821
+ error,
1822
+ isPolling,
1823
+ elapsedMs,
1824
+ attempts,
1825
+ start,
1826
+ stop,
1827
+ reset
1828
+ };
1829
+ }
1830
+
1831
+ // src/useSendCalls.ts
1832
+ import { computed as computed14, onScopeDispose as onScopeDispose20, shallowRef as shallowRef21, toValue as toValue17, unref as unref17 } from "vue";
1833
+ function useSendCalls(options) {
1834
+ const status = shallowRef21("idle");
1835
+ const error = shallowRef21(null);
1836
+ const batchHash = shallowRef21(null);
1837
+ const callsStatus = shallowRef21(null);
1838
+ let sendGeneration = 0;
1839
+ let statusGeneration = 0;
1840
+ let disposed = false;
1841
+ const sendCalls = async (calls, input) => {
1842
+ const invoke = unref17(options.sendCalls);
1843
+ const own = ++sendGeneration;
1844
+ status.value = "awaiting_approval";
1845
+ error.value = null;
1846
+ batchHash.value = null;
1847
+ try {
1848
+ const hash = await invoke(calls, input);
1849
+ if (!disposed && own === sendGeneration) {
1850
+ status.value = "submitted";
1851
+ batchHash.value = hash;
1852
+ }
1853
+ return hash;
1854
+ } catch (cause) {
1855
+ const normalized = cause instanceof Error ? cause : new Error("sendCalls failed");
1856
+ if (!disposed && own === sendGeneration) {
1857
+ status.value = "failed";
1858
+ error.value = normalized;
1859
+ }
1860
+ throw normalized;
1861
+ }
1862
+ };
1863
+ const getCallsStatus = async (hash) => {
1864
+ const invoke = unref17(options.getCallsStatus);
1865
+ const own = ++statusGeneration;
1866
+ const result = await invoke(hash);
1867
+ if (!disposed && own === statusGeneration) callsStatus.value = result;
1868
+ return result;
1869
+ };
1870
+ const showCallsStatus = (hash) => unref17(options.showCallsStatus)(hash);
1871
+ const reset = () => {
1872
+ sendGeneration++;
1873
+ statusGeneration++;
1874
+ status.value = "idle";
1875
+ error.value = null;
1876
+ batchHash.value = null;
1877
+ callsStatus.value = null;
1878
+ };
1879
+ onScopeDispose20(() => {
1880
+ disposed = true;
1881
+ sendGeneration++;
1882
+ statusGeneration++;
1883
+ });
1884
+ return {
1885
+ sendCalls,
1886
+ getCallsStatus,
1887
+ showCallsStatus,
1888
+ status,
1889
+ error,
1890
+ batchHash,
1891
+ callsStatus,
1892
+ execution: computed14(() => toValue17(options.execution) ?? null),
1893
+ isSending: computed14(() => status.value === "awaiting_approval"),
1894
+ reset
1895
+ };
1896
+ }
1897
+
1898
+ // src/useEmbeddedWallet.ts
1899
+ import { computed as computed15, onScopeDispose as onScopeDispose21, shallowRef as shallowRef22, toValue as toValue18, unref as unref18 } from "vue";
1900
+ function useEmbeddedWallet(options) {
1901
+ const isBusy = shallowRef22(false);
1902
+ const error = shallowRef22(null);
1903
+ let active = 0;
1904
+ let generation = 0;
1905
+ let disposed = false;
1906
+ const run = async (action) => {
1907
+ const own = ++generation;
1908
+ active++;
1909
+ isBusy.value = true;
1910
+ error.value = null;
1911
+ try {
1912
+ return await action();
1913
+ } catch (cause) {
1914
+ const normalized = cause instanceof Error ? cause : new Error("Embedded wallet action failed");
1915
+ if (!disposed && own === generation) error.value = normalized;
1916
+ throw normalized;
1917
+ } finally {
1918
+ active--;
1919
+ if (!disposed) isBusy.value = active > 0;
1920
+ }
1921
+ };
1922
+ const wallet = computed15(() => toValue18(options.wallet));
1923
+ onScopeDispose21(() => {
1924
+ disposed = true;
1925
+ generation++;
1926
+ });
1927
+ return {
1928
+ wallet,
1929
+ hasWallet: computed15(() => wallet.value !== null),
1930
+ address: computed15(() => wallet.value?.address ?? null),
1931
+ accounts: computed15(() => wallet.value?.accounts ?? []),
1932
+ activeNamespace: computed15(() => wallet.value?.activeNamespace ?? null),
1933
+ backupPending: computed15(() => toValue18(options.backupPending)),
1934
+ storageSecurityLevel: computed15(() => toValue18(options.storageSecurityLevel)),
1935
+ securityReport: computed15(() => toValue18(options.securityReport)),
1936
+ connectEmbedded: () => run(() => unref18(options.connectEmbedded)()),
1937
+ restoreWallet: () => run(() => unref18(options.restoreWallet)()),
1938
+ generateWallet: () => run(() => unref18(options.generateWallet)()),
1939
+ importFromMnemonic: (value) => run(() => unref18(options.importFromMnemonic)(value)),
1940
+ importFromPrivateKey: (value) => run(() => unref18(options.importFromPrivateKey)(value)),
1941
+ wipe: () => run(() => unref18(options.wipe)()),
1942
+ setActiveNamespace: (value) => unref18(options.setActiveNamespace)(value),
1943
+ backfillAccounts: () => run(() => unref18(options.backfillAccounts)()),
1944
+ getSeedPhrase: () => unref18(options.getSeedPhrase)(),
1945
+ getPrivateKey: () => unref18(options.getPrivateKey)(),
1946
+ confirmBackup: () => unref18(options.confirmBackup)(),
1947
+ isBusy,
1948
+ error,
1949
+ clearError: () => {
1950
+ error.value = null;
1951
+ }
1952
+ };
1953
+ }
1954
+
1955
+ // src/useSIWxLogin.ts
1956
+ function useSIWxLogin(action) {
1957
+ const state = useSignInWithX(action);
1958
+ return {
1959
+ signIn: state.signIn,
1960
+ isSigningIn: state.isSigningIn,
1961
+ error: state.error,
1962
+ clearError: state.clearError
1963
+ };
1964
+ }
1965
+
1966
+ // src/useSIWxSession.ts
1967
+ import { computed as computed16, onScopeDispose as onScopeDispose22, shallowRef as shallowRef23, toValue as toValue19, unref as unref19 } from "vue";
1968
+ function useSIWxSession(options) {
1969
+ const isSigningIn = shallowRef23(false);
1970
+ const error = shallowRef23(null);
1971
+ let generation = 0;
1972
+ let active = 0;
1973
+ let disposed = false;
1974
+ const run = async (action, message) => {
1975
+ const own = ++generation;
1976
+ active++;
1977
+ isSigningIn.value = true;
1978
+ error.value = null;
1979
+ try {
1980
+ return await action();
1981
+ } catch (cause) {
1982
+ const normalized = cause instanceof Error ? cause : new Error(message);
1983
+ if (!disposed && own === generation) error.value = normalized;
1984
+ throw normalized;
1985
+ } finally {
1986
+ active--;
1987
+ if (!disposed) isSigningIn.value = active > 0;
1988
+ }
1989
+ };
1990
+ onScopeDispose22(() => {
1991
+ disposed = true;
1992
+ generation++;
1993
+ });
1994
+ return {
1995
+ session: computed16(() => toValue19(options.session)),
1996
+ isAuthenticated: computed16(
1997
+ () => toValue19(options.session) !== null && !toValue19(options.isExpired)
1998
+ ),
1999
+ isRestoring: computed16(() => toValue19(options.isRestoring)),
2000
+ isSigningIn,
2001
+ isExpired: computed16(() => toValue19(options.isExpired)),
2002
+ timeUntilExpiry: computed16(() => toValue19(options.timeUntilExpiry)),
2003
+ signIn: (input) => run(() => unref19(options.signIn)(input), "SIWX sign-in failed"),
2004
+ signOut: async () => {
2005
+ await unref19(options.signOut)();
2006
+ error.value = null;
2007
+ },
2008
+ refresh: () => run(() => unref19(options.refresh)(), "Session refresh failed"),
2009
+ error,
2010
+ clearError: () => {
2011
+ error.value = null;
2012
+ }
2013
+ };
2014
+ }
2015
+
2016
+ // src/useSiwxAuthSession.ts
2017
+ import { computed as computed17, onScopeDispose as onScopeDispose23, shallowRef as shallowRef24, toValue as toValue20, unref as unref20 } from "vue";
2018
+ function useSiwxAuthSession(options) {
2019
+ const isSigningIn = shallowRef24(false);
2020
+ const error = shallowRef24(null);
2021
+ let generation = 0;
2022
+ let disposed = false;
2023
+ const signIn = async (input) => {
2024
+ const own = ++generation;
2025
+ isSigningIn.value = true;
2026
+ error.value = null;
2027
+ try {
2028
+ return await unref20(options.signIn)(input);
2029
+ } catch (cause) {
2030
+ const normalized = cause instanceof Error ? cause : new Error("SIWX sign-in failed");
2031
+ if (!disposed && own === generation) error.value = normalized;
2032
+ throw normalized;
2033
+ } finally {
2034
+ if (!disposed && own === generation) isSigningIn.value = false;
2035
+ }
2036
+ };
2037
+ const signOut = async () => {
2038
+ generation++;
2039
+ await unref20(options.signOut)();
2040
+ if (!disposed) {
2041
+ isSigningIn.value = false;
2042
+ error.value = null;
2043
+ }
2044
+ };
2045
+ onScopeDispose23(() => {
2046
+ disposed = true;
2047
+ generation++;
2048
+ });
2049
+ const siwxResult = computed17(() => toValue20(options.result));
2050
+ return {
2051
+ isSignedIn: computed17(() => siwxResult.value !== null),
2052
+ isRestoring: computed17(() => toValue20(options.isRestoring)),
2053
+ siwxResult,
2054
+ isSigningIn,
2055
+ error,
2056
+ signIn,
2057
+ signOut,
2058
+ clearError: () => {
2059
+ error.value = null;
2060
+ }
2061
+ };
2062
+ }
2063
+
2064
+ // src/useBalance.ts
2065
+ import { bareEvmAddress as bareEvmAddress5 } from "@naculus/connect-appkit-core";
2066
+ import { formatUnits as formatUnits2 } from "@naculus/connect-core";
2067
+ import { computed as computed18, onScopeDispose as onScopeDispose24, shallowRef as shallowRef25, toValue as toValue21, watch as watch8 } from "vue";
2068
+ function useBalance(account, client, options = {}) {
2069
+ const balance = shallowRef25(null);
2070
+ const isFetching = shallowRef25(false);
2071
+ const error = shallowRef25(null);
2072
+ let generation = 0;
2073
+ let disposed = false;
2074
+ let timer = null;
2075
+ const refetch = async () => {
2076
+ const reader = toValue21(client);
2077
+ const address = bareEvmAddress5(toValue21(account));
2078
+ const own = ++generation;
2079
+ if (!reader || !address) {
2080
+ balance.value = null;
2081
+ error.value = null;
2082
+ isFetching.value = false;
2083
+ return;
2084
+ }
2085
+ isFetching.value = true;
2086
+ error.value = null;
2087
+ try {
2088
+ const next = await reader.getBalance({ address });
2089
+ if (disposed || own !== generation) return;
2090
+ balance.value = next.toString();
2091
+ } catch (cause) {
2092
+ if (disposed || own !== generation) return;
2093
+ balance.value = null;
2094
+ error.value = cause instanceof Error ? cause : new Error("Balance read failed");
2095
+ } finally {
2096
+ if (!disposed && own === generation) isFetching.value = false;
2097
+ }
2098
+ };
2099
+ const stopTimer = () => {
2100
+ if (timer) clearInterval(timer);
2101
+ timer = null;
2102
+ };
2103
+ watch8(
2104
+ [
2105
+ () => toValue21(account),
2106
+ () => toValue21(client),
2107
+ () => toValue21(options.refreshInterval) ?? 0
2108
+ ],
2109
+ ([, , interval]) => {
2110
+ stopTimer();
2111
+ void refetch();
2112
+ if (interval > 0) timer = setInterval(() => void refetch(), interval);
2113
+ },
2114
+ { immediate: true }
2115
+ );
2116
+ onScopeDispose24(() => {
2117
+ disposed = true;
2118
+ generation++;
2119
+ stopTimer();
2120
+ });
2121
+ return {
2122
+ balance,
2123
+ formatted: computed18(
2124
+ () => balance.value === null ? null : formatUnits2(BigInt(balance.value), toValue21(options.decimals) ?? 18)
2125
+ ),
2126
+ symbol: computed18(() => toValue21(options.symbol) ?? null),
2127
+ isFetching,
2128
+ error,
2129
+ refetch
2130
+ };
2131
+ }
2132
+
2133
+ // src/useRouteQuote.ts
2134
+ import {
2135
+ isQuotableInput
2136
+ } from "@naculus/connect-appkit-core";
2137
+ import { onScopeDispose as onScopeDispose25, shallowRef as shallowRef26, toValue as toValue22, unref as unref21, watch as watch9 } from "vue";
2138
+ function useRouteQuote(input, getQuotes, options = {}) {
2139
+ const quotes = shallowRef26([]);
2140
+ const loading = shallowRef26(false);
2141
+ const error = shallowRef26(null);
2142
+ let generation = 0;
2143
+ let disposed = false;
2144
+ let timer = null;
2145
+ const clearTimer = () => {
2146
+ if (timer) clearTimeout(timer);
2147
+ timer = null;
2148
+ };
2149
+ const fetchQuotes = async () => {
2150
+ const current = toValue22(input);
2151
+ const fn = unref21(getQuotes);
2152
+ const own = ++generation;
2153
+ if (!isQuotableInput(current)) {
2154
+ quotes.value = [];
2155
+ return;
2156
+ }
2157
+ if (!fn) return;
2158
+ loading.value = true;
2159
+ error.value = null;
2160
+ try {
2161
+ const result = await fn(
2162
+ current.fromChain,
2163
+ current.toChain,
2164
+ current.fromToken,
2165
+ current.amount,
2166
+ current.options,
2167
+ current.toToken
2168
+ );
2169
+ if (disposed || own !== generation) return;
2170
+ quotes.value = result;
2171
+ } catch (cause) {
2172
+ if (disposed || own !== generation) return;
2173
+ error.value = cause instanceof Error ? cause : new Error(String(cause));
2174
+ quotes.value = [];
2175
+ } finally {
2176
+ if (!disposed && own === generation) loading.value = false;
2177
+ }
2178
+ };
2179
+ watch9(
2180
+ [
2181
+ () => toValue22(input).fromChain,
2182
+ () => toValue22(input).toChain,
2183
+ () => toValue22(input).fromToken,
2184
+ () => toValue22(input).toToken,
2185
+ () => toValue22(input).amount,
2186
+ () => unref21(getQuotes)
2187
+ ],
2188
+ ([fromChain, toChain, fromToken, , amount]) => {
2189
+ clearTimer();
2190
+ if (!fromChain || !toChain || !fromToken || !amount) {
2191
+ quotes.value = [];
2192
+ return;
2193
+ }
2194
+ timer = setTimeout(() => {
2195
+ timer = null;
2196
+ void fetchQuotes();
2197
+ }, options.debounceMs ?? 300);
2198
+ },
2199
+ { immediate: true }
2200
+ );
2201
+ onScopeDispose25(() => {
2202
+ disposed = true;
2203
+ generation++;
2204
+ clearTimer();
2205
+ });
2206
+ return {
2207
+ quotes,
2208
+ loading,
2209
+ error,
2210
+ refresh: fetchQuotes,
2211
+ clear: () => {
2212
+ clearTimer();
2213
+ generation++;
2214
+ quotes.value = [];
2215
+ error.value = null;
2216
+ loading.value = false;
2217
+ }
2218
+ };
2219
+ }
2220
+
2221
+ // src/useCompareCosts.ts
2222
+ import {
2223
+ compareCostsKey
2224
+ } from "@naculus/connect-appkit-core";
2225
+ import { onScopeDispose as onScopeDispose26, shallowRef as shallowRef27, toValue as toValue23, unref as unref22, watch as watch10 } from "vue";
2226
+ function useCompareCosts(input, compareCosts) {
2227
+ const comparisons = shallowRef27([]);
2228
+ const loading = shallowRef27(false);
2229
+ const error = shallowRef27(null);
2230
+ let generation = 0;
2231
+ let disposed = false;
2232
+ const fetchComparisons = async () => {
2233
+ const { operation, chains, options } = toValue23(input);
2234
+ const fn = unref22(compareCosts);
2235
+ const own = ++generation;
2236
+ if (!chains || chains.length === 0) {
2237
+ comparisons.value = [];
2238
+ return;
2239
+ }
2240
+ if (!fn) return;
2241
+ loading.value = true;
2242
+ error.value = null;
2243
+ try {
2244
+ const result = await fn(operation, chains, options);
2245
+ if (disposed || own !== generation) return;
2246
+ comparisons.value = result;
2247
+ } catch (cause) {
2248
+ if (disposed || own !== generation) return;
2249
+ error.value = cause instanceof Error ? cause : new Error(String(cause));
2250
+ comparisons.value = [];
2251
+ } finally {
2252
+ if (!disposed && own === generation) loading.value = false;
2253
+ }
2254
+ };
2255
+ watch10(
2256
+ [() => compareCostsKey(toValue23(input)), () => unref22(compareCosts)],
2257
+ () => {
2258
+ void fetchComparisons();
2259
+ },
2260
+ { immediate: true }
2261
+ );
2262
+ onScopeDispose26(() => {
2263
+ disposed = true;
2264
+ generation++;
2265
+ });
2266
+ return { comparisons, loading, error, refresh: fetchComparisons };
2267
+ }
2268
+
2269
+ // src/useExecuteRoute.ts
2270
+ import {
2271
+ toExecuteRouteError,
2272
+ validateRouteRecipient
2273
+ } from "@naculus/connect-appkit-core";
2274
+ import { onScopeDispose as onScopeDispose27, shallowRef as shallowRef28, unref as unref23 } from "vue";
2275
+ function useExecuteRoute(executeRoute) {
2276
+ const executing = shallowRef28(false);
2277
+ const result = shallowRef28(null);
2278
+ const error = shallowRef28(null);
2279
+ let inFlight = false;
2280
+ let disposed = false;
2281
+ const execute = async (quote, recipient, options) => {
2282
+ const fn = unref23(executeRoute);
2283
+ if (!fn) {
2284
+ error.value = {
2285
+ code: "no_executor",
2286
+ message: "No executeRoute function provided"
2287
+ };
2288
+ result.value = null;
2289
+ return null;
2290
+ }
2291
+ const recipientError = validateRouteRecipient(quote, recipient);
2292
+ if (recipientError) {
2293
+ error.value = recipientError;
2294
+ result.value = null;
2295
+ return null;
2296
+ }
2297
+ if (inFlight) {
2298
+ error.value = {
2299
+ code: "execution_in_progress",
2300
+ message: "A route execution is already in progress"
2301
+ };
2302
+ return null;
2303
+ }
2304
+ inFlight = true;
2305
+ executing.value = true;
2306
+ error.value = null;
2307
+ result.value = null;
2308
+ try {
2309
+ const execResult = await fn(quote, recipient, options);
2310
+ if (!disposed) result.value = execResult;
2311
+ return execResult;
2312
+ } catch (cause) {
2313
+ if (!disposed) error.value = toExecuteRouteError(cause);
2314
+ return null;
2315
+ } finally {
2316
+ inFlight = false;
2317
+ if (!disposed) executing.value = false;
2318
+ }
2319
+ };
2320
+ onScopeDispose27(() => {
2321
+ disposed = true;
2322
+ });
2323
+ return {
2324
+ execute,
2325
+ executing,
2326
+ result,
2327
+ error,
2328
+ reset: () => {
2329
+ result.value = null;
2330
+ error.value = null;
2331
+ executing.value = false;
2332
+ }
2333
+ };
2334
+ }
2335
+
2336
+ // src/useTokenList.ts
2337
+ import { eip155ChainIdToNumber } from "@naculus/connect-appkit-core";
2338
+ import {
2339
+ TokenListManager
2340
+ } from "@naculus/connect-core";
2341
+ import { onScopeDispose as onScopeDispose28, shallowRef as shallowRef29, toValue as toValue24, watch as watch11 } from "vue";
2342
+ function useTokenList(chainId, options = {}) {
2343
+ const config = {};
2344
+ if (options.sources) config.sources = options.sources;
2345
+ const manager = options.manager ?? new TokenListManager(config);
2346
+ const tokens = shallowRef29([]);
2347
+ const isLoading = shallowRef29(options.autoLoad !== false);
2348
+ const isLoaded = shallowRef29(false);
2349
+ const error = shallowRef29(null);
2350
+ let generation = 0;
2351
+ let disposed = false;
2352
+ const select = () => {
2353
+ const id = toValue24(chainId);
2354
+ const numeric = id ? eip155ChainIdToNumber(id) : void 0;
2355
+ return manager.getTokens(
2356
+ numeric !== void 0 ? { chainId: numeric } : void 0
2357
+ );
2358
+ };
2359
+ const run = async (op) => {
2360
+ const own = ++generation;
2361
+ isLoading.value = true;
2362
+ error.value = null;
2363
+ try {
2364
+ await op();
2365
+ if (disposed || own !== generation) return;
2366
+ tokens.value = select();
2367
+ isLoaded.value = true;
2368
+ } catch (cause) {
2369
+ if (disposed || own !== generation) return;
2370
+ error.value = cause instanceof Error ? cause : new Error(String(cause));
2371
+ } finally {
2372
+ if (!disposed && own === generation) isLoading.value = false;
2373
+ }
2374
+ };
2375
+ watch11(
2376
+ () => toValue24(chainId),
2377
+ () => {
2378
+ if (options.autoLoad !== false) void run(() => manager.load());
2379
+ },
2380
+ { immediate: true }
2381
+ );
2382
+ onScopeDispose28(() => {
2383
+ disposed = true;
2384
+ generation++;
2385
+ });
2386
+ return {
2387
+ tokens,
2388
+ isLoading,
2389
+ isLoaded,
2390
+ error,
2391
+ refetch: () => run(() => manager.refresh())
2392
+ };
2393
+ }
2394
+
2395
+ // src/useTokenSearch.ts
2396
+ import { eip155ChainIdToNumber as eip155ChainIdToNumber2 } from "@naculus/connect-appkit-core";
2397
+ import {
2398
+ TokenListManager as TokenListManager2
2399
+ } from "@naculus/connect-core";
2400
+ import { onScopeDispose as onScopeDispose29, shallowRef as shallowRef30, toValue as toValue25, watch as watch12 } from "vue";
2401
+ var DEBOUNCE_MS = 300;
2402
+ var EMPTY = { exact: [], fuzzy: [], hasMore: false };
2403
+ var sharedManager = null;
2404
+ function getSharedManager() {
2405
+ if (!sharedManager) {
2406
+ sharedManager = new TokenListManager2();
2407
+ sharedManager.load().catch(() => {
2408
+ });
2409
+ }
2410
+ return sharedManager;
2411
+ }
2412
+ function useTokenSearch(query, chainId, options = {}) {
2413
+ const results = shallowRef30(EMPTY);
2414
+ const isSearching = shallowRef30(false);
2415
+ let timer = null;
2416
+ const clear = () => {
2417
+ if (timer) clearTimeout(timer);
2418
+ timer = null;
2419
+ };
2420
+ watch12(
2421
+ [() => (toValue25(query) ?? "").trim(), () => toValue25(chainId)],
2422
+ ([q, id]) => {
2423
+ clear();
2424
+ if (!q) {
2425
+ results.value = EMPTY;
2426
+ isSearching.value = false;
2427
+ return;
2428
+ }
2429
+ isSearching.value = true;
2430
+ timer = setTimeout(() => {
2431
+ timer = null;
2432
+ const manager = options.manager ?? getSharedManager();
2433
+ const numeric = id ? eip155ChainIdToNumber2(id) : void 0;
2434
+ results.value = manager.search(q, {
2435
+ chainId: numeric,
2436
+ limit: options.limit ?? 20
2437
+ });
2438
+ isSearching.value = false;
2439
+ }, options.debounceMs ?? DEBOUNCE_MS);
2440
+ },
2441
+ { immediate: true }
2442
+ );
2443
+ onScopeDispose29(clear);
2444
+ return { results, isSearching };
2445
+ }
2446
+
2447
+ // src/useValidateDestination.ts
2448
+ import {
2449
+ validateDestination
2450
+ } from "@naculus/connect-appkit-core";
2451
+ import { computed as computed19, toValue as toValue26 } from "vue";
2452
+ function useValidateDestination(address) {
2453
+ return {
2454
+ validation: computed19(() => validateDestination(toValue26(address) ?? ""))
2455
+ };
2456
+ }
2457
+
2458
+ // src/useTokenBalance.ts
2459
+ import { bareEvmAddress as bareEvmAddress6 } from "@naculus/connect-appkit-core";
2460
+ import { ERC20_MIN_ABI as ERC20_MIN_ABI3, formatUnits as formatUnits3 } from "@naculus/connect-core";
2461
+ import { onScopeDispose as onScopeDispose30, shallowRef as shallowRef31, toValue as toValue27, watch as watch13 } from "vue";
2462
+ function tokensKey(tokens) {
2463
+ return tokens.map((t) => `${t.address.toLowerCase()}|${t.decimals}|${t.symbol}`).join(",");
2464
+ }
2465
+ function useTokenBalance(account, client, tokens, options = {}) {
2466
+ const tokenBalances = shallowRef31([]);
2467
+ const isFetching = shallowRef31(false);
2468
+ const error = shallowRef31(null);
2469
+ let generation = 0;
2470
+ let disposed = false;
2471
+ let timer = null;
2472
+ const refetch = async () => {
2473
+ const reader = toValue27(client);
2474
+ const address = bareEvmAddress6(toValue27(account));
2475
+ const list = toValue27(tokens) ?? [];
2476
+ const own = ++generation;
2477
+ if (!reader || !address || list.length === 0) {
2478
+ tokenBalances.value = [];
2479
+ error.value = null;
2480
+ isFetching.value = false;
2481
+ return;
2482
+ }
2483
+ isFetching.value = true;
2484
+ error.value = null;
2485
+ try {
2486
+ const results = await Promise.all(
2487
+ list.map(async (token) => {
2488
+ try {
2489
+ const raw = await reader.readContract({
2490
+ address: token.address,
2491
+ abi: ERC20_MIN_ABI3,
2492
+ functionName: "balanceOf",
2493
+ args: [address]
2494
+ });
2495
+ const value = BigInt(raw);
2496
+ return {
2497
+ ...token,
2498
+ balance: value.toString(),
2499
+ formatted: formatUnits3(value, token.decimals)
2500
+ };
2501
+ } catch {
2502
+ return { ...token, balance: null, formatted: null };
2503
+ }
2504
+ })
2505
+ );
2506
+ if (disposed || own !== generation) return;
2507
+ tokenBalances.value = results;
2508
+ } catch (cause) {
2509
+ if (disposed || own !== generation) return;
2510
+ tokenBalances.value = [];
2511
+ error.value = cause instanceof Error ? cause : new Error("Failed to fetch token balances");
2512
+ } finally {
2513
+ if (!disposed && own === generation) isFetching.value = false;
2514
+ }
2515
+ };
2516
+ const stopTimer = () => {
2517
+ if (timer) clearInterval(timer);
2518
+ timer = null;
2519
+ };
2520
+ watch13(
2521
+ [
2522
+ () => toValue27(account),
2523
+ () => toValue27(client),
2524
+ () => tokensKey(toValue27(tokens) ?? []),
2525
+ () => toValue27(options.refreshInterval) ?? 0
2526
+ ],
2527
+ ([, , , interval]) => {
2528
+ stopTimer();
2529
+ void refetch();
2530
+ if (interval > 0) timer = setInterval(() => void refetch(), interval);
2531
+ },
2532
+ { immediate: true }
2533
+ );
2534
+ onScopeDispose30(() => {
2535
+ disposed = true;
2536
+ generation++;
2537
+ stopTimer();
2538
+ });
2539
+ return {
2540
+ tokenBalances,
2541
+ isFetching,
2542
+ error,
2543
+ refetch,
2544
+ getTokenBalance: (tokenAddress) => tokenBalances.value.find(
2545
+ (t) => t.address.toLowerCase() === tokenAddress.toLowerCase()
2546
+ )
2547
+ };
2548
+ }
2549
+
2550
+ // src/useDelegation.ts
2551
+ import { bareEvmAddress as bareEvmAddress7 } from "@naculus/connect-appkit-core";
2552
+ import {
2553
+ readDelegation,
2554
+ UNKNOWN_DELEGATION
2555
+ } from "@naculus/connect-core";
2556
+ import { computed as computed20, onScopeDispose as onScopeDispose31, shallowRef as shallowRef32, toValue as toValue28, watch as watch14 } from "vue";
2557
+ function useDelegation(account, client, chainId) {
2558
+ const status = shallowRef32(UNKNOWN_DELEGATION);
2559
+ const isFetching = shallowRef32(false);
2560
+ const error = shallowRef32(null);
2561
+ let generation = 0;
2562
+ let disposed = false;
2563
+ const refetch = async () => {
2564
+ const mine = ++generation;
2565
+ const reader = toValue28(client);
2566
+ const address = bareEvmAddress7(toValue28(account));
2567
+ status.value = UNKNOWN_DELEGATION;
2568
+ error.value = null;
2569
+ if (!reader || !address) {
2570
+ isFetching.value = false;
2571
+ return;
2572
+ }
2573
+ isFetching.value = true;
2574
+ try {
2575
+ const code = await reader.getCode({ address });
2576
+ if (!disposed && mine === generation) {
2577
+ status.value = readDelegation(code ?? "0x");
2578
+ }
2579
+ } catch (cause) {
2580
+ if (!disposed && mine === generation) {
2581
+ status.value = UNKNOWN_DELEGATION;
2582
+ error.value = cause instanceof Error ? cause : new Error("Code read failed");
2583
+ }
2584
+ } finally {
2585
+ if (!disposed && mine === generation) isFetching.value = false;
2586
+ }
2587
+ };
2588
+ watch14(
2589
+ [() => toValue28(account), () => toValue28(client), () => toValue28(chainId)],
2590
+ () => {
2591
+ void refetch();
2592
+ },
2593
+ { immediate: true, flush: "sync" }
2594
+ );
2595
+ onScopeDispose31(() => {
2596
+ disposed = true;
2597
+ generation++;
2598
+ });
2599
+ return {
2600
+ delegated: computed20(() => status.value.delegated),
2601
+ delegate: computed20(() => status.value.delegate),
2602
+ isFetching,
2603
+ error,
2604
+ refetch
2605
+ };
2606
+ }
2607
+
2608
+ // src/name-lookup.ts
2609
+ import { getResolver } from "@naculus/connect-appkit-core";
2610
+ import { computed as computed21, onScopeDispose as onScopeDispose32, shallowRef as shallowRef33, toValue as toValue29, watch as watch15 } from "vue";
2611
+ function useNameLookup(options) {
2612
+ const data = shallowRef33(null);
2613
+ const loading = shallowRef33(false);
2614
+ const error = shallowRef33(null);
2615
+ let generation = 0;
2616
+ let disposed = false;
2617
+ const run = () => {
2618
+ const input = toValue29(options.input).trim();
2619
+ const skip = toValue29(options.skip) ?? false;
2620
+ const scope = toValue29(options.scope);
2621
+ const config = toValue29(options.resolverConfig);
2622
+ const mine = ++generation;
2623
+ if (!input || skip) {
2624
+ data.value = null;
2625
+ loading.value = false;
2626
+ error.value = null;
2627
+ return;
2628
+ }
2629
+ data.value = null;
2630
+ loading.value = true;
2631
+ error.value = null;
2632
+ Promise.resolve().then(() => options.query(getResolver(config), input, scope)).then((result) => {
2633
+ if (disposed || mine !== generation) return;
2634
+ data.value = result;
2635
+ loading.value = false;
2636
+ }).catch((cause) => {
2637
+ if (disposed || mine !== generation) return;
2638
+ data.value = null;
2639
+ error.value = cause instanceof Error ? cause : new Error(String(cause));
2640
+ loading.value = false;
2641
+ });
2642
+ };
2643
+ watch15(
2644
+ () => [
2645
+ toValue29(options.input),
2646
+ toValue29(options.skip),
2647
+ toValue29(options.scope),
2648
+ toValue29(options.resolverConfig)
2649
+ ],
2650
+ run,
2651
+ { immediate: true, flush: "sync", deep: true }
2652
+ );
2653
+ onScopeDispose32(() => {
2654
+ disposed = true;
2655
+ generation++;
2656
+ });
2657
+ return {
2658
+ data,
2659
+ isLoading: computed21(() => loading.value),
2660
+ error,
2661
+ refetch: run
2662
+ };
2663
+ }
2664
+
2665
+ // src/useResolveName.ts
2666
+ function useResolveName(name, options) {
2667
+ return useNameLookup({
2668
+ input: name,
2669
+ skip: options?.skip,
2670
+ resolverConfig: options?.resolverConfig,
2671
+ query: (resolver, input) => resolver.resolveName(input)
2672
+ });
2673
+ }
2674
+
2675
+ // src/useLookupAddress.ts
2676
+ function useLookupAddress(address, options) {
2677
+ return useNameLookup({
2678
+ input: address,
2679
+ scope: options?.chainId,
2680
+ skip: options?.skip,
2681
+ resolverConfig: options?.resolverConfig,
2682
+ query: (resolver, input, scope) => resolver.lookupAddress(input, scope)
2683
+ });
2684
+ }
2685
+
2686
+ // src/useSolanaAccount.ts
2687
+ import { computed as computed22, toValue as toValue30 } from "vue";
2688
+ function useSolanaAccount(accounts, connected) {
2689
+ const isConnected = computed22(() => toValue30(connected));
2690
+ const caip10 = computed22(
2691
+ () => isConnected.value ? (toValue30(accounts) ?? []).find(
2692
+ (account) => account.startsWith("solana:")
2693
+ ) ?? null : null
2694
+ );
2695
+ const parts = computed22(() => caip10.value?.split(":") ?? []);
2696
+ return {
2697
+ address: computed22(
2698
+ () => parts.value.length >= 3 ? parts.value.at(-1) ?? null : null
2699
+ ),
2700
+ caip10,
2701
+ chainId: computed22(
2702
+ () => parts.value.length >= 3 ? parts.value.slice(0, -1).join(":") : null
2703
+ ),
2704
+ isConnected
2705
+ };
2706
+ }
2707
+
212
2708
  // src/useChain.ts
213
2709
  import {
214
2710
  chainNamespace,
215
- chainNumber,
2711
+ chainNumber as chainNumber2,
216
2712
  chainsForNamespace,
217
2713
  describeChain,
218
2714
  resolveChain
219
2715
  } from "@naculus/connect-appkit-core";
220
- import { computed as computed2, toValue as toValue2 } from "vue";
2716
+ import { computed as computed23, toValue as toValue31 } from "vue";
221
2717
  function useChain(chains, chainId) {
222
- const list = computed2(() => toValue2(chains) ?? []);
223
- const id = computed2(() => toValue2(chainId) ?? null);
224
- const currentChain = computed2(() => resolveChain(list.value, id.value));
2718
+ const list = computed23(() => toValue31(chains) ?? []);
2719
+ const id = computed23(() => toValue31(chainId) ?? null);
2720
+ const currentChain = computed23(() => resolveChain(list.value, id.value));
225
2721
  return {
226
2722
  currentChain,
227
- chainInfo: computed2(() => describeChain(list.value, id.value)),
228
- availableChains: computed2(() => chainsForNamespace(list.value, id.value)),
229
- currentChainNumber: computed2(
230
- () => currentChain.value ? chainNumber(currentChain.value) : null
2723
+ chainInfo: computed23(() => describeChain(list.value, id.value)),
2724
+ availableChains: computed23(() => chainsForNamespace(list.value, id.value)),
2725
+ currentChainNumber: computed23(
2726
+ () => currentChain.value ? chainNumber2(currentChain.value) : null
231
2727
  ),
232
- namespace: computed2(
2728
+ namespace: computed23(
233
2729
  () => currentChain.value ? chainNamespace(currentChain.value) : null
234
2730
  )
235
2731
  };
236
2732
  }
237
2733
 
238
2734
  // src/usePassphraseGate.ts
239
- import { onScopeDispose, readonly, shallowRef } from "vue";
2735
+ import { onScopeDispose as onScopeDispose33, readonly, shallowRef as shallowRef34 } from "vue";
240
2736
  function usePassphraseGate(gate) {
241
- const request = shallowRef(gate.getSnapshot());
2737
+ const request = shallowRef34(gate.getSnapshot());
242
2738
  const unsubscribe = gate.subscribe(() => {
243
2739
  request.value = gate.getSnapshot();
244
2740
  });
245
- onScopeDispose(unsubscribe);
2741
+ onScopeDispose33(unsubscribe);
246
2742
  return {
247
2743
  request: readonly(request),
248
2744
  submit: (passphrase) => gate.submit(passphrase),
@@ -255,16 +2751,16 @@ function usePassphraseGate(gate) {
255
2751
  import {
256
2752
  getSolanaBalance
257
2753
  } from "@naculus/connect-core";
258
- import { onScopeDispose as onScopeDispose2, ref, shallowRef as shallowRef2, toValue as toValue3, watchEffect } from "vue";
2754
+ import { onScopeDispose as onScopeDispose34, ref, shallowRef as shallowRef35, toValue as toValue32, watchEffect } from "vue";
259
2755
  function useSolanaBalance(address, rpcUrl) {
260
- const balance = shallowRef2(null);
2756
+ const balance = shallowRef35(null);
261
2757
  const isFetching = ref(false);
262
- const error = shallowRef2(null);
2758
+ const error = shallowRef35(null);
263
2759
  let generation = 0;
264
2760
  let disposed = false;
265
2761
  const refetch = async () => {
266
- const addr = toValue3(address);
267
- const url = toValue3(rpcUrl);
2762
+ const addr = toValue32(address);
2763
+ const url = toValue32(rpcUrl);
268
2764
  if (!addr || !url) {
269
2765
  balance.value = null;
270
2766
  return;
@@ -285,34 +2781,224 @@ function useSolanaBalance(address, rpcUrl) {
285
2781
  }
286
2782
  };
287
2783
  watchEffect(() => {
288
- toValue3(address);
289
- toValue3(rpcUrl);
2784
+ toValue32(address);
2785
+ toValue32(rpcUrl);
290
2786
  void refetch();
291
2787
  });
292
- onScopeDispose2(() => {
2788
+ onScopeDispose34(() => {
293
2789
  disposed = true;
294
2790
  });
295
2791
  return { balance, isFetching, error, refetch };
296
2792
  }
297
2793
 
2794
+ // src/useLastTx.ts
2795
+ import { shallowRef as shallowRef36, toValue as toValue33, watch as watch16 } from "vue";
2796
+ function useLastTx(monitor) {
2797
+ const lastTx = shallowRef36(null);
2798
+ const lastConfirmedTx = shallowRef36(null);
2799
+ const lastFailedTx = shallowRef36(null);
2800
+ watch16(
2801
+ () => toValue33(monitor),
2802
+ (activeMonitor, _previous, onCleanup) => {
2803
+ if (!activeMonitor) return;
2804
+ const recordLatest = (entry) => {
2805
+ if (!lastTx.value || entry.createdAt >= lastTx.value.createdAt) {
2806
+ lastTx.value = entry;
2807
+ }
2808
+ };
2809
+ const onConfirmed = (entry) => {
2810
+ lastConfirmedTx.value = entry;
2811
+ recordLatest(entry);
2812
+ };
2813
+ const onFailed = (entry) => {
2814
+ lastFailedTx.value = entry;
2815
+ recordLatest(entry);
2816
+ };
2817
+ activeMonitor.on("confirmed", onConfirmed);
2818
+ activeMonitor.on("failed", onFailed);
2819
+ onCleanup(() => {
2820
+ activeMonitor.off("confirmed", onConfirmed);
2821
+ activeMonitor.off("failed", onFailed);
2822
+ });
2823
+ },
2824
+ { immediate: true }
2825
+ );
2826
+ return {
2827
+ lastTx,
2828
+ lastConfirmedTx,
2829
+ lastFailedTx,
2830
+ clear: () => {
2831
+ lastTx.value = null;
2832
+ lastConfirmedTx.value = null;
2833
+ lastFailedTx.value = null;
2834
+ }
2835
+ };
2836
+ }
2837
+
2838
+ // src/useTxHistory.ts
2839
+ import { computed as computed24, shallowRef as shallowRef37, toValue as toValue34, watch as watch17 } from "vue";
2840
+ function useTxHistory(address, chainId, monitor) {
2841
+ const entries = shallowRef37([]);
2842
+ const isLoading = shallowRef37(false);
2843
+ const error = shallowRef37(null);
2844
+ let generation = 0;
2845
+ const refresh = async () => {
2846
+ const mine = ++generation;
2847
+ const activeMonitor = toValue34(monitor);
2848
+ if (!activeMonitor) {
2849
+ entries.value = [];
2850
+ isLoading.value = false;
2851
+ error.value = null;
2852
+ return;
2853
+ }
2854
+ isLoading.value = true;
2855
+ error.value = null;
2856
+ try {
2857
+ const result = await activeMonitor.getTxHistory(
2858
+ toValue34(address) ?? void 0,
2859
+ toValue34(chainId) ?? void 0
2860
+ );
2861
+ if (mine === generation) entries.value = result;
2862
+ } catch (err) {
2863
+ if (mine !== generation) return;
2864
+ error.value = err instanceof Error ? err : new Error("Failed to load transaction history");
2865
+ } finally {
2866
+ if (mine === generation) isLoading.value = false;
2867
+ }
2868
+ };
2869
+ watch17(
2870
+ [() => toValue34(monitor), () => toValue34(address), () => toValue34(chainId)],
2871
+ ([activeMonitor], _previous, onCleanup) => {
2872
+ if (!activeMonitor) {
2873
+ void refresh();
2874
+ return;
2875
+ }
2876
+ const onStatusChange = () => {
2877
+ void refresh();
2878
+ };
2879
+ activeMonitor.on("statusChange", onStatusChange);
2880
+ onCleanup(() => activeMonitor.off("statusChange", onStatusChange));
2881
+ void refresh();
2882
+ },
2883
+ { immediate: true }
2884
+ );
2885
+ return {
2886
+ entries,
2887
+ isLoading,
2888
+ error,
2889
+ refresh,
2890
+ summary: computed24(() => ({
2891
+ pending: entries.value.filter((item) => item.status === "pending").length,
2892
+ confirmed: entries.value.filter((item) => item.status === "confirmed").length,
2893
+ failed: entries.value.filter((item) => item.status === "failed").length
2894
+ }))
2895
+ };
2896
+ }
2897
+
2898
+ // src/useTxMonitor.ts
2899
+ import { computed as computed25, shallowRef as shallowRef38, toValue as toValue35, watch as watch18 } from "vue";
2900
+ function useTxMonitor(hash, chainId, monitor) {
2901
+ const entry = shallowRef38(null);
2902
+ const isLoading = shallowRef38(false);
2903
+ const isWatching = shallowRef38(false);
2904
+ const error = shallowRef38(null);
2905
+ let generation = 0;
2906
+ const refresh = async () => {
2907
+ const activeMonitor = toValue35(monitor);
2908
+ const activeHash = toValue35(hash);
2909
+ const activeChainId = toValue35(chainId);
2910
+ if (!activeMonitor || !activeHash) return;
2911
+ isLoading.value = true;
2912
+ error.value = null;
2913
+ try {
2914
+ await activeMonitor.refreshTx(activeHash, activeChainId ?? void 0);
2915
+ const current = activeMonitor.getTxStatus(
2916
+ activeHash,
2917
+ activeChainId ?? void 0
2918
+ );
2919
+ if (current) entry.value = current;
2920
+ } catch (err) {
2921
+ error.value = err instanceof Error ? err : new Error("Failed to refresh transaction");
2922
+ } finally {
2923
+ isLoading.value = false;
2924
+ }
2925
+ };
2926
+ const stopWatching = () => {
2927
+ const activeMonitor = toValue35(monitor);
2928
+ const activeHash = toValue35(hash);
2929
+ const activeChainId = toValue35(chainId);
2930
+ if (!activeMonitor || !activeHash) return;
2931
+ activeMonitor.stopWatching(activeHash, activeChainId ?? void 0);
2932
+ isWatching.value = false;
2933
+ };
2934
+ watch18(
2935
+ [() => toValue35(monitor), () => toValue35(hash), () => toValue35(chainId)],
2936
+ ([activeMonitor, activeHash, activeChainId], _previous, onCleanup) => {
2937
+ const mine = ++generation;
2938
+ if (!activeMonitor || !activeHash || !activeChainId) {
2939
+ entry.value = null;
2940
+ isLoading.value = false;
2941
+ isWatching.value = false;
2942
+ error.value = null;
2943
+ return;
2944
+ }
2945
+ let cancelled = false;
2946
+ const onStatusChange = (updated) => {
2947
+ if (!cancelled && updated.hash === activeHash && updated.chainId === activeChainId) {
2948
+ entry.value = { ...updated };
2949
+ }
2950
+ };
2951
+ activeMonitor.on("statusChange", onStatusChange);
2952
+ onCleanup(() => {
2953
+ cancelled = true;
2954
+ activeMonitor.off("statusChange", onStatusChange);
2955
+ });
2956
+ isWatching.value = true;
2957
+ isLoading.value = true;
2958
+ error.value = null;
2959
+ const current = activeMonitor.getTxStatus(activeHash, activeChainId);
2960
+ if (current) entry.value = current;
2961
+ activeMonitor.watchTx(activeHash, activeChainId, {}).then((initial) => {
2962
+ if (cancelled || mine !== generation) return;
2963
+ entry.value = initial;
2964
+ isLoading.value = false;
2965
+ }).catch((err) => {
2966
+ if (cancelled || mine !== generation) return;
2967
+ error.value = err instanceof Error ? err : new Error("Failed to watch transaction");
2968
+ isLoading.value = false;
2969
+ });
2970
+ },
2971
+ { immediate: true }
2972
+ );
2973
+ return {
2974
+ entry,
2975
+ status: computed25(() => entry.value?.status ?? "idle"),
2976
+ isLoading,
2977
+ isWatching,
2978
+ error,
2979
+ refresh,
2980
+ stopWatching
2981
+ };
2982
+ }
2983
+
298
2984
  // src/useCapabilities.ts
299
2985
  import {
300
2986
  atomicSupportFor,
301
2987
  normalizeCapabilities,
302
2988
  selectChainCapabilities
303
2989
  } from "@naculus/connect-appkit-core";
304
- import { computed as computed3, shallowRef as shallowRef3, toValue as toValue4, watchEffect as watchEffect2 } from "vue";
2990
+ import { computed as computed26, shallowRef as shallowRef39, toValue as toValue36, watchEffect as watchEffect2 } from "vue";
305
2991
  function useCapabilities(client, session, chainId) {
306
- const capabilities = shallowRef3(
2992
+ const capabilities = shallowRef39(
307
2993
  null
308
2994
  );
309
- const isFetching = shallowRef3(false);
310
- const error = shallowRef3(null);
2995
+ const isFetching = shallowRef39(false);
2996
+ const error = shallowRef39(null);
311
2997
  let generation = 0;
312
2998
  const refetch = async () => {
313
2999
  const mine = ++generation;
314
- const activeClient = toValue4(client);
315
- const activeSession = toValue4(session);
3000
+ const activeClient = toValue36(client);
3001
+ const activeSession = toValue36(session);
316
3002
  if (!activeClient?.getCapabilities || !activeSession) {
317
3003
  capabilities.value = null;
318
3004
  isFetching.value = false;
@@ -334,17 +3020,17 @@ function useCapabilities(client, session, chainId) {
334
3020
  }
335
3021
  };
336
3022
  watchEffect2(() => {
337
- void toValue4(client);
338
- void toValue4(session);
3023
+ void toValue36(client);
3024
+ void toValue36(session);
339
3025
  void refetch();
340
3026
  });
341
3027
  return {
342
3028
  capabilities,
343
- current: computed3(
344
- () => selectChainCapabilities(capabilities.value, toValue4(chainId))
3029
+ current: computed26(
3030
+ () => selectChainCapabilities(capabilities.value, toValue36(chainId))
345
3031
  ),
346
- atomic: computed3(
347
- () => atomicSupportFor(capabilities.value, toValue4(chainId))
3032
+ atomic: computed26(
3033
+ () => atomicSupportFor(capabilities.value, toValue36(chainId))
348
3034
  ),
349
3035
  isFetching,
350
3036
  error,
@@ -356,17 +3042,17 @@ function useCapabilities(client, session, chainId) {
356
3042
  import {
357
3043
  readSolanaRoles
358
3044
  } from "@naculus/connect-appkit-core";
359
- import { computed as computed4, toValue as toValue5 } from "vue";
3045
+ import { computed as computed27, toValue as toValue37 } from "vue";
360
3046
  function useSolanaRoles(connector, session) {
361
- const state = computed4(
362
- () => readSolanaRoles(toValue5(connector), toValue5(session))
3047
+ const state = computed27(
3048
+ () => readSolanaRoles(toValue37(connector), toValue37(session))
363
3049
  );
364
3050
  return {
365
- roles: computed4(() => state.value.roles),
366
- absence: computed4(() => state.value.absence),
367
- identity: computed4(() => state.value.roles?.identity ?? null),
368
- signer: computed4(() => state.value.roles?.signer ?? null),
369
- payer: computed4(() => state.value.roles?.payer ?? null)
3051
+ roles: computed27(() => state.value.roles),
3052
+ absence: computed27(() => state.value.absence),
3053
+ identity: computed27(() => state.value.roles?.identity ?? null),
3054
+ signer: computed27(() => state.value.roles?.signer ?? null),
3055
+ payer: computed27(() => state.value.roles?.payer ?? null)
370
3056
  };
371
3057
  }
372
3058
  export {
@@ -398,11 +3084,56 @@ export {
398
3084
  AppkitTabs,
399
3085
  AppkitToggleGroup,
400
3086
  AppkitTooltip,
3087
+ useAccount,
401
3088
  useAccounts,
3089
+ useBalance,
402
3090
  useCapabilities,
403
3091
  useChain,
3092
+ useCompareCosts,
3093
+ useConnect,
3094
+ useCreateSessionKey,
3095
+ useDelegation,
3096
+ useDelegationPolicy,
3097
+ useDisconnect,
3098
+ useERC20Approve,
3099
+ useERC20Transfer,
3100
+ useERC20TransferSimulation,
3101
+ useEmbeddedWallet,
3102
+ useExecuteCalls,
3103
+ useExecuteRoute,
3104
+ useLastTx,
3105
+ useLookupAddress,
3106
+ useNotification,
404
3107
  usePassphraseGate,
3108
+ useResolveName,
3109
+ useRevokeSession,
3110
+ useRouteQuote,
3111
+ useSIWxLogin,
3112
+ useSIWxSession,
3113
+ useSendCalls,
3114
+ useSendTransaction,
3115
+ useSendUserOperation,
3116
+ useSendWithSession,
3117
+ useSession,
3118
+ useSessionKeys,
3119
+ useSignInWithEthereum,
3120
+ useSignInWithX,
3121
+ useSignMessage,
3122
+ useSimulateTransfer,
3123
+ useSiwxAuthSession,
3124
+ useSmartAccount,
3125
+ useSolanaAccount,
405
3126
  useSolanaBalance,
406
- useSolanaRoles
3127
+ useSolanaRoles,
3128
+ useSolanaTransaction,
3129
+ useSwitchChain,
3130
+ useTokenBalance,
3131
+ useTokenList,
3132
+ useTokenSearch,
3133
+ useTransactionSimulation,
3134
+ useTxHistory,
3135
+ useTxMonitor,
3136
+ useUserOpStatus,
3137
+ useValidateDestination
407
3138
  };
408
3139
  //# sourceMappingURL=index.js.map