@naculus/connect-appkit-vue 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -80,6 +80,7 @@ __export(index_exports, {
80
80
  useLookupAddress: () => useLookupAddress,
81
81
  useNotification: () => useNotification,
82
82
  usePassphraseGate: () => usePassphraseGate,
83
+ usePaymentFetch: () => usePaymentFetch,
83
84
  useResolveName: () => useResolveName,
84
85
  useRevokeSession: () => useRevokeSession,
85
86
  useRouteQuote: () => useRouteQuote,
@@ -393,110 +394,159 @@ function useNotification(options = {}) {
393
394
  // src/useSimulateTransfer.ts
394
395
  var import_connect_appkit_core2 = require("@naculus/connect-appkit-core");
395
396
  var import_connect_core3 = require("@naculus/connect-core");
397
+ var import_vue4 = require("vue");
398
+
399
+ // src/internal/action-guard.ts
396
400
  var import_vue3 = require("vue");
397
- function useSimulateTransfer(options = {}) {
398
- const result = (0, import_vue3.shallowRef)(null);
399
- const loading = (0, import_vue3.shallowRef)(false);
401
+ function useActionGuard() {
402
+ const busy = (0, import_vue3.shallowRef)(false);
400
403
  const error = (0, import_vue3.shallowRef)(null);
401
- let manager;
404
+ let active = 0;
402
405
  let generation = 0;
403
406
  let disposed = false;
404
- const simulate = async (tokenAddress, from, to, amount, callOptions) => {
407
+ const run = async (action, fallbackMessage, normalizeError, options = {}) => {
405
408
  const own = ++generation;
406
- loading.value = true;
407
- error.value = null;
409
+ const commit = (write) => {
410
+ if (!disposed && own === generation) write();
411
+ };
412
+ active++;
413
+ busy.value = true;
414
+ if (!options.keepError) error.value = null;
408
415
  try {
409
- const fallbackRpcUrl = (0, import_vue3.unref)(options.rpcUrl);
410
- const endpoint = (0, import_connect_appkit_core2.resolveSimulationEndpoint)(
411
- callOptions?.chainId,
412
- (0, import_vue3.unref)(options.chainId),
413
- callOptions?.rpcUrl,
414
- fallbackRpcUrl
415
- );
416
- manager ??= new import_connect_core3.SimulationManager({
417
- enabled: true,
418
- rpcUrl: fallbackRpcUrl,
419
- autoSimulate: false
420
- });
421
- const value = await manager.simulateERC20Transfer(
422
- tokenAddress,
423
- from,
424
- to,
425
- amount,
426
- endpoint.chainId,
427
- callOptions?.decimals,
428
- endpoint.rpcUrl
429
- );
430
- if (!disposed && own === generation) result.value = value;
431
- return value;
416
+ return await action(commit);
432
417
  } catch (cause) {
433
- const normalized = cause instanceof Error ? cause : new Error(String(cause));
418
+ const normalized = normalizeError ? normalizeError(cause) : cause instanceof Error ? cause : new Error(fallbackMessage);
434
419
  if (!disposed && own === generation) error.value = normalized;
435
420
  throw normalized;
436
421
  } finally {
437
- if (!disposed && own === generation) loading.value = false;
422
+ try {
423
+ if (options.onSettled) commit(options.onSettled);
424
+ } finally {
425
+ active--;
426
+ if (!disposed) busy.value = active > 0;
427
+ }
438
428
  }
439
429
  };
440
- const reset = () => {
430
+ const invalidate = () => {
441
431
  generation++;
442
- result.value = null;
432
+ };
433
+ const reset = () => {
434
+ invalidate();
435
+ error.value = null;
436
+ };
437
+ const clearError = () => {
443
438
  error.value = null;
444
- loading.value = false;
445
439
  };
446
- (0, import_vue3.onScopeDispose)(() => {
440
+ const dispose = () => {
447
441
  disposed = true;
448
442
  generation++;
449
- });
450
- return { result, loading, error, simulate, reset };
443
+ };
444
+ (0, import_vue3.onScopeDispose)(dispose);
445
+ return { busy, error, run, clearError, reset, invalidate, dispose };
446
+ }
447
+
448
+ // src/useSimulateTransfer.ts
449
+ function useSimulateTransfer(options = {}) {
450
+ const guard = useActionGuard();
451
+ const result = (0, import_vue4.shallowRef)(null);
452
+ const loading = (0, import_vue4.shallowRef)(false);
453
+ let manager;
454
+ const simulate = async (tokenAddress, from, to, amount, callOptions) => {
455
+ loading.value = true;
456
+ return await guard.run(
457
+ async (commit) => {
458
+ const fallbackRpcUrl = (0, import_vue4.unref)(options.rpcUrl);
459
+ const endpoint = (0, import_connect_appkit_core2.resolveSimulationEndpoint)(
460
+ callOptions?.chainId,
461
+ (0, import_vue4.unref)(options.chainId),
462
+ callOptions?.rpcUrl,
463
+ fallbackRpcUrl
464
+ );
465
+ manager ??= new import_connect_core3.SimulationManager({
466
+ enabled: true,
467
+ rpcUrl: fallbackRpcUrl,
468
+ autoSimulate: false
469
+ });
470
+ const value = await manager.simulateERC20Transfer(
471
+ tokenAddress,
472
+ from,
473
+ to,
474
+ amount,
475
+ endpoint.chainId,
476
+ callOptions?.decimals,
477
+ endpoint.rpcUrl
478
+ );
479
+ commit(() => {
480
+ result.value = value;
481
+ });
482
+ return value;
483
+ },
484
+ "Simulation failed",
485
+ (cause) => cause instanceof Error ? cause : new Error(String(cause)),
486
+ {
487
+ onSettled: () => {
488
+ loading.value = false;
489
+ }
490
+ }
491
+ );
492
+ };
493
+ const reset = () => {
494
+ guard.reset();
495
+ result.value = null;
496
+ loading.value = false;
497
+ };
498
+ return { result, loading, error: guard.error, simulate, reset };
451
499
  }
452
500
 
453
501
  // src/useTransactionSimulation.ts
454
502
  var import_connect_appkit_core3 = require("@naculus/connect-appkit-core");
455
- var import_vue4 = require("vue");
503
+ var import_vue5 = require("vue");
456
504
  function useTransactionSimulation(tx, options = {}) {
457
- const result = (0, import_vue4.shallowRef)(void 0);
458
- const isSimulating = (0, import_vue4.shallowRef)(false);
459
- const error = (0, import_vue4.shallowRef)(null);
505
+ const guard = useActionGuard();
506
+ const result = (0, import_vue5.shallowRef)(void 0);
507
+ const isSimulating = (0, import_vue5.shallowRef)(false);
460
508
  let timer;
461
- let generation = 0;
462
- let disposed = false;
463
509
  const simulate = async () => {
464
- const own = ++generation;
465
- const transaction = (0, import_vue4.toValue)(tx);
466
- if (transaction) {
467
- isSimulating.value = true;
468
- error.value = null;
469
- }
470
- try {
471
- const value = await (0, import_connect_appkit_core3.simulateTransactionPreview)(transaction, {
472
- chainId: (0, import_vue4.unref)(options.chainId),
473
- currentChain: (0, import_vue4.unref)(options.currentChain),
474
- publicClient: (0, import_vue4.unref)(options.publicClient),
475
- evmAccount: (0, import_vue4.unref)(options.evmAccount)
476
- });
477
- if (!disposed && own === generation) result.value = value;
478
- return value;
479
- } catch (cause) {
480
- const normalized = cause instanceof Error ? cause : new Error("Simulation failed");
481
- if (!disposed && own === generation) error.value = normalized;
482
- throw normalized;
483
- } finally {
484
- if (transaction && !disposed && own === generation)
485
- isSimulating.value = false;
486
- }
510
+ const transaction = (0, import_vue5.toValue)(tx);
511
+ if (transaction) isSimulating.value = true;
512
+ return await guard.run(
513
+ async (commit) => {
514
+ const value = await (0, import_connect_appkit_core3.simulateTransactionPreview)(transaction, {
515
+ chainId: (0, import_vue5.unref)(options.chainId),
516
+ currentChain: (0, import_vue5.unref)(options.currentChain),
517
+ publicClient: (0, import_vue5.unref)(options.publicClient),
518
+ evmAccount: (0, import_vue5.unref)(options.evmAccount)
519
+ });
520
+ commit(() => {
521
+ result.value = value;
522
+ });
523
+ return value;
524
+ },
525
+ "Simulation failed",
526
+ void 0,
527
+ {
528
+ keepError: !transaction,
529
+ onSettled: transaction ? () => {
530
+ isSimulating.value = false;
531
+ } : void 0
532
+ }
533
+ );
487
534
  };
488
- (0, import_vue4.watch)(
535
+ (0, import_vue5.watch)(
489
536
  [
490
- () => (0, import_vue4.toValue)(tx),
491
- () => (0, import_vue4.unref)(options.chainId),
492
- () => (0, import_vue4.unref)(options.currentChain),
493
- () => (0, import_vue4.unref)(options.publicClient),
494
- () => (0, import_vue4.unref)(options.evmAccount)
537
+ () => (0, import_vue5.toValue)(tx),
538
+ () => (0, import_vue5.unref)(options.chainId),
539
+ () => (0, import_vue5.unref)(options.currentChain),
540
+ () => (0, import_vue5.unref)(options.publicClient),
541
+ () => (0, import_vue5.unref)(options.evmAccount)
495
542
  ],
496
543
  ([transaction]) => {
497
- generation++;
544
+ guard.invalidate();
498
545
  if (timer) clearTimeout(timer);
499
- if (!transaction) return;
546
+ if (!transaction) {
547
+ isSimulating.value = false;
548
+ return;
549
+ }
500
550
  timer = setTimeout(() => {
501
551
  timer = void 0;
502
552
  void simulate().catch(() => {
@@ -506,23 +556,20 @@ function useTransactionSimulation(tx, options = {}) {
506
556
  { immediate: true }
507
557
  );
508
558
  const reset = () => {
509
- generation++;
559
+ guard.reset();
510
560
  result.value = void 0;
511
- error.value = null;
512
561
  isSimulating.value = false;
513
562
  };
514
- (0, import_vue4.onScopeDispose)(() => {
515
- disposed = true;
516
- generation++;
563
+ (0, import_vue5.onScopeDispose)(() => {
517
564
  if (timer) clearTimeout(timer);
518
565
  });
519
- return { result, isSimulating, error, simulate, reset };
566
+ return { result, isSimulating, error: guard.error, simulate, reset };
520
567
  }
521
568
 
522
569
  // src/useERC20Transfer.ts
523
570
  var import_connect_appkit_core5 = require("@naculus/connect-appkit-core");
524
571
  var import_connect_core5 = require("@naculus/connect-core");
525
- var import_vue5 = require("vue");
572
+ var import_vue6 = require("vue");
526
573
 
527
574
  // src/erc20.ts
528
575
  var import_connect_appkit_core4 = require("@naculus/connect-appkit-core");
@@ -542,22 +589,22 @@ function assertErc20Context(token, chainId, account, connected) {
542
589
 
543
590
  // src/useERC20Transfer.ts
544
591
  function useERC20Transfer(options) {
545
- const initialToken = (0, import_vue5.toValue)(options.token);
592
+ const initialToken = (0, import_vue6.toValue)(options.token);
546
593
  const decimals = (0, import_connect_appkit_core5.createDecimalsCache)(initialToken, initialToken.decimals);
547
- const isSending = (0, import_vue5.shallowRef)(false);
548
- const error = (0, import_vue5.shallowRef)(null);
594
+ const isSending = (0, import_vue6.shallowRef)(false);
595
+ const error = (0, import_vue6.shallowRef)(null);
549
596
  let generation = 0;
550
597
  let disposed = false;
551
- (0, import_vue5.watch)(
598
+ (0, import_vue6.watch)(
552
599
  [
553
- () => (0, import_vue5.toValue)(options.token).address,
554
- () => (0, import_vue5.toValue)(options.token).chainId,
555
- () => (0, import_vue5.toValue)(options.token).decimals,
556
- () => (0, import_vue5.toValue)(options.account),
557
- () => (0, import_vue5.toValue)(options.chainId),
558
- () => (0, import_vue5.toValue)(options.connected),
559
- () => (0, import_vue5.toValue)(options.publicClient),
560
- () => (0, import_vue5.unref)(options.sendTransaction)
600
+ () => (0, import_vue6.toValue)(options.token).address,
601
+ () => (0, import_vue6.toValue)(options.token).chainId,
602
+ () => (0, import_vue6.toValue)(options.token).decimals,
603
+ () => (0, import_vue6.toValue)(options.account),
604
+ () => (0, import_vue6.toValue)(options.chainId),
605
+ () => (0, import_vue6.toValue)(options.connected),
606
+ () => (0, import_vue6.toValue)(options.publicClient),
607
+ () => (0, import_vue6.unref)(options.sendTransaction)
561
608
  ],
562
609
  () => {
563
610
  generation++;
@@ -568,17 +615,17 @@ function useERC20Transfer(options) {
568
615
  );
569
616
  const sendTransfer = async (to, amount) => {
570
617
  const own = ++generation;
571
- const token = (0, import_vue5.toValue)(options.token);
572
- const reader = (0, import_vue5.toValue)(options.publicClient);
618
+ const token = (0, import_vue6.toValue)(options.token);
619
+ const reader = (0, import_vue6.toValue)(options.publicClient);
573
620
  const stillCurrent = () => !disposed && own === generation;
574
621
  error.value = null;
575
622
  isSending.value = true;
576
623
  try {
577
624
  assertErc20Context(
578
625
  token,
579
- (0, import_vue5.toValue)(options.chainId),
580
- (0, import_vue5.toValue)(options.account),
581
- (0, import_vue5.toValue)(options.connected)
626
+ (0, import_vue6.toValue)(options.chainId),
627
+ (0, import_vue6.toValue)(options.account),
628
+ (0, import_vue6.toValue)(options.connected)
582
629
  );
583
630
  if (!reader) {
584
631
  throw new import_connect_core5.WalletError(
@@ -604,7 +651,7 @@ function useERC20Transfer(options) {
604
651
  (0, import_connect_appkit_core5.writeDecimals)(decimals, token, precision);
605
652
  }
606
653
  const data = (0, import_connect_appkit_core5.encodeErc20Transfer)(to, (0, import_connect_core5.parseUnits)(amount, precision));
607
- return await (0, import_vue5.unref)(options.sendTransaction)({
654
+ return await (0, import_vue6.unref)(options.sendTransaction)({
608
655
  to: token.address,
609
656
  data,
610
657
  value: "0"
@@ -617,7 +664,7 @@ function useERC20Transfer(options) {
617
664
  if (stillCurrent()) isSending.value = false;
618
665
  }
619
666
  };
620
- (0, import_vue5.onScopeDispose)(() => {
667
+ (0, import_vue6.onScopeDispose)(() => {
621
668
  disposed = true;
622
669
  generation++;
623
670
  });
@@ -627,29 +674,29 @@ function useERC20Transfer(options) {
627
674
  // src/useERC20Approve.ts
628
675
  var import_connect_appkit_core6 = require("@naculus/connect-appkit-core");
629
676
  var import_connect_core6 = require("@naculus/connect-core");
630
- var import_vue6 = require("vue");
677
+ var import_vue7 = require("vue");
631
678
  var MAX_UINT256 = (1n << 256n) - 1n;
632
679
  function useERC20Approve(options) {
633
- const initialToken = (0, import_vue6.toValue)(options.token);
680
+ const initialToken = (0, import_vue7.toValue)(options.token);
634
681
  const decimals = (0, import_connect_appkit_core6.createDecimalsCache)(initialToken, initialToken.decimals);
635
- const allowanceRaw = (0, import_vue6.shallowRef)(null);
636
- const isApproving = (0, import_vue6.shallowRef)(false);
637
- const isFetchingAllowance = (0, import_vue6.shallowRef)(false);
638
- const error = (0, import_vue6.shallowRef)(null);
682
+ const allowanceRaw = (0, import_vue7.shallowRef)(null);
683
+ const isApproving = (0, import_vue7.shallowRef)(false);
684
+ const isFetchingAllowance = (0, import_vue7.shallowRef)(false);
685
+ const error = (0, import_vue7.shallowRef)(null);
639
686
  let generation = 0;
640
687
  let allowanceGeneration = 0;
641
688
  let disposed = false;
642
- (0, import_vue6.watch)(
689
+ (0, import_vue7.watch)(
643
690
  [
644
- () => (0, import_vue6.toValue)(options.token).address,
645
- () => (0, import_vue6.toValue)(options.token).chainId,
646
- () => (0, import_vue6.toValue)(options.token).decimals,
647
- () => (0, import_vue6.toValue)(options.spender),
648
- () => (0, import_vue6.toValue)(options.account),
649
- () => (0, import_vue6.toValue)(options.chainId),
650
- () => (0, import_vue6.toValue)(options.connected),
651
- () => (0, import_vue6.toValue)(options.publicClient),
652
- () => (0, import_vue6.unref)(options.sendTransaction)
691
+ () => (0, import_vue7.toValue)(options.token).address,
692
+ () => (0, import_vue7.toValue)(options.token).chainId,
693
+ () => (0, import_vue7.toValue)(options.token).decimals,
694
+ () => (0, import_vue7.toValue)(options.spender),
695
+ () => (0, import_vue7.toValue)(options.account),
696
+ () => (0, import_vue7.toValue)(options.chainId),
697
+ () => (0, import_vue7.toValue)(options.connected),
698
+ () => (0, import_vue7.toValue)(options.publicClient),
699
+ () => (0, import_vue7.unref)(options.sendTransaction)
653
700
  ],
654
701
  () => {
655
702
  generation++;
@@ -662,17 +709,17 @@ function useERC20Approve(options) {
662
709
  { flush: "sync" }
663
710
  );
664
711
  const context = () => {
665
- const token = (0, import_vue6.toValue)(options.token);
712
+ const token = (0, import_vue7.toValue)(options.token);
666
713
  const account = assertErc20Context(
667
714
  token,
668
- (0, import_vue6.toValue)(options.chainId),
669
- (0, import_vue6.toValue)(options.account),
670
- (0, import_vue6.toValue)(options.connected)
715
+ (0, import_vue7.toValue)(options.chainId),
716
+ (0, import_vue7.toValue)(options.account),
717
+ (0, import_vue7.toValue)(options.connected)
671
718
  );
672
- const reader = (0, import_vue6.toValue)(options.publicClient);
719
+ const reader = (0, import_vue7.toValue)(options.publicClient);
673
720
  if (!reader)
674
721
  throw new import_connect_core6.WalletError("wallet_unavailable", "No public client");
675
- return { token, account, reader, spender: (0, import_vue6.toValue)(options.spender) };
722
+ return { token, account, reader, spender: (0, import_vue7.toValue)(options.spender) };
676
723
  };
677
724
  const readPrecision = async () => {
678
725
  const { token, reader } = context();
@@ -723,7 +770,7 @@ function useERC20Approve(options) {
723
770
  isApproving.value = true;
724
771
  try {
725
772
  const { token, spender } = context();
726
- const hash = await (0, import_vue6.unref)(options.sendTransaction)({
773
+ const hash = await (0, import_vue7.unref)(options.sendTransaction)({
727
774
  to: token.address,
728
775
  data: (0, import_connect_appkit_core6.encodeErc20Approve)(spender, rawAmount),
729
776
  value: "0"
@@ -764,13 +811,13 @@ function useERC20Approve(options) {
764
811
  if (raw === null) return false;
765
812
  return raw >= (0, import_connect_core6.parseUnits)(required, await readPrecision());
766
813
  };
767
- const allowance = (0, import_vue6.computed)(() => {
814
+ const allowance = (0, import_vue7.computed)(() => {
768
815
  if (allowanceRaw.value === null) return null;
769
- const token = (0, import_vue6.toValue)(options.token);
816
+ const token = (0, import_vue7.toValue)(options.token);
770
817
  const precision = (0, import_connect_appkit_core6.readDecimals)(decimals, token, token.decimals);
771
818
  return precision === void 0 ? null : (0, import_connect_core6.formatUnits)(allowanceRaw.value, precision);
772
819
  });
773
- (0, import_vue6.onScopeDispose)(() => {
820
+ (0, import_vue7.onScopeDispose)(() => {
774
821
  disposed = true;
775
822
  generation++;
776
823
  allowanceGeneration++;
@@ -791,19 +838,19 @@ function useERC20Approve(options) {
791
838
  // src/useERC20TransferSimulation.ts
792
839
  var import_connect_appkit_core7 = require("@naculus/connect-appkit-core");
793
840
  var import_connect_core7 = require("@naculus/connect-core");
794
- var import_vue7 = require("vue");
841
+ var import_vue8 = require("vue");
795
842
  function useERC20TransferSimulation(options) {
796
- const transaction = (0, import_vue7.computed)(() => {
797
- const token = (0, import_vue7.toValue)(options.token);
798
- if (!(0, import_vue7.toValue)(options.connected) || !(0, import_vue7.toValue)(options.evmAccount))
843
+ const transaction = (0, import_vue8.computed)(() => {
844
+ const token = (0, import_vue8.toValue)(options.token);
845
+ if (!(0, import_vue8.toValue)(options.connected) || !(0, import_vue8.toValue)(options.evmAccount))
799
846
  return void 0;
800
847
  try {
801
848
  if (token.decimals === void 0) return void 0;
802
849
  return {
803
850
  to: token.address,
804
851
  data: (0, import_connect_appkit_core7.encodeErc20Transfer)(
805
- (0, import_vue7.toValue)(options.to),
806
- (0, import_connect_core7.parseUnits)((0, import_vue7.toValue)(options.amount), token.decimals)
852
+ (0, import_vue8.toValue)(options.to),
853
+ (0, import_connect_core7.parseUnits)((0, import_vue8.toValue)(options.amount), token.decimals)
807
854
  ),
808
855
  value: "0"
809
856
  };
@@ -811,10 +858,10 @@ function useERC20TransferSimulation(options) {
811
858
  return void 0;
812
859
  }
813
860
  });
814
- const chainId = (0, import_vue7.computed)(() => {
815
- const token = (0, import_vue7.toValue)(options.token);
861
+ const chainId = (0, import_vue8.computed)(() => {
862
+ const token = (0, import_vue8.toValue)(options.token);
816
863
  if (token.chainId !== void 0) return token.chainId;
817
- const currentChain = (0, import_vue7.toValue)(options.currentChain);
864
+ const currentChain = (0, import_vue8.toValue)(options.currentChain);
818
865
  return currentChain ? (0, import_connect_appkit_core7.chainNumber)(currentChain) ?? void 0 : void 0;
819
866
  });
820
867
  const simulation = useTransactionSimulation(transaction, {
@@ -824,39 +871,39 @@ function useERC20TransferSimulation(options) {
824
871
  evmAccount: options.evmAccount
825
872
  });
826
873
  return {
827
- result: (0, import_vue7.computed)(
874
+ result: (0, import_vue8.computed)(
828
875
  () => transaction.value ? simulation.result.value : void 0
829
876
  ),
830
- isSimulating: (0, import_vue7.computed)(
877
+ isSimulating: (0, import_vue8.computed)(
831
878
  () => !!transaction.value && simulation.isSimulating.value
832
879
  ),
833
- error: (0, import_vue7.computed)(() => transaction.value ? simulation.error.value : null),
880
+ error: (0, import_vue8.computed)(() => transaction.value ? simulation.error.value : null),
834
881
  reSimulate: simulation.simulate,
835
882
  reset: simulation.reset
836
883
  };
837
884
  }
838
885
 
839
886
  // src/useAccount.ts
840
- var import_vue8 = require("vue");
887
+ var import_vue9 = require("vue");
841
888
  function useAccount(accounts, connected) {
842
889
  const parsed = useAccounts(accounts);
843
- const isConnected = (0, import_vue8.computed)(() => (0, import_vue8.toValue)(connected));
844
- const accountList = (0, import_vue8.computed)(() => (0, import_vue8.toValue)(accounts) ?? []);
890
+ const isConnected = (0, import_vue9.computed)(() => (0, import_vue9.toValue)(connected));
891
+ const accountList = (0, import_vue9.computed)(() => (0, import_vue9.toValue)(accounts) ?? []);
845
892
  return {
846
- accounts: (0, import_vue8.computed)(
893
+ accounts: (0, import_vue9.computed)(
847
894
  () => isConnected.value && accountList.value.length > 0 ? parsed.accounts.value : null
848
895
  ),
849
- evmAccount: (0, import_vue8.computed)(
896
+ evmAccount: (0, import_vue9.computed)(
850
897
  () => isConnected.value ? parsed.evmAccount.value : null
851
898
  ),
852
- primaryAccount: (0, import_vue8.computed)(() => accountList.value[0] ?? null),
899
+ primaryAccount: (0, import_vue9.computed)(() => accountList.value[0] ?? null),
853
900
  isConnected,
854
- count: (0, import_vue8.computed)(() => accountList.value.length)
901
+ count: (0, import_vue9.computed)(() => accountList.value.length)
855
902
  };
856
903
  }
857
904
 
858
905
  // src/useSession.ts
859
- var import_vue9 = require("vue");
906
+ var import_vue10 = require("vue");
860
907
  function readSession(manager) {
861
908
  const bundle = manager?.getActiveBundle();
862
909
  if (!bundle) {
@@ -875,9 +922,9 @@ function readSession(manager) {
875
922
  };
876
923
  }
877
924
  function useSession(manager) {
878
- const snapshot = (0, import_vue9.shallowRef)(readSession((0, import_vue9.toValue)(manager)));
879
- (0, import_vue9.watch)(
880
- () => (0, import_vue9.toValue)(manager),
925
+ const snapshot = (0, import_vue10.shallowRef)(readSession((0, import_vue10.toValue)(manager)));
926
+ (0, import_vue10.watch)(
927
+ () => (0, import_vue10.toValue)(manager),
881
928
  (current, _previous, onCleanup) => {
882
929
  const update = () => {
883
930
  snapshot.value = readSession(current);
@@ -900,61 +947,17 @@ function useSession(manager) {
900
947
  { immediate: true }
901
948
  );
902
949
  return {
903
- session: (0, import_vue9.computed)(() => snapshot.value.session),
904
- chainSessions: (0, import_vue9.computed)(() => snapshot.value.chainSessions),
905
- activeChainId: (0, import_vue9.computed)(() => snapshot.value.activeChainId),
906
- isConnected: (0, import_vue9.computed)(() => snapshot.value.session !== null),
907
- connectorId: (0, import_vue9.computed)(() => snapshot.value.connectorId)
950
+ session: (0, import_vue10.computed)(() => snapshot.value.session),
951
+ chainSessions: (0, import_vue10.computed)(() => snapshot.value.chainSessions),
952
+ activeChainId: (0, import_vue10.computed)(() => snapshot.value.activeChainId),
953
+ isConnected: (0, import_vue10.computed)(() => snapshot.value.session !== null),
954
+ connectorId: (0, import_vue10.computed)(() => snapshot.value.connectorId)
908
955
  };
909
956
  }
910
957
 
911
958
  // src/useConnect.ts
912
959
  var import_connect_core8 = require("@naculus/connect-core");
913
960
  var import_vue11 = require("vue");
914
-
915
- // src/internal/action-guard.ts
916
- var import_vue10 = require("vue");
917
- function useActionGuard() {
918
- const busy = (0, import_vue10.shallowRef)(false);
919
- const error = (0, import_vue10.shallowRef)(null);
920
- let active = 0;
921
- let generation = 0;
922
- let disposed = false;
923
- const run = async (action, fallbackMessage, normalizeError) => {
924
- const own = ++generation;
925
- const commit = (write) => {
926
- if (!disposed && own === generation) write();
927
- };
928
- active++;
929
- busy.value = true;
930
- error.value = null;
931
- try {
932
- return await action(commit);
933
- } catch (cause) {
934
- const normalized = normalizeError ? normalizeError(cause) : cause instanceof Error ? cause : new Error(fallbackMessage);
935
- if (!disposed && own === generation) error.value = normalized;
936
- throw normalized;
937
- } finally {
938
- active--;
939
- if (!disposed) busy.value = active > 0;
940
- }
941
- };
942
- const reset = () => {
943
- generation++;
944
- error.value = null;
945
- };
946
- const clearError = () => {
947
- error.value = null;
948
- };
949
- const dispose = () => {
950
- disposed = true;
951
- generation++;
952
- };
953
- (0, import_vue10.onScopeDispose)(dispose);
954
- return { busy, error, run, clearError, reset, dispose };
955
- }
956
-
957
- // src/useConnect.ts
958
961
  function useConnect(action, status) {
959
962
  const guard = useActionGuard();
960
963
  let inFlight = null;
@@ -1124,44 +1127,30 @@ function useSolanaTransaction(options) {
1124
1127
  // src/useSignInWithX.ts
1125
1128
  var import_vue17 = require("vue");
1126
1129
  function useSignInWithX(action) {
1127
- const isSigningIn = (0, import_vue17.shallowRef)(false);
1130
+ const guard = useActionGuard();
1128
1131
  const result = (0, import_vue17.shallowRef)(null);
1129
- const error = (0, import_vue17.shallowRef)(null);
1130
- let generation = 0;
1131
- let active = 0;
1132
- let disposed = false;
1133
- const signIn = async (options) => {
1132
+ const signIn = (options) => {
1134
1133
  const invoke = (0, import_vue17.unref)(action);
1135
- const own = ++generation;
1136
- active++;
1137
- isSigningIn.value = true;
1138
- error.value = null;
1139
- try {
1134
+ return guard.run(async (commit) => {
1140
1135
  const next = await invoke(options);
1141
- if (!disposed && own === generation) result.value = next;
1136
+ commit(() => {
1137
+ result.value = next;
1138
+ });
1142
1139
  return next;
1143
- } catch (cause) {
1144
- const normalized = cause instanceof Error ? cause : new Error("SIWX sign-in failed");
1145
- if (!disposed && own === generation) error.value = normalized;
1146
- throw normalized;
1147
- } finally {
1148
- active--;
1149
- if (!disposed) isSigningIn.value = active > 0;
1150
- }
1151
- };
1152
- const clearError = () => {
1153
- error.value = null;
1140
+ }, "SIWX sign-in failed");
1154
1141
  };
1155
1142
  const reset = () => {
1156
- generation++;
1143
+ guard.reset();
1157
1144
  result.value = null;
1158
- error.value = null;
1159
1145
  };
1160
- (0, import_vue17.onScopeDispose)(() => {
1161
- disposed = true;
1162
- generation++;
1163
- });
1164
- return { signIn, isSigningIn, result, error, clearError, reset };
1146
+ return {
1147
+ signIn,
1148
+ isSigningIn: guard.busy,
1149
+ result,
1150
+ error: guard.error,
1151
+ clearError: guard.clearError,
1152
+ reset
1153
+ };
1165
1154
  }
1166
1155
 
1167
1156
  // src/useSignInWithEthereum.ts
@@ -1322,6 +1311,10 @@ function useDelegationPolicy(options) {
1322
1311
  previewExecution: (callCount, atomicity) => (0, import_vue20.unref)(options.previewExecution)(callCount, atomicity),
1323
1312
  sponsorship: options.sponsorship,
1324
1313
  adapter: options.adapter,
1314
+ signTypedData: options.signTypedData ? (typedData) => (0, import_vue20.unref)(
1315
+ options.signTypedData
1316
+ )(typedData) : void 0,
1317
+ chainId: () => (0, import_vue20.toValue)(options.chainId) ?? null,
1325
1318
  delegation: () => (0, import_vue20.toValue)(options.delegation),
1326
1319
  encryptionKeyConfigured: Boolean(options.managerConfig?.encryptionKey),
1327
1320
  storageAvailable: () => sessionKeys.storageAvailable,
@@ -1939,35 +1932,43 @@ var import_connect_appkit_core14 = require("@naculus/connect-appkit-core");
1939
1932
  var import_connect_core11 = require("@naculus/connect-core");
1940
1933
  var import_vue28 = require("vue");
1941
1934
  function useBalance(account, client, options = {}) {
1935
+ const guard = useActionGuard();
1942
1936
  const balance = (0, import_vue28.shallowRef)(null);
1943
1937
  const isFetching = (0, import_vue28.shallowRef)(false);
1944
- const error = (0, import_vue28.shallowRef)(null);
1945
- let generation = 0;
1946
- let disposed = false;
1947
1938
  let timer = null;
1948
1939
  const refetch = async () => {
1949
1940
  const reader = (0, import_vue28.toValue)(client);
1950
1941
  const address = (0, import_connect_appkit_core14.bareEvmAddress)((0, import_vue28.toValue)(account));
1951
- const own = ++generation;
1952
1942
  if (!reader || !address) {
1943
+ guard.reset();
1953
1944
  balance.value = null;
1954
- error.value = null;
1955
1945
  isFetching.value = false;
1956
1946
  return;
1957
1947
  }
1958
1948
  isFetching.value = true;
1959
- error.value = null;
1960
- try {
1961
- const next = await reader.getBalance({ address });
1962
- if (disposed || own !== generation) return;
1963
- balance.value = next.toString();
1964
- } catch (cause) {
1965
- if (disposed || own !== generation) return;
1966
- balance.value = null;
1967
- error.value = cause instanceof Error ? cause : new Error("Balance read failed");
1968
- } finally {
1969
- if (!disposed && own === generation) isFetching.value = false;
1970
- }
1949
+ await guard.run(
1950
+ async (commit) => {
1951
+ try {
1952
+ const next = await reader.getBalance({ address });
1953
+ commit(() => {
1954
+ balance.value = next.toString();
1955
+ });
1956
+ } catch (cause) {
1957
+ commit(() => {
1958
+ balance.value = null;
1959
+ });
1960
+ throw cause;
1961
+ }
1962
+ },
1963
+ "Balance read failed",
1964
+ void 0,
1965
+ {
1966
+ onSettled: () => {
1967
+ isFetching.value = false;
1968
+ }
1969
+ }
1970
+ ).catch(() => {
1971
+ });
1971
1972
  };
1972
1973
  const stopTimer = () => {
1973
1974
  if (timer) clearInterval(timer);
@@ -1986,11 +1987,7 @@ function useBalance(account, client, options = {}) {
1986
1987
  },
1987
1988
  { immediate: true }
1988
1989
  );
1989
- (0, import_vue28.onScopeDispose)(() => {
1990
- disposed = true;
1991
- generation++;
1992
- stopTimer();
1993
- });
1990
+ (0, import_vue28.onScopeDispose)(stopTimer);
1994
1991
  return {
1995
1992
  balance,
1996
1993
  formatted: (0, import_vue28.computed)(
@@ -1998,7 +1995,7 @@ function useBalance(account, client, options = {}) {
1998
1995
  ),
1999
1996
  symbol: (0, import_vue28.computed)(() => (0, import_vue28.toValue)(options.symbol) ?? null),
2000
1997
  isFetching,
2001
- error,
1998
+ error: guard.error,
2002
1999
  refetch
2003
2000
  };
2004
2001
  }
@@ -2007,45 +2004,64 @@ function useBalance(account, client, options = {}) {
2007
2004
  var import_connect_appkit_core15 = require("@naculus/connect-appkit-core");
2008
2005
  var import_vue29 = require("vue");
2009
2006
  function useRouteQuote(input, getQuotes, options = {}) {
2007
+ const guard = useActionGuard();
2010
2008
  const quotes = (0, import_vue29.shallowRef)([]);
2011
2009
  const loading = (0, import_vue29.shallowRef)(false);
2012
- const error = (0, import_vue29.shallowRef)(null);
2013
- let generation = 0;
2014
- let disposed = false;
2015
2010
  let timer = null;
2016
2011
  const clearTimer = () => {
2017
2012
  if (timer) clearTimeout(timer);
2018
2013
  timer = null;
2019
2014
  };
2020
- const fetchQuotes = async () => {
2021
- const current = (0, import_vue29.toValue)(input);
2022
- const fn = (0, import_vue29.unref)(getQuotes);
2023
- const own = ++generation;
2015
+ const requestable = (current) => {
2024
2016
  if (!(0, import_connect_appkit_core15.isQuotableInput)(current)) {
2017
+ guard.invalidate();
2018
+ loading.value = false;
2025
2019
  quotes.value = [];
2026
- return;
2020
+ return null;
2027
2021
  }
2022
+ const fn = (0, import_vue29.unref)(getQuotes);
2023
+ if (!fn) {
2024
+ guard.invalidate();
2025
+ loading.value = false;
2026
+ return null;
2027
+ }
2028
+ return fn;
2029
+ };
2030
+ const fetchQuotes = async () => {
2031
+ const current = (0, import_vue29.toValue)(input);
2032
+ const fn = requestable(current);
2028
2033
  if (!fn) return;
2029
2034
  loading.value = true;
2030
- error.value = null;
2031
- try {
2032
- const result = await fn(
2033
- current.fromChain,
2034
- current.toChain,
2035
- current.fromToken,
2036
- current.amount,
2037
- current.options,
2038
- current.toToken
2039
- );
2040
- if (disposed || own !== generation) return;
2041
- quotes.value = result;
2042
- } catch (cause) {
2043
- if (disposed || own !== generation) return;
2044
- error.value = cause instanceof Error ? cause : new Error(String(cause));
2045
- quotes.value = [];
2046
- } finally {
2047
- if (!disposed && own === generation) loading.value = false;
2048
- }
2035
+ await guard.run(
2036
+ async (commit) => {
2037
+ try {
2038
+ const result = await fn(
2039
+ current.fromChain,
2040
+ current.toChain,
2041
+ current.fromToken,
2042
+ current.amount,
2043
+ current.options,
2044
+ current.toToken
2045
+ );
2046
+ commit(() => {
2047
+ quotes.value = result;
2048
+ });
2049
+ } catch (cause) {
2050
+ commit(() => {
2051
+ quotes.value = [];
2052
+ });
2053
+ throw cause;
2054
+ }
2055
+ },
2056
+ "Route quote failed",
2057
+ (cause) => cause instanceof Error ? cause : new Error(String(cause)),
2058
+ {
2059
+ onSettled: () => {
2060
+ loading.value = false;
2061
+ }
2062
+ }
2063
+ ).catch(() => {
2064
+ });
2049
2065
  };
2050
2066
  (0, import_vue29.watch)(
2051
2067
  [
@@ -2056,12 +2072,10 @@ function useRouteQuote(input, getQuotes, options = {}) {
2056
2072
  () => (0, import_vue29.toValue)(input).amount,
2057
2073
  () => (0, import_vue29.unref)(getQuotes)
2058
2074
  ],
2059
- ([fromChain, toChain, fromToken, , amount]) => {
2075
+ () => {
2060
2076
  clearTimer();
2061
- if (!fromChain || !toChain || !fromToken || !amount) {
2062
- quotes.value = [];
2063
- return;
2064
- }
2077
+ guard.invalidate();
2078
+ if (!requestable((0, import_vue29.toValue)(input))) return;
2065
2079
  timer = setTimeout(() => {
2066
2080
  timer = null;
2067
2081
  void fetchQuotes();
@@ -2069,21 +2083,16 @@ function useRouteQuote(input, getQuotes, options = {}) {
2069
2083
  },
2070
2084
  { immediate: true }
2071
2085
  );
2072
- (0, import_vue29.onScopeDispose)(() => {
2073
- disposed = true;
2074
- generation++;
2075
- clearTimer();
2076
- });
2086
+ (0, import_vue29.onScopeDispose)(clearTimer);
2077
2087
  return {
2078
2088
  quotes,
2079
2089
  loading,
2080
- error,
2090
+ error: guard.error,
2081
2091
  refresh: fetchQuotes,
2082
2092
  clear: () => {
2083
2093
  clearTimer();
2084
- generation++;
2094
+ guard.reset();
2085
2095
  quotes.value = [];
2086
- error.value = null;
2087
2096
  loading.value = false;
2088
2097
  }
2089
2098
  };
@@ -2093,33 +2102,47 @@ function useRouteQuote(input, getQuotes, options = {}) {
2093
2102
  var import_connect_appkit_core16 = require("@naculus/connect-appkit-core");
2094
2103
  var import_vue30 = require("vue");
2095
2104
  function useCompareCosts(input, compareCosts) {
2105
+ const guard = useActionGuard();
2096
2106
  const comparisons = (0, import_vue30.shallowRef)([]);
2097
2107
  const loading = (0, import_vue30.shallowRef)(false);
2098
- const error = (0, import_vue30.shallowRef)(null);
2099
- let generation = 0;
2100
- let disposed = false;
2101
2108
  const fetchComparisons = async () => {
2102
2109
  const { operation, chains, options } = (0, import_vue30.toValue)(input);
2103
2110
  const fn = (0, import_vue30.unref)(compareCosts);
2104
- const own = ++generation;
2105
2111
  if (!chains || chains.length === 0) {
2112
+ guard.invalidate();
2113
+ loading.value = false;
2106
2114
  comparisons.value = [];
2107
2115
  return;
2108
2116
  }
2109
- if (!fn) return;
2110
- loading.value = true;
2111
- error.value = null;
2112
- try {
2113
- const result = await fn(operation, chains, options);
2114
- if (disposed || own !== generation) return;
2115
- comparisons.value = result;
2116
- } catch (cause) {
2117
- if (disposed || own !== generation) return;
2118
- error.value = cause instanceof Error ? cause : new Error(String(cause));
2119
- comparisons.value = [];
2120
- } finally {
2121
- if (!disposed && own === generation) loading.value = false;
2117
+ if (!fn) {
2118
+ guard.invalidate();
2119
+ loading.value = false;
2120
+ return;
2122
2121
  }
2122
+ loading.value = true;
2123
+ await guard.run(
2124
+ async (commit) => {
2125
+ try {
2126
+ const result = await fn(operation, chains, options);
2127
+ commit(() => {
2128
+ comparisons.value = result;
2129
+ });
2130
+ } catch (cause) {
2131
+ commit(() => {
2132
+ comparisons.value = [];
2133
+ });
2134
+ throw cause;
2135
+ }
2136
+ },
2137
+ "Cost comparison failed",
2138
+ (cause) => cause instanceof Error ? cause : new Error(String(cause)),
2139
+ {
2140
+ onSettled: () => {
2141
+ loading.value = false;
2142
+ }
2143
+ }
2144
+ ).catch(() => {
2145
+ });
2123
2146
  };
2124
2147
  (0, import_vue30.watch)(
2125
2148
  [() => (0, import_connect_appkit_core16.compareCostsKey)((0, import_vue30.toValue)(input)), () => (0, import_vue30.unref)(compareCosts)],
@@ -2128,11 +2151,12 @@ function useCompareCosts(input, compareCosts) {
2128
2151
  },
2129
2152
  { immediate: true }
2130
2153
  );
2131
- (0, import_vue30.onScopeDispose)(() => {
2132
- disposed = true;
2133
- generation++;
2134
- });
2135
- return { comparisons, loading, error, refresh: fetchComparisons };
2154
+ return {
2155
+ comparisons,
2156
+ loading,
2157
+ error: guard.error,
2158
+ refresh: fetchComparisons
2159
+ };
2136
2160
  }
2137
2161
 
2138
2162
  // src/useExecuteRoute.ts
@@ -2207,12 +2231,10 @@ function useTokenList(chainId, options = {}) {
2207
2231
  const config = {};
2208
2232
  if (options.sources) config.sources = options.sources;
2209
2233
  const manager = options.manager ?? new import_connect_core12.TokenListManager(config);
2234
+ const guard = useActionGuard();
2210
2235
  const tokens = (0, import_vue32.shallowRef)([]);
2211
2236
  const isLoading = (0, import_vue32.shallowRef)(options.autoLoad !== false);
2212
2237
  const isLoaded = (0, import_vue32.shallowRef)(false);
2213
- const error = (0, import_vue32.shallowRef)(null);
2214
- let generation = 0;
2215
- let disposed = false;
2216
2238
  const select = () => {
2217
2239
  const id = (0, import_vue32.toValue)(chainId);
2218
2240
  const numeric = id ? (0, import_connect_appkit_core18.eip155ChainIdToNumber)(id) : void 0;
@@ -2221,20 +2243,24 @@ function useTokenList(chainId, options = {}) {
2221
2243
  );
2222
2244
  };
2223
2245
  const run = async (op) => {
2224
- const own = ++generation;
2225
2246
  isLoading.value = true;
2226
- error.value = null;
2227
- try {
2228
- await op();
2229
- if (disposed || own !== generation) return;
2230
- tokens.value = select();
2231
- isLoaded.value = true;
2232
- } catch (cause) {
2233
- if (disposed || own !== generation) return;
2234
- error.value = cause instanceof Error ? cause : new Error(String(cause));
2235
- } finally {
2236
- if (!disposed && own === generation) isLoading.value = false;
2237
- }
2247
+ await guard.run(
2248
+ async (commit) => {
2249
+ await op();
2250
+ commit(() => {
2251
+ tokens.value = select();
2252
+ isLoaded.value = true;
2253
+ });
2254
+ },
2255
+ "Token list load failed",
2256
+ (cause) => cause instanceof Error ? cause : new Error(String(cause)),
2257
+ {
2258
+ onSettled: () => {
2259
+ isLoading.value = false;
2260
+ }
2261
+ }
2262
+ ).catch(() => {
2263
+ });
2238
2264
  };
2239
2265
  (0, import_vue32.watch)(
2240
2266
  () => (0, import_vue32.toValue)(chainId),
@@ -2243,15 +2269,11 @@ function useTokenList(chainId, options = {}) {
2243
2269
  },
2244
2270
  { immediate: true }
2245
2271
  );
2246
- (0, import_vue32.onScopeDispose)(() => {
2247
- disposed = true;
2248
- generation++;
2249
- });
2250
2272
  return {
2251
2273
  tokens,
2252
2274
  isLoading,
2253
2275
  isLoaded,
2254
- error,
2276
+ error: guard.error,
2255
2277
  refetch: () => run(() => manager.refresh())
2256
2278
  };
2257
2279
  }
@@ -2323,55 +2345,63 @@ function tokensKey(tokens) {
2323
2345
  return tokens.map((t) => `${t.address.toLowerCase()}|${t.decimals}|${t.symbol}`).join(",");
2324
2346
  }
2325
2347
  function useTokenBalance(account, client, tokens, options = {}) {
2348
+ const guard = useActionGuard();
2326
2349
  const tokenBalances = (0, import_vue35.shallowRef)([]);
2327
2350
  const isFetching = (0, import_vue35.shallowRef)(false);
2328
- const error = (0, import_vue35.shallowRef)(null);
2329
- let generation = 0;
2330
- let disposed = false;
2331
2351
  let timer = null;
2332
2352
  const refetch = async () => {
2333
2353
  const reader = (0, import_vue35.toValue)(client);
2334
2354
  const address = (0, import_connect_appkit_core21.bareEvmAddress)((0, import_vue35.toValue)(account));
2335
2355
  const list = (0, import_vue35.toValue)(tokens) ?? [];
2336
- const own = ++generation;
2337
2356
  if (!reader || !address || list.length === 0) {
2357
+ guard.reset();
2338
2358
  tokenBalances.value = [];
2339
- error.value = null;
2340
2359
  isFetching.value = false;
2341
2360
  return;
2342
2361
  }
2343
2362
  isFetching.value = true;
2344
- error.value = null;
2345
- try {
2346
- const results = await Promise.all(
2347
- list.map(async (token) => {
2348
- try {
2349
- const raw = await reader.readContract({
2350
- address: token.address,
2351
- abi: import_connect_core14.ERC20_MIN_ABI,
2352
- functionName: "balanceOf",
2353
- args: [address]
2354
- });
2355
- const value = BigInt(raw);
2356
- return {
2357
- ...token,
2358
- balance: value.toString(),
2359
- formatted: (0, import_connect_core14.formatUnits)(value, token.decimals)
2360
- };
2361
- } catch {
2362
- return { ...token, balance: null, formatted: null };
2363
- }
2364
- })
2365
- );
2366
- if (disposed || own !== generation) return;
2367
- tokenBalances.value = results;
2368
- } catch (cause) {
2369
- if (disposed || own !== generation) return;
2370
- tokenBalances.value = [];
2371
- error.value = cause instanceof Error ? cause : new Error("Failed to fetch token balances");
2372
- } finally {
2373
- if (!disposed && own === generation) isFetching.value = false;
2374
- }
2363
+ await guard.run(
2364
+ async (commit) => {
2365
+ try {
2366
+ const results = await Promise.all(
2367
+ list.map(async (token) => {
2368
+ try {
2369
+ const raw = await reader.readContract({
2370
+ address: token.address,
2371
+ abi: import_connect_core14.ERC20_MIN_ABI,
2372
+ functionName: "balanceOf",
2373
+ args: [address]
2374
+ });
2375
+ const value = BigInt(raw);
2376
+ return {
2377
+ ...token,
2378
+ balance: value.toString(),
2379
+ formatted: (0, import_connect_core14.formatUnits)(value, token.decimals)
2380
+ };
2381
+ } catch {
2382
+ return { ...token, balance: null, formatted: null };
2383
+ }
2384
+ })
2385
+ );
2386
+ commit(() => {
2387
+ tokenBalances.value = results;
2388
+ });
2389
+ } catch (cause) {
2390
+ commit(() => {
2391
+ tokenBalances.value = [];
2392
+ });
2393
+ throw cause;
2394
+ }
2395
+ },
2396
+ "Failed to fetch token balances",
2397
+ void 0,
2398
+ {
2399
+ onSettled: () => {
2400
+ isFetching.value = false;
2401
+ }
2402
+ }
2403
+ ).catch(() => {
2404
+ });
2375
2405
  };
2376
2406
  const stopTimer = () => {
2377
2407
  if (timer) clearInterval(timer);
@@ -2391,15 +2421,11 @@ function useTokenBalance(account, client, tokens, options = {}) {
2391
2421
  },
2392
2422
  { immediate: true }
2393
2423
  );
2394
- (0, import_vue35.onScopeDispose)(() => {
2395
- disposed = true;
2396
- generation++;
2397
- stopTimer();
2398
- });
2424
+ (0, import_vue35.onScopeDispose)(stopTimer);
2399
2425
  return {
2400
2426
  tokenBalances,
2401
2427
  isFetching,
2402
- error,
2428
+ error: guard.error,
2403
2429
  refetch,
2404
2430
  getTokenBalance: (tokenAddress) => tokenBalances.value.find(
2405
2431
  (t) => t.address.toLowerCase() === tokenAddress.toLowerCase()
@@ -2504,35 +2530,42 @@ var import_connect_appkit_core23 = require("@naculus/connect-appkit-core");
2504
2530
  var import_connect_core16 = require("@naculus/connect-core");
2505
2531
  var import_vue37 = require("vue");
2506
2532
  function useDelegation(account, client, chainId) {
2533
+ const guard = useActionGuard();
2507
2534
  const status = (0, import_vue37.shallowRef)(import_connect_core16.UNKNOWN_DELEGATION);
2508
2535
  const isFetching = (0, import_vue37.shallowRef)(false);
2509
- const error = (0, import_vue37.shallowRef)(null);
2510
- let generation = 0;
2511
- let disposed = false;
2512
2536
  const refetch = async () => {
2513
- const mine = ++generation;
2514
2537
  const reader = (0, import_vue37.toValue)(client);
2515
2538
  const address = (0, import_connect_appkit_core23.bareEvmAddress)((0, import_vue37.toValue)(account));
2516
2539
  status.value = import_connect_core16.UNKNOWN_DELEGATION;
2517
- error.value = null;
2518
2540
  if (!reader || !address) {
2541
+ guard.reset();
2519
2542
  isFetching.value = false;
2520
2543
  return;
2521
2544
  }
2522
2545
  isFetching.value = true;
2523
- try {
2524
- const code = await reader.getCode({ address });
2525
- if (!disposed && mine === generation) {
2526
- status.value = (0, import_connect_core16.readDelegation)(code ?? "0x");
2527
- }
2528
- } catch (cause) {
2529
- if (!disposed && mine === generation) {
2530
- status.value = import_connect_core16.UNKNOWN_DELEGATION;
2531
- error.value = cause instanceof Error ? cause : new Error("Code read failed");
2546
+ await guard.run(
2547
+ async (commit) => {
2548
+ try {
2549
+ const code = await reader.getCode({ address });
2550
+ commit(() => {
2551
+ status.value = (0, import_connect_core16.readDelegation)(code ?? "0x");
2552
+ });
2553
+ } catch (cause) {
2554
+ commit(() => {
2555
+ status.value = import_connect_core16.UNKNOWN_DELEGATION;
2556
+ });
2557
+ throw cause;
2558
+ }
2559
+ },
2560
+ "Code read failed",
2561
+ void 0,
2562
+ {
2563
+ onSettled: () => {
2564
+ isFetching.value = false;
2565
+ }
2532
2566
  }
2533
- } finally {
2534
- if (!disposed && mine === generation) isFetching.value = false;
2535
- }
2567
+ ).catch(() => {
2568
+ });
2536
2569
  };
2537
2570
  (0, import_vue37.watch)(
2538
2571
  [() => (0, import_vue37.toValue)(account), () => (0, import_vue37.toValue)(client), () => (0, import_vue37.toValue)(chainId)],
@@ -2541,72 +2574,108 @@ function useDelegation(account, client, chainId) {
2541
2574
  },
2542
2575
  { immediate: true, flush: "sync" }
2543
2576
  );
2544
- (0, import_vue37.onScopeDispose)(() => {
2545
- disposed = true;
2546
- generation++;
2547
- });
2548
2577
  return {
2549
2578
  delegated: (0, import_vue37.computed)(() => status.value.delegated),
2550
2579
  delegate: (0, import_vue37.computed)(() => status.value.delegate),
2551
2580
  isFetching,
2552
- error,
2581
+ error: guard.error,
2553
2582
  refetch
2554
2583
  };
2555
2584
  }
2556
2585
 
2557
- // src/name-lookup.ts
2586
+ // src/usePaymentFetch.ts
2558
2587
  var import_connect_appkit_core24 = require("@naculus/connect-appkit-core");
2559
2588
  var import_vue38 = require("vue");
2589
+ function usePaymentFetch(pay) {
2590
+ const guard = useActionGuard();
2591
+ const lastPayment = (0, import_vue38.shallowRef)(null);
2592
+ let epoch = 0;
2593
+ (0, import_vue38.onScopeDispose)(() => {
2594
+ epoch++;
2595
+ });
2596
+ const payFetch = (input, init) => {
2597
+ const invoke = (0, import_vue38.unref)(pay);
2598
+ const own = epoch;
2599
+ return guard.run(async () => {
2600
+ const result = await invoke(input, init);
2601
+ const payment = (0, import_connect_appkit_core24.describePayment)(input, result);
2602
+ if (payment && own === epoch) lastPayment.value = payment;
2603
+ return result;
2604
+ }, "Paid request failed");
2605
+ };
2606
+ return {
2607
+ payFetch,
2608
+ isPending: guard.busy,
2609
+ lastPayment,
2610
+ error: guard.error,
2611
+ reset: () => {
2612
+ epoch++;
2613
+ guard.reset();
2614
+ lastPayment.value = null;
2615
+ }
2616
+ };
2617
+ }
2618
+
2619
+ // src/name-lookup.ts
2620
+ var import_connect_appkit_core25 = require("@naculus/connect-appkit-core");
2621
+ var import_vue39 = require("vue");
2560
2622
  function useNameLookup(options) {
2561
- const data = (0, import_vue38.shallowRef)(null);
2562
- const loading = (0, import_vue38.shallowRef)(false);
2563
- const error = (0, import_vue38.shallowRef)(null);
2564
- let generation = 0;
2565
- let disposed = false;
2623
+ const guard = useActionGuard();
2624
+ const data = (0, import_vue39.shallowRef)(null);
2625
+ const loading = (0, import_vue39.shallowRef)(false);
2566
2626
  const run = () => {
2567
- const input = (0, import_vue38.toValue)(options.input).trim();
2568
- const skip = (0, import_vue38.toValue)(options.skip) ?? false;
2569
- const scope = (0, import_vue38.toValue)(options.scope);
2570
- const config = (0, import_vue38.toValue)(options.resolverConfig);
2571
- const mine = ++generation;
2627
+ const input = (0, import_vue39.toValue)(options.input).trim();
2628
+ const skip = (0, import_vue39.toValue)(options.skip) ?? false;
2629
+ const scope = (0, import_vue39.toValue)(options.scope);
2630
+ const config = (0, import_vue39.toValue)(options.resolverConfig);
2572
2631
  if (!input || skip) {
2632
+ guard.reset();
2573
2633
  data.value = null;
2574
2634
  loading.value = false;
2575
- error.value = null;
2576
2635
  return;
2577
2636
  }
2578
2637
  data.value = null;
2579
2638
  loading.value = true;
2580
- error.value = null;
2581
- Promise.resolve().then(() => options.query((0, import_connect_appkit_core24.getResolver)(config), input, scope)).then((result) => {
2582
- if (disposed || mine !== generation) return;
2583
- data.value = result;
2584
- loading.value = false;
2585
- }).catch((cause) => {
2586
- if (disposed || mine !== generation) return;
2587
- data.value = null;
2588
- error.value = cause instanceof Error ? cause : new Error(String(cause));
2589
- loading.value = false;
2639
+ void guard.run(
2640
+ async (commit) => {
2641
+ try {
2642
+ const result = await Promise.resolve().then(
2643
+ () => options.query((0, import_connect_appkit_core25.getResolver)(config), input, scope)
2644
+ );
2645
+ commit(() => {
2646
+ data.value = result;
2647
+ });
2648
+ } catch (cause) {
2649
+ commit(() => {
2650
+ data.value = null;
2651
+ });
2652
+ throw cause;
2653
+ }
2654
+ },
2655
+ "Name lookup failed",
2656
+ (cause) => cause instanceof Error ? cause : new Error(String(cause)),
2657
+ {
2658
+ onSettled: () => {
2659
+ loading.value = false;
2660
+ }
2661
+ }
2662
+ ).catch(() => {
2590
2663
  });
2591
2664
  };
2592
- (0, import_vue38.watch)(
2665
+ (0, import_vue39.watch)(
2593
2666
  () => [
2594
- (0, import_vue38.toValue)(options.input),
2595
- (0, import_vue38.toValue)(options.skip),
2596
- (0, import_vue38.toValue)(options.scope),
2597
- (0, import_vue38.toValue)(options.resolverConfig)
2667
+ (0, import_vue39.toValue)(options.input),
2668
+ (0, import_vue39.toValue)(options.skip),
2669
+ (0, import_vue39.toValue)(options.scope),
2670
+ (0, import_vue39.toValue)(options.resolverConfig)
2598
2671
  ],
2599
2672
  run,
2600
2673
  { immediate: true, flush: "sync", deep: true }
2601
2674
  );
2602
- (0, import_vue38.onScopeDispose)(() => {
2603
- disposed = true;
2604
- generation++;
2605
- });
2606
2675
  return {
2607
2676
  data,
2608
- isLoading: (0, import_vue38.computed)(() => loading.value),
2609
- error,
2677
+ isLoading: (0, import_vue39.computed)(() => loading.value),
2678
+ error: guard.error,
2610
2679
  refetch: run
2611
2680
  };
2612
2681
  }
@@ -2633,21 +2702,21 @@ function useLookupAddress(address, options) {
2633
2702
  }
2634
2703
 
2635
2704
  // src/useSolanaAccount.ts
2636
- var import_vue39 = require("vue");
2705
+ var import_vue40 = require("vue");
2637
2706
  function useSolanaAccount(accounts, connected) {
2638
- const isConnected = (0, import_vue39.computed)(() => (0, import_vue39.toValue)(connected));
2639
- const caip10 = (0, import_vue39.computed)(
2640
- () => isConnected.value ? ((0, import_vue39.toValue)(accounts) ?? []).find(
2707
+ const isConnected = (0, import_vue40.computed)(() => (0, import_vue40.toValue)(connected));
2708
+ const caip10 = (0, import_vue40.computed)(
2709
+ () => isConnected.value ? ((0, import_vue40.toValue)(accounts) ?? []).find(
2641
2710
  (account) => account.startsWith("solana:")
2642
2711
  ) ?? null : null
2643
2712
  );
2644
- const parts = (0, import_vue39.computed)(() => caip10.value?.split(":") ?? []);
2713
+ const parts = (0, import_vue40.computed)(() => caip10.value?.split(":") ?? []);
2645
2714
  return {
2646
- address: (0, import_vue39.computed)(
2715
+ address: (0, import_vue40.computed)(
2647
2716
  () => parts.value.length >= 3 ? parts.value.at(-1) ?? null : null
2648
2717
  ),
2649
2718
  caip10,
2650
- chainId: (0, import_vue39.computed)(
2719
+ chainId: (0, import_vue40.computed)(
2651
2720
  () => parts.value.length >= 3 ? parts.value.slice(0, -1).join(":") : null
2652
2721
  ),
2653
2722
  isConnected
@@ -2655,35 +2724,35 @@ function useSolanaAccount(accounts, connected) {
2655
2724
  }
2656
2725
 
2657
2726
  // src/useChain.ts
2658
- var import_connect_appkit_core25 = require("@naculus/connect-appkit-core");
2659
- var import_vue40 = require("vue");
2727
+ var import_connect_appkit_core26 = require("@naculus/connect-appkit-core");
2728
+ var import_vue41 = require("vue");
2660
2729
  function useChain(chains, chainId) {
2661
- const list = (0, import_vue40.computed)(() => (0, import_vue40.toValue)(chains) ?? []);
2662
- const id = (0, import_vue40.computed)(() => (0, import_vue40.toValue)(chainId) ?? null);
2663
- const currentChain = (0, import_vue40.computed)(() => (0, import_connect_appkit_core25.resolveChain)(list.value, id.value));
2730
+ const list = (0, import_vue41.computed)(() => (0, import_vue41.toValue)(chains) ?? []);
2731
+ const id = (0, import_vue41.computed)(() => (0, import_vue41.toValue)(chainId) ?? null);
2732
+ const currentChain = (0, import_vue41.computed)(() => (0, import_connect_appkit_core26.resolveChain)(list.value, id.value));
2664
2733
  return {
2665
2734
  currentChain,
2666
- chainInfo: (0, import_vue40.computed)(() => (0, import_connect_appkit_core25.describeChain)(list.value, id.value)),
2667
- availableChains: (0, import_vue40.computed)(() => (0, import_connect_appkit_core25.chainsForNamespace)(list.value, id.value)),
2668
- currentChainNumber: (0, import_vue40.computed)(
2669
- () => currentChain.value ? (0, import_connect_appkit_core25.chainNumber)(currentChain.value) : null
2735
+ chainInfo: (0, import_vue41.computed)(() => (0, import_connect_appkit_core26.describeChain)(list.value, id.value)),
2736
+ availableChains: (0, import_vue41.computed)(() => (0, import_connect_appkit_core26.chainsForNamespace)(list.value, id.value)),
2737
+ currentChainNumber: (0, import_vue41.computed)(
2738
+ () => currentChain.value ? (0, import_connect_appkit_core26.chainNumber)(currentChain.value) : null
2670
2739
  ),
2671
- namespace: (0, import_vue40.computed)(
2672
- () => currentChain.value ? (0, import_connect_appkit_core25.chainNamespace)(currentChain.value) : null
2740
+ namespace: (0, import_vue41.computed)(
2741
+ () => currentChain.value ? (0, import_connect_appkit_core26.chainNamespace)(currentChain.value) : null
2673
2742
  )
2674
2743
  };
2675
2744
  }
2676
2745
 
2677
2746
  // src/usePassphraseGate.ts
2678
- var import_vue41 = require("vue");
2747
+ var import_vue42 = require("vue");
2679
2748
  function usePassphraseGate(gate) {
2680
- const request = (0, import_vue41.shallowRef)(gate.getSnapshot());
2749
+ const request = (0, import_vue42.shallowRef)(gate.getSnapshot());
2681
2750
  const unsubscribe = gate.subscribe(() => {
2682
2751
  request.value = gate.getSnapshot();
2683
2752
  });
2684
- (0, import_vue41.onScopeDispose)(unsubscribe);
2753
+ (0, import_vue42.onScopeDispose)(unsubscribe);
2685
2754
  return {
2686
- request: (0, import_vue41.readonly)(request),
2755
+ request: (0, import_vue42.readonly)(request),
2687
2756
  submit: (passphrase) => gate.submit(passphrase),
2688
2757
  cancel: (reason) => gate.cancel(reason),
2689
2758
  forget: (reason) => gate.forget(reason)
@@ -2692,54 +2761,61 @@ function usePassphraseGate(gate) {
2692
2761
 
2693
2762
  // src/useSolanaBalance.ts
2694
2763
  var import_connect_core17 = require("@naculus/connect-core");
2695
- var import_vue42 = require("vue");
2764
+ var import_vue43 = require("vue");
2696
2765
  function useSolanaBalance(address, rpcUrl) {
2697
- const balance = (0, import_vue42.shallowRef)(null);
2698
- const isFetching = (0, import_vue42.ref)(false);
2699
- const error = (0, import_vue42.shallowRef)(null);
2700
- let generation = 0;
2701
- let disposed = false;
2766
+ const guard = useActionGuard();
2767
+ const balance = (0, import_vue43.shallowRef)(null);
2768
+ const isFetching = (0, import_vue43.ref)(false);
2702
2769
  const refetch = async () => {
2703
- const addr = (0, import_vue42.toValue)(address);
2704
- const url = (0, import_vue42.toValue)(rpcUrl);
2770
+ const addr = (0, import_vue43.toValue)(address);
2771
+ const url = (0, import_vue43.toValue)(rpcUrl);
2705
2772
  if (!addr || !url) {
2773
+ guard.invalidate();
2774
+ isFetching.value = false;
2706
2775
  balance.value = null;
2707
2776
  return;
2708
2777
  }
2709
- const own = ++generation;
2710
2778
  isFetching.value = true;
2711
- error.value = null;
2712
- try {
2713
- const next = await (0, import_connect_core17.getSolanaBalance)(url, addr);
2714
- if (disposed || own !== generation) return;
2715
- balance.value = next;
2716
- } catch (err) {
2717
- if (disposed || own !== generation) return;
2718
- balance.value = null;
2719
- error.value = err instanceof Error ? err : new Error("Balance read failed");
2720
- } finally {
2721
- if (!disposed && own === generation) isFetching.value = false;
2722
- }
2779
+ await guard.run(
2780
+ async (commit) => {
2781
+ try {
2782
+ const next = await (0, import_connect_core17.getSolanaBalance)(url, addr);
2783
+ commit(() => {
2784
+ balance.value = next;
2785
+ });
2786
+ } catch (err) {
2787
+ commit(() => {
2788
+ balance.value = null;
2789
+ });
2790
+ throw err;
2791
+ }
2792
+ },
2793
+ "Balance read failed",
2794
+ void 0,
2795
+ {
2796
+ onSettled: () => {
2797
+ isFetching.value = false;
2798
+ }
2799
+ }
2800
+ ).catch(() => {
2801
+ });
2723
2802
  };
2724
- (0, import_vue42.watchEffect)(() => {
2725
- (0, import_vue42.toValue)(address);
2726
- (0, import_vue42.toValue)(rpcUrl);
2803
+ (0, import_vue43.watchEffect)(() => {
2804
+ (0, import_vue43.toValue)(address);
2805
+ (0, import_vue43.toValue)(rpcUrl);
2727
2806
  void refetch();
2728
2807
  });
2729
- (0, import_vue42.onScopeDispose)(() => {
2730
- disposed = true;
2731
- });
2732
- return { balance, isFetching, error, refetch };
2808
+ return { balance, isFetching, error: guard.error, refetch };
2733
2809
  }
2734
2810
 
2735
2811
  // src/useLastTx.ts
2736
- var import_vue43 = require("vue");
2812
+ var import_vue44 = require("vue");
2737
2813
  function useLastTx(monitor) {
2738
- const lastTx = (0, import_vue43.shallowRef)(null);
2739
- const lastConfirmedTx = (0, import_vue43.shallowRef)(null);
2740
- const lastFailedTx = (0, import_vue43.shallowRef)(null);
2741
- (0, import_vue43.watch)(
2742
- () => (0, import_vue43.toValue)(monitor),
2814
+ const lastTx = (0, import_vue44.shallowRef)(null);
2815
+ const lastConfirmedTx = (0, import_vue44.shallowRef)(null);
2816
+ const lastFailedTx = (0, import_vue44.shallowRef)(null);
2817
+ (0, import_vue44.watch)(
2818
+ () => (0, import_vue44.toValue)(monitor),
2743
2819
  (activeMonitor, _previous, onCleanup) => {
2744
2820
  if (!activeMonitor) return;
2745
2821
  const recordLatest = (entry) => {
@@ -2777,38 +2853,42 @@ function useLastTx(monitor) {
2777
2853
  }
2778
2854
 
2779
2855
  // src/useTxHistory.ts
2780
- var import_vue44 = require("vue");
2856
+ var import_vue45 = require("vue");
2781
2857
  function useTxHistory(address, chainId, monitor) {
2782
- const entries = (0, import_vue44.shallowRef)([]);
2783
- const isLoading = (0, import_vue44.shallowRef)(false);
2784
- const error = (0, import_vue44.shallowRef)(null);
2785
- let generation = 0;
2858
+ const guard = useActionGuard();
2859
+ const entries = (0, import_vue45.shallowRef)([]);
2860
+ const isLoading = (0, import_vue45.shallowRef)(false);
2786
2861
  const refresh = async () => {
2787
- const mine = ++generation;
2788
- const activeMonitor = (0, import_vue44.toValue)(monitor);
2862
+ const activeMonitor = (0, import_vue45.toValue)(monitor);
2789
2863
  if (!activeMonitor) {
2864
+ guard.reset();
2790
2865
  entries.value = [];
2791
2866
  isLoading.value = false;
2792
- error.value = null;
2793
2867
  return;
2794
2868
  }
2795
2869
  isLoading.value = true;
2796
- error.value = null;
2797
- try {
2798
- const result = await activeMonitor.getTxHistory(
2799
- (0, import_vue44.toValue)(address) ?? void 0,
2800
- (0, import_vue44.toValue)(chainId) ?? void 0
2801
- );
2802
- if (mine === generation) entries.value = result;
2803
- } catch (err) {
2804
- if (mine !== generation) return;
2805
- error.value = err instanceof Error ? err : new Error("Failed to load transaction history");
2806
- } finally {
2807
- if (mine === generation) isLoading.value = false;
2808
- }
2870
+ await guard.run(
2871
+ async (commit) => {
2872
+ const result = await activeMonitor.getTxHistory(
2873
+ (0, import_vue45.toValue)(address) ?? void 0,
2874
+ (0, import_vue45.toValue)(chainId) ?? void 0
2875
+ );
2876
+ commit(() => {
2877
+ entries.value = result;
2878
+ });
2879
+ },
2880
+ "Failed to load transaction history",
2881
+ void 0,
2882
+ {
2883
+ onSettled: () => {
2884
+ isLoading.value = false;
2885
+ }
2886
+ }
2887
+ ).catch(() => {
2888
+ });
2809
2889
  };
2810
- (0, import_vue44.watch)(
2811
- [() => (0, import_vue44.toValue)(monitor), () => (0, import_vue44.toValue)(address), () => (0, import_vue44.toValue)(chainId)],
2890
+ (0, import_vue45.watch)(
2891
+ [() => (0, import_vue45.toValue)(monitor), () => (0, import_vue45.toValue)(address), () => (0, import_vue45.toValue)(chainId)],
2812
2892
  ([activeMonitor], _previous, onCleanup) => {
2813
2893
  if (!activeMonitor) {
2814
2894
  void refresh();
@@ -2826,9 +2906,9 @@ function useTxHistory(address, chainId, monitor) {
2826
2906
  return {
2827
2907
  entries,
2828
2908
  isLoading,
2829
- error,
2909
+ error: guard.error,
2830
2910
  refresh,
2831
- summary: (0, import_vue44.computed)(() => ({
2911
+ summary: (0, import_vue45.computed)(() => ({
2832
2912
  pending: entries.value.filter((item) => item.status === "pending").length,
2833
2913
  confirmed: entries.value.filter((item) => item.status === "confirmed").length,
2834
2914
  failed: entries.value.filter((item) => item.status === "failed").length
@@ -2837,17 +2917,17 @@ function useTxHistory(address, chainId, monitor) {
2837
2917
  }
2838
2918
 
2839
2919
  // src/useTxMonitor.ts
2840
- var import_vue45 = require("vue");
2920
+ var import_vue46 = require("vue");
2841
2921
  function useTxMonitor(hash, chainId, monitor) {
2842
- const entry = (0, import_vue45.shallowRef)(null);
2843
- const isLoading = (0, import_vue45.shallowRef)(false);
2844
- const isWatching = (0, import_vue45.shallowRef)(false);
2845
- const error = (0, import_vue45.shallowRef)(null);
2922
+ const entry = (0, import_vue46.shallowRef)(null);
2923
+ const isLoading = (0, import_vue46.shallowRef)(false);
2924
+ const isWatching = (0, import_vue46.shallowRef)(false);
2925
+ const error = (0, import_vue46.shallowRef)(null);
2846
2926
  let generation = 0;
2847
2927
  const refresh = async () => {
2848
- const activeMonitor = (0, import_vue45.toValue)(monitor);
2849
- const activeHash = (0, import_vue45.toValue)(hash);
2850
- const activeChainId = (0, import_vue45.toValue)(chainId);
2928
+ const activeMonitor = (0, import_vue46.toValue)(monitor);
2929
+ const activeHash = (0, import_vue46.toValue)(hash);
2930
+ const activeChainId = (0, import_vue46.toValue)(chainId);
2851
2931
  if (!activeMonitor || !activeHash) return;
2852
2932
  isLoading.value = true;
2853
2933
  error.value = null;
@@ -2865,15 +2945,15 @@ function useTxMonitor(hash, chainId, monitor) {
2865
2945
  }
2866
2946
  };
2867
2947
  const stopWatching = () => {
2868
- const activeMonitor = (0, import_vue45.toValue)(monitor);
2869
- const activeHash = (0, import_vue45.toValue)(hash);
2870
- const activeChainId = (0, import_vue45.toValue)(chainId);
2948
+ const activeMonitor = (0, import_vue46.toValue)(monitor);
2949
+ const activeHash = (0, import_vue46.toValue)(hash);
2950
+ const activeChainId = (0, import_vue46.toValue)(chainId);
2871
2951
  if (!activeMonitor || !activeHash) return;
2872
2952
  activeMonitor.stopWatching(activeHash, activeChainId ?? void 0);
2873
2953
  isWatching.value = false;
2874
2954
  };
2875
- (0, import_vue45.watch)(
2876
- [() => (0, import_vue45.toValue)(monitor), () => (0, import_vue45.toValue)(hash), () => (0, import_vue45.toValue)(chainId)],
2955
+ (0, import_vue46.watch)(
2956
+ [() => (0, import_vue46.toValue)(monitor), () => (0, import_vue46.toValue)(hash), () => (0, import_vue46.toValue)(chainId)],
2877
2957
  ([activeMonitor, activeHash, activeChainId], _previous, onCleanup) => {
2878
2958
  const mine = ++generation;
2879
2959
  if (!activeMonitor || !activeHash || !activeChainId) {
@@ -2913,7 +2993,7 @@ function useTxMonitor(hash, chainId, monitor) {
2913
2993
  );
2914
2994
  return {
2915
2995
  entry,
2916
- status: (0, import_vue45.computed)(() => entry.value?.status ?? "idle"),
2996
+ status: (0, import_vue46.computed)(() => entry.value?.status ?? "idle"),
2917
2997
  isLoading,
2918
2998
  isWatching,
2919
2999
  error,
@@ -2923,71 +3003,80 @@ function useTxMonitor(hash, chainId, monitor) {
2923
3003
  }
2924
3004
 
2925
3005
  // src/useCapabilities.ts
2926
- var import_connect_appkit_core26 = require("@naculus/connect-appkit-core");
2927
- var import_vue46 = require("vue");
3006
+ var import_connect_appkit_core27 = require("@naculus/connect-appkit-core");
3007
+ var import_vue47 = require("vue");
2928
3008
  function useCapabilities(client, session, chainId) {
2929
- const capabilities = (0, import_vue46.shallowRef)(
3009
+ const guard = useActionGuard();
3010
+ const capabilities = (0, import_vue47.shallowRef)(
2930
3011
  null
2931
3012
  );
2932
- const isFetching = (0, import_vue46.shallowRef)(false);
2933
- const error = (0, import_vue46.shallowRef)(null);
2934
- let generation = 0;
3013
+ const isFetching = (0, import_vue47.shallowRef)(false);
2935
3014
  const refetch = async () => {
2936
- const mine = ++generation;
2937
- const activeClient = (0, import_vue46.toValue)(client);
2938
- const activeSession = (0, import_vue46.toValue)(session);
3015
+ const activeClient = (0, import_vue47.toValue)(client);
3016
+ const activeSession = (0, import_vue47.toValue)(session);
2939
3017
  if (!activeClient?.getCapabilities || !activeSession) {
3018
+ guard.reset();
2940
3019
  capabilities.value = null;
2941
3020
  isFetching.value = false;
2942
- error.value = null;
2943
3021
  return;
2944
3022
  }
2945
3023
  isFetching.value = true;
2946
- error.value = null;
2947
- try {
2948
- const raw = await activeClient.getCapabilities(activeSession);
2949
- if (mine !== generation) return;
2950
- capabilities.value = (0, import_connect_appkit_core26.normalizeCapabilities)(raw);
2951
- } catch (err) {
2952
- if (mine !== generation) return;
2953
- capabilities.value = null;
2954
- error.value = err instanceof Error ? err : new Error("Capability query failed");
2955
- } finally {
2956
- if (mine === generation) isFetching.value = false;
2957
- }
3024
+ await guard.run(
3025
+ async (commit) => {
3026
+ try {
3027
+ const raw = await activeClient.getCapabilities(activeSession);
3028
+ commit(() => {
3029
+ capabilities.value = (0, import_connect_appkit_core27.normalizeCapabilities)(raw);
3030
+ });
3031
+ } catch (err) {
3032
+ commit(() => {
3033
+ capabilities.value = null;
3034
+ });
3035
+ throw err;
3036
+ }
3037
+ },
3038
+ "Capability query failed",
3039
+ void 0,
3040
+ {
3041
+ onSettled: () => {
3042
+ isFetching.value = false;
3043
+ }
3044
+ }
3045
+ ).catch(() => {
3046
+ });
2958
3047
  };
2959
- (0, import_vue46.watchEffect)(() => {
2960
- void (0, import_vue46.toValue)(client);
2961
- void (0, import_vue46.toValue)(session);
3048
+ (0, import_vue47.watchEffect)(() => {
3049
+ void (0, import_vue47.toValue)(client);
3050
+ void (0, import_vue47.toValue)(session);
2962
3051
  void refetch();
2963
3052
  });
2964
3053
  return {
2965
3054
  capabilities,
2966
- current: (0, import_vue46.computed)(
2967
- () => (0, import_connect_appkit_core26.selectChainCapabilities)(capabilities.value, (0, import_vue46.toValue)(chainId))
3055
+ current: (0, import_vue47.computed)(
3056
+ () => (0, import_connect_appkit_core27.selectChainCapabilities)(capabilities.value, (0, import_vue47.toValue)(chainId))
2968
3057
  ),
2969
- atomic: (0, import_vue46.computed)(
2970
- () => (0, import_connect_appkit_core26.atomicSupportFor)(capabilities.value, (0, import_vue46.toValue)(chainId))
3058
+ atomic: (0, import_vue47.computed)(
3059
+ () => (0, import_connect_appkit_core27.atomicSupportFor)(capabilities.value, (0, import_vue47.toValue)(chainId))
2971
3060
  ),
2972
3061
  isFetching,
2973
- error,
3062
+ error: guard.error,
2974
3063
  refetch
2975
3064
  };
2976
3065
  }
2977
3066
 
2978
3067
  // src/useSolanaRoles.ts
2979
- var import_connect_appkit_core27 = require("@naculus/connect-appkit-core");
2980
- var import_vue47 = require("vue");
3068
+ var import_connect_appkit_core28 = require("@naculus/connect-appkit-core");
3069
+ var import_vue48 = require("vue");
2981
3070
  function useSolanaRoles(connector, session) {
2982
- const state = (0, import_vue47.computed)(
2983
- () => (0, import_connect_appkit_core27.readSolanaRoles)((0, import_vue47.toValue)(connector), (0, import_vue47.toValue)(session))
3071
+ const state = (0, import_vue48.computed)(
3072
+ () => (0, import_connect_appkit_core28.readSolanaRoles)((0, import_vue48.toValue)(connector), (0, import_vue48.toValue)(session))
2984
3073
  );
2985
3074
  return {
2986
- roles: (0, import_vue47.computed)(() => state.value.roles),
2987
- absence: (0, import_vue47.computed)(() => state.value.absence),
2988
- identity: (0, import_vue47.computed)(() => state.value.roles?.identity ?? null),
2989
- signer: (0, import_vue47.computed)(() => state.value.roles?.signer ?? null),
2990
- payer: (0, import_vue47.computed)(() => state.value.roles?.payer ?? null)
3075
+ roles: (0, import_vue48.computed)(() => state.value.roles),
3076
+ absence: (0, import_vue48.computed)(() => state.value.absence),
3077
+ identity: (0, import_vue48.computed)(() => state.value.roles?.identity ?? null),
3078
+ signer: (0, import_vue48.computed)(() => state.value.roles?.signer ?? null),
3079
+ payer: (0, import_vue48.computed)(() => state.value.roles?.payer ?? null)
2991
3080
  };
2992
3081
  }
2993
3082
  // Annotate the CommonJS export names for ESM import in node:
@@ -3042,6 +3131,7 @@ function useSolanaRoles(connector, session) {
3042
3131
  useLookupAddress,
3043
3132
  useNotification,
3044
3133
  usePassphraseGate,
3134
+ usePaymentFetch,
3045
3135
  useResolveName,
3046
3136
  useRevokeSession,
3047
3137
  useRouteQuote,