@t402/vue 2.3.1 → 2.5.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/README.md CHANGED
@@ -12,18 +12,16 @@ npm install @t402/vue
12
12
 
13
13
  ```vue
14
14
  <script setup lang="ts">
15
- import { PaymentButton, usePaymentRequired } from "@t402/vue";
15
+ import { PaymentButton, usePaymentRequired } from '@t402/vue'
16
16
 
17
- const { paymentRequired, requirements, pay, status } = usePaymentRequired("/api/data");
17
+ const { paymentRequired, requirements, pay, status } = usePaymentRequired('/api/data')
18
18
  </script>
19
19
 
20
20
  <template>
21
21
  <div v-if="paymentRequired">
22
22
  <PaymentButton :requirements="requirements" :status="status" @pay="pay" />
23
23
  </div>
24
- <div v-else>
25
- Premium content loaded!
26
- </div>
24
+ <div v-else>Premium content loaded!</div>
27
25
  </template>
28
26
  ```
29
27
 
@@ -34,11 +32,7 @@ const { paymentRequired, requirements, pay, status } = usePaymentRequired("/api/
34
32
  Renders a payment action button with loading and status states.
35
33
 
36
34
  ```vue
37
- <PaymentButton
38
- :requirements="requirements"
39
- :status="status"
40
- @pay="handlePay"
41
- />
35
+ <PaymentButton :requirements="requirements" :status="status" @pay="handlePay" />
42
36
  ```
43
37
 
44
38
  ### PaymentDetails
@@ -73,11 +67,11 @@ Detects 402 responses and extracts payment requirements.
73
67
 
74
68
  ```typescript
75
69
  const {
76
- paymentRequired, // Ref<boolean>
77
- requirements, // Ref<PaymentRequirements[]>
78
- pay, // () => Promise<void>
79
- status, // Ref<PaymentStatus>
80
- } = usePaymentRequired(url, options);
70
+ paymentRequired, // Ref<boolean>
71
+ requirements, // Ref<PaymentRequirements[]>
72
+ pay, // () => Promise<void>
73
+ status, // Ref<PaymentStatus>
74
+ } = usePaymentRequired(url, options)
81
75
  ```
82
76
 
83
77
  ### usePaymentStatus
@@ -85,7 +79,7 @@ const {
85
79
  Tracks the lifecycle of a payment (idle, pending, confirming, complete, error).
86
80
 
87
81
  ```typescript
88
- const { status, error, reset } = usePaymentStatus();
82
+ const { status, error, reset } = usePaymentStatus()
89
83
  ```
90
84
 
91
85
  ### useAsyncPayment
@@ -93,7 +87,7 @@ const { status, error, reset } = usePaymentStatus();
93
87
  Manages async payment flows with automatic retry and status tracking.
94
88
 
95
89
  ```typescript
96
- const { execute, status, error } = useAsyncPayment(paymentFn);
90
+ const { execute, status, error } = useAsyncPayment(paymentFn)
97
91
  ```
98
92
 
99
93
  ## Utilities
@@ -107,15 +101,15 @@ import {
107
101
  truncateAddress,
108
102
  formatTokenAmount,
109
103
  choosePaymentRequirement,
110
- } from "@t402/vue";
104
+ } from '@t402/vue'
111
105
 
112
106
  // Network detection
113
- isEvmNetwork("eip155:8453"); // true
107
+ isEvmNetwork('eip155:8453') // true
114
108
 
115
109
  // Display helpers
116
- getNetworkDisplayName("eip155:8453"); // "Base"
117
- truncateAddress("0x1234567890abcdef"); // "0x1234...cdef"
118
- formatTokenAmount(1500000n, 6); // "1.50"
110
+ getNetworkDisplayName('eip155:8453') // "Base"
111
+ truncateAddress('0x1234567890abcdef') // "0x1234...cdef"
112
+ formatTokenAmount(1500000n, 6) // "1.50"
119
113
  ```
120
114
 
121
115
  ## Peer Dependencies
@@ -294,17 +294,17 @@ function getNetworkDisplayName(network) {
294
294
  return EVM_CHAIN_NAMES[chainId] ?? `Chain ${chainId}`;
295
295
  }
296
296
  if (network.startsWith("solana:")) {
297
- const ref6 = network.split(":")[1];
298
- return ref6 === SOLANA_NETWORK_REFS.DEVNET ? "Solana Devnet" : "Solana";
297
+ const ref9 = network.split(":")[1];
298
+ return ref9 === SOLANA_NETWORK_REFS.DEVNET ? "Solana Devnet" : "Solana";
299
299
  }
300
300
  if (network.startsWith("ton:")) {
301
- const ref6 = network.split(":")[1];
302
- return ref6 === TON_NETWORK_REFS.TESTNET ? "TON Testnet" : "TON";
301
+ const ref9 = network.split(":")[1];
302
+ return ref9 === TON_NETWORK_REFS.TESTNET ? "TON Testnet" : "TON";
303
303
  }
304
304
  if (network.startsWith("tron:")) {
305
- const ref6 = network.split(":")[1];
306
- if (ref6 === TRON_NETWORK_REFS.NILE) return "TRON Nile";
307
- if (ref6 === TRON_NETWORK_REFS.SHASTA) return "TRON Shasta";
305
+ const ref9 = network.split(":")[1];
306
+ if (ref9 === TRON_NETWORK_REFS.NILE) return "TRON Nile";
307
+ if (ref9 === TRON_NETWORK_REFS.SHASTA) return "TRON Shasta";
308
308
  return "TRON";
309
309
  }
310
310
  return network;
@@ -316,16 +316,16 @@ function isTestnetNetwork(network) {
316
316
  return TESTNET_CHAIN_IDS.has(chainId);
317
317
  }
318
318
  if (network.startsWith("solana:")) {
319
- const ref6 = network.split(":")[1];
320
- return ref6 === SOLANA_NETWORK_REFS.DEVNET;
319
+ const ref9 = network.split(":")[1];
320
+ return ref9 === SOLANA_NETWORK_REFS.DEVNET;
321
321
  }
322
322
  if (network.startsWith("ton:")) {
323
- const ref6 = network.split(":")[1];
324
- return ref6 === TON_NETWORK_REFS.TESTNET;
323
+ const ref9 = network.split(":")[1];
324
+ return ref9 === TON_NETWORK_REFS.TESTNET;
325
325
  }
326
326
  if (network.startsWith("tron:")) {
327
- const ref6 = network.split(":")[1];
328
- return ref6 === TRON_NETWORK_REFS.NILE || ref6 === TRON_NETWORK_REFS.SHASTA;
327
+ const ref9 = network.split(":")[1];
328
+ return ref9 === TRON_NETWORK_REFS.NILE || ref9 === TRON_NETWORK_REFS.SHASTA;
329
329
  }
330
330
  return false;
331
331
  }
@@ -716,6 +716,229 @@ function useAsyncPayment(options) {
716
716
  reset
717
717
  };
718
718
  }
719
+ function useGaslessPayment(options) {
720
+ const { payFn, onSuccess, onError, autoWait = true } = options;
721
+ const status = vue.ref("idle");
722
+ const userOpHash = vue.ref(null);
723
+ const txHash = vue.ref(null);
724
+ const sponsored = vue.ref(null);
725
+ const error = vue.ref(null);
726
+ const isLoading = vue.computed(() => status.value === "loading");
727
+ const isSuccess = vue.computed(() => status.value === "success");
728
+ const isError = vue.computed(() => status.value === "error");
729
+ const pay = async (params) => {
730
+ status.value = "loading";
731
+ error.value = null;
732
+ userOpHash.value = null;
733
+ txHash.value = null;
734
+ sponsored.value = null;
735
+ try {
736
+ const result = await payFn(params);
737
+ userOpHash.value = result.userOpHash;
738
+ sponsored.value = result.sponsored;
739
+ if (autoWait) {
740
+ const receipt = await result.wait();
741
+ txHash.value = receipt.txHash;
742
+ status.value = "success";
743
+ onSuccess?.(receipt);
744
+ } else {
745
+ status.value = "success";
746
+ onSuccess?.({ txHash: result.userOpHash, success: true });
747
+ }
748
+ } catch (err) {
749
+ const errorMessage = err instanceof Error ? err.message : "Gasless payment failed";
750
+ error.value = errorMessage;
751
+ status.value = "error";
752
+ onError?.(err instanceof Error ? err : new Error(errorMessage));
753
+ }
754
+ };
755
+ const reset = () => {
756
+ status.value = "idle";
757
+ userOpHash.value = null;
758
+ txHash.value = null;
759
+ sponsored.value = null;
760
+ error.value = null;
761
+ };
762
+ return {
763
+ pay,
764
+ status,
765
+ userOpHash,
766
+ txHash,
767
+ sponsored,
768
+ error,
769
+ isLoading,
770
+ isSuccess,
771
+ isError,
772
+ reset
773
+ };
774
+ }
775
+ function useBridgePayment(options) {
776
+ const { bridgeFn, autoBridgeFn, onSuccess, onError, autoWaitForDelivery = false } = options;
777
+ const status = vue.ref("idle");
778
+ const txHash = vue.ref(null);
779
+ const messageGuid = vue.ref(null);
780
+ const dstTxHash = vue.ref(null);
781
+ const error = vue.ref(null);
782
+ const isLoading = vue.computed(
783
+ () => status.value === "bridging" || status.value === "quoting" || status.value === "waiting"
784
+ );
785
+ const isSuccess = vue.computed(() => status.value === "success");
786
+ const isError = vue.computed(() => status.value === "error");
787
+ const executeBridge = async (bridgeCall) => {
788
+ status.value = "bridging";
789
+ error.value = null;
790
+ txHash.value = null;
791
+ messageGuid.value = null;
792
+ dstTxHash.value = null;
793
+ try {
794
+ const result = await bridgeCall();
795
+ txHash.value = result.txHash;
796
+ messageGuid.value = result.messageGuid;
797
+ if (autoWaitForDelivery) {
798
+ status.value = "waiting";
799
+ const delivery = await result.waitForDelivery();
800
+ if (delivery.dstTxHash) dstTxHash.value = delivery.dstTxHash;
801
+ status.value = "success";
802
+ onSuccess?.({
803
+ txHash: result.txHash,
804
+ dstTxHash: delivery.dstTxHash,
805
+ fromChain: result.fromChain,
806
+ toChain: result.toChain
807
+ });
808
+ } else {
809
+ status.value = "success";
810
+ onSuccess?.({
811
+ txHash: result.txHash,
812
+ fromChain: result.fromChain,
813
+ toChain: result.toChain
814
+ });
815
+ }
816
+ } catch (err) {
817
+ const errorMessage = err instanceof Error ? err.message : "Bridge operation failed";
818
+ error.value = errorMessage;
819
+ status.value = "error";
820
+ onError?.(err instanceof Error ? err : new Error(errorMessage));
821
+ }
822
+ };
823
+ const bridge = async (params) => {
824
+ await executeBridge(() => bridgeFn(params));
825
+ };
826
+ const autoBridge = async (params) => {
827
+ const fn = autoBridgeFn ?? (() => {
828
+ throw new Error("autoBridgeFn not provided");
829
+ });
830
+ await executeBridge(() => fn(params));
831
+ };
832
+ const reset = () => {
833
+ status.value = "idle";
834
+ txHash.value = null;
835
+ messageGuid.value = null;
836
+ dstTxHash.value = null;
837
+ error.value = null;
838
+ };
839
+ return {
840
+ bridge,
841
+ autoBridge,
842
+ status,
843
+ txHash,
844
+ messageGuid,
845
+ dstTxHash,
846
+ error,
847
+ isLoading,
848
+ isSuccess,
849
+ isError,
850
+ reset
851
+ };
852
+ }
853
+ function useMultiSigPayment(options) {
854
+ const { initiateFn, submitFn, onSuccess, onError, autoWait = true } = options;
855
+ const status = vue.ref("idle");
856
+ const requestId = vue.ref(null);
857
+ const userOpHash = vue.ref(null);
858
+ const txHash = vue.ref(null);
859
+ const threshold = vue.ref(0);
860
+ const collectedCount = vue.ref(0);
861
+ const isReady = vue.ref(false);
862
+ const error = vue.ref(null);
863
+ const isLoading = vue.computed(() => status.value === "initiating" || status.value === "submitting");
864
+ const isSuccess = vue.computed(() => status.value === "success");
865
+ const isError = vue.computed(() => status.value === "error");
866
+ const initiate = async (params) => {
867
+ status.value = "initiating";
868
+ error.value = null;
869
+ requestId.value = null;
870
+ userOpHash.value = null;
871
+ txHash.value = null;
872
+ try {
873
+ const result = await initiateFn(params);
874
+ requestId.value = result.requestId;
875
+ userOpHash.value = result.userOpHash;
876
+ threshold.value = result.threshold;
877
+ collectedCount.value = result.collectedCount;
878
+ isReady.value = result.isReady;
879
+ status.value = "collecting";
880
+ } catch (err) {
881
+ const errorMessage = err instanceof Error ? err.message : "Failed to initiate multi-sig payment";
882
+ error.value = errorMessage;
883
+ status.value = "error";
884
+ onError?.(err instanceof Error ? err : new Error(errorMessage));
885
+ }
886
+ };
887
+ const submit = async () => {
888
+ if (!requestId.value) {
889
+ const err = new Error("No active request to submit");
890
+ error.value = err.message;
891
+ status.value = "error";
892
+ onError?.(err);
893
+ return;
894
+ }
895
+ status.value = "submitting";
896
+ error.value = null;
897
+ try {
898
+ const result = await submitFn(requestId.value);
899
+ if (autoWait) {
900
+ const receipt = await result.wait();
901
+ txHash.value = receipt.txHash;
902
+ status.value = "success";
903
+ onSuccess?.(receipt);
904
+ } else {
905
+ status.value = "success";
906
+ onSuccess?.({ txHash: result.userOpHash, success: true });
907
+ }
908
+ } catch (err) {
909
+ const errorMessage = err instanceof Error ? err.message : "Failed to submit multi-sig transaction";
910
+ error.value = errorMessage;
911
+ status.value = "error";
912
+ onError?.(err instanceof Error ? err : new Error(errorMessage));
913
+ }
914
+ };
915
+ const reset = () => {
916
+ status.value = "idle";
917
+ requestId.value = null;
918
+ userOpHash.value = null;
919
+ txHash.value = null;
920
+ threshold.value = 0;
921
+ collectedCount.value = 0;
922
+ isReady.value = false;
923
+ error.value = null;
924
+ };
925
+ return {
926
+ initiate,
927
+ submit,
928
+ status,
929
+ requestId,
930
+ userOpHash,
931
+ txHash,
932
+ threshold,
933
+ collectedCount,
934
+ isReady,
935
+ error,
936
+ isLoading,
937
+ isSuccess,
938
+ isError,
939
+ reset
940
+ };
941
+ }
719
942
 
720
943
  exports.AddressDisplay = AddressDisplay;
721
944
  exports.EVM_CHAIN_IDS = EVM_CHAIN_IDS;
@@ -740,6 +963,9 @@ exports.normalizePaymentRequirements = normalizePaymentRequirements;
740
963
  exports.spinnerStyles = spinnerStyles;
741
964
  exports.truncateAddress = truncateAddress;
742
965
  exports.useAsyncPayment = useAsyncPayment;
966
+ exports.useBridgePayment = useBridgePayment;
967
+ exports.useGaslessPayment = useGaslessPayment;
968
+ exports.useMultiSigPayment = useMultiSigPayment;
743
969
  exports.usePaymentRequired = usePaymentRequired;
744
970
  exports.usePaymentStatus = usePaymentStatus;
745
971
  //# sourceMappingURL=index.cjs.map