@voyage_ai/v402-web-ts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,147 @@
1
+ /**
2
+ * useWallet Hook
3
+ *
4
+ * React hook for wallet connection management
5
+ */
6
+
7
+ import {useCallback, useEffect, useState} from 'react';
8
+ import {NetworkType} from '../../types';
9
+ import {
10
+ connectWallet as connectWalletUtil,
11
+ disconnectWallet as disconnectWalletUtil,
12
+ getConnectedNetworkType,
13
+ getCurrentWallet,
14
+ isWalletManuallyDisconnected,
15
+ onAccountsChanged,
16
+ } from '../../utils';
17
+
18
+ export interface UseWalletReturn {
19
+ // State
20
+ address: string | null;
21
+ networkType: NetworkType | null;
22
+ isConnecting: boolean;
23
+ error: string | null;
24
+
25
+ // Actions
26
+ connect: (networkType: NetworkType) => Promise<void>;
27
+ disconnect: () => void;
28
+ clearError: () => void;
29
+ }
30
+
31
+ /**
32
+ * Hook for managing wallet connection
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * function MyComponent() {
37
+ * const { address, connect, disconnect, isConnecting } = useWallet();
38
+ *
39
+ * return (
40
+ * <div>
41
+ * {address ? (
42
+ * <button onClick={disconnect}>Disconnect {address}</button>
43
+ * ) : (
44
+ * <button onClick={() => connect(NetworkType.SOLANA)}>
45
+ * Connect Wallet
46
+ * </button>
47
+ * )}
48
+ * </div>
49
+ * );
50
+ * }
51
+ * ```
52
+ */
53
+ export function useWallet(): UseWalletReturn {
54
+ const [address, setAddress] = useState<string | null>(null);
55
+ const [networkType, setNetworkType] = useState<NetworkType | null>(null);
56
+ const [isConnecting, setIsConnecting] = useState(false);
57
+ const [error, setError] = useState<string | null>(null);
58
+
59
+ // Initialize wallet on mount
60
+ useEffect(() => {
61
+ const initWallet = async () => {
62
+ if (!isWalletManuallyDisconnected()) {
63
+ const connectedType = getConnectedNetworkType();
64
+ if (connectedType) {
65
+ const currentAddress = await getCurrentWallet(connectedType);
66
+ if (currentAddress) {
67
+ setAddress(currentAddress);
68
+ setNetworkType(connectedType);
69
+ console.log('🔄 Auto-reconnected wallet:', currentAddress);
70
+ }
71
+ }
72
+ }
73
+ };
74
+
75
+ initWallet();
76
+
77
+ // Listen for account changes (EVM only)
78
+ const unsubscribe = onAccountsChanged((accounts) => {
79
+ const connectedType = getConnectedNetworkType();
80
+ if (connectedType === NetworkType.EVM) {
81
+ if (accounts.length === 0) {
82
+ setAddress(null);
83
+ console.log('🔌 Wallet disconnected');
84
+ } else {
85
+ if (!isWalletManuallyDisconnected()) {
86
+ setAddress(accounts[0]);
87
+ console.log('🔄 Account changed:', accounts[0]);
88
+ }
89
+ }
90
+ }
91
+ });
92
+
93
+ return () => {
94
+ unsubscribe();
95
+ };
96
+ }, []); // Only run on mount
97
+
98
+ // Connect wallet
99
+ const connect = useCallback(async (type: NetworkType) => {
100
+ setIsConnecting(true);
101
+ setError(null);
102
+
103
+ try {
104
+ const walletAddress = await connectWalletUtil(type);
105
+
106
+ console.log('✅ Wallet connected:', walletAddress, 'Network:', type);
107
+
108
+ // Update state - this should trigger re-render
109
+ setAddress(walletAddress);
110
+ setNetworkType(type);
111
+
112
+ // Force a small delay to ensure state updates
113
+ await new Promise(resolve => setTimeout(resolve, 0));
114
+
115
+ console.log('📝 State updated in hook');
116
+ } catch (err: any) {
117
+ setError(err.message || 'Failed to connect wallet');
118
+ throw err;
119
+ } finally {
120
+ setIsConnecting(false);
121
+ }
122
+ }, []);
123
+
124
+ // Disconnect wallet
125
+ const disconnect = useCallback(() => {
126
+ disconnectWalletUtil();
127
+ setAddress(null);
128
+ setNetworkType(null);
129
+ setError(null);
130
+ }, []);
131
+
132
+ // Clear error
133
+ const clearError = useCallback(() => {
134
+ setError(null);
135
+ }, []);
136
+
137
+ return {
138
+ address,
139
+ networkType,
140
+ isConnecting,
141
+ error,
142
+ connect,
143
+ disconnect,
144
+ clearError,
145
+ };
146
+ }
147
+
@@ -0,0 +1,61 @@
1
+ /**
2
+ * useWallet Hook (External Store)
3
+ *
4
+ * Uses useSyncExternalStore for optimal performance
5
+ * No Provider needed!
6
+ */
7
+
8
+ import {useSyncExternalStore} from 'react';
9
+ import {walletStore} from '../store/walletStore';
10
+ import {NetworkType} from '../../types';
11
+
12
+ export interface UseWalletReturn {
13
+ // State
14
+ address: string | null;
15
+ networkType: NetworkType | null;
16
+ isConnecting: boolean;
17
+ error: string | null;
18
+
19
+ // Actions
20
+ connect: (networkType: NetworkType) => Promise<void>;
21
+ disconnect: () => void;
22
+ clearError: () => void;
23
+ }
24
+
25
+ /**
26
+ * Hook for wallet connection
27
+ * No Provider needed - uses external store
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * function MyComponent() {
32
+ * const { address, connect, disconnect } = useWallet();
33
+ *
34
+ * return (
35
+ * <div>
36
+ * {address ? (
37
+ * <button onClick={disconnect}>Disconnect</button>
38
+ * ) : (
39
+ * <button onClick={() => connect(NetworkType.SOLANA)}>Connect</button>
40
+ * )}
41
+ * </div>
42
+ * );
43
+ * }
44
+ * ```
45
+ */
46
+ export function useWallet(): UseWalletReturn {
47
+ // Use React 18's useSyncExternalStore for optimal performance
48
+ const state = useSyncExternalStore(
49
+ (listener) => walletStore.subscribe(listener),
50
+ () => walletStore.getState(),
51
+ () => walletStore.getState() // Server snapshot
52
+ );
53
+
54
+ return {
55
+ ...state,
56
+ connect: (type: NetworkType) => walletStore.connect(type),
57
+ disconnect: () => walletStore.disconnect(),
58
+ clearError: () => walletStore.clearError(),
59
+ };
60
+ }
61
+
@@ -0,0 +1,248 @@
1
+ import { PaymentRequirements } from 'x402/types';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * Common types for x402 SDK
6
+ * Framework-agnostic types that work across different wallet implementations
7
+ */
8
+
9
+ /**
10
+ * Network type enum - for wallet detection
11
+ */
12
+ declare enum NetworkType {
13
+ EVM = "evm",
14
+ SOLANA = "solana",
15
+ SVM = "svm",// Alias for Solana
16
+ UNKNOWN = "unknown"
17
+ }
18
+
19
+ /**
20
+ * useWallet Hook (External Store)
21
+ *
22
+ * Uses useSyncExternalStore for optimal performance
23
+ * No Provider needed!
24
+ */
25
+
26
+ interface UseWalletReturn {
27
+ address: string | null;
28
+ networkType: NetworkType | null;
29
+ isConnecting: boolean;
30
+ error: string | null;
31
+ connect: (networkType: NetworkType) => Promise<void>;
32
+ disconnect: () => void;
33
+ clearError: () => void;
34
+ }
35
+ /**
36
+ * Hook for wallet connection
37
+ * No Provider needed - uses external store
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * function MyComponent() {
42
+ * const { address, connect, disconnect } = useWallet();
43
+ *
44
+ * return (
45
+ * <div>
46
+ * {address ? (
47
+ * <button onClick={disconnect}>Disconnect</button>
48
+ * ) : (
49
+ * <button onClick={() => connect(NetworkType.SOLANA)}>Connect</button>
50
+ * )}
51
+ * </div>
52
+ * );
53
+ * }
54
+ * ```
55
+ */
56
+ declare function useWallet(): UseWalletReturn;
57
+
58
+ /**
59
+ * usePayment Hook
60
+ *
61
+ * React hook for payment state management
62
+ * Provides state only - you control the payment flow
63
+ */
64
+ interface UsePaymentReturn {
65
+ isProcessing: boolean;
66
+ result: any;
67
+ error: string | null;
68
+ setIsProcessing: (value: boolean) => void;
69
+ setResult: (value: any) => void;
70
+ setError: (value: string | null) => void;
71
+ clearResult: () => void;
72
+ clearError: () => void;
73
+ reset: () => void;
74
+ }
75
+ /**
76
+ * Hook for managing payment state
77
+ *
78
+ * This hook only manages state - you control the payment logic.
79
+ * Use SDK's handleSvmPayment/handleEvmPayment directly for full control.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * import { usePayment, useWallet } from '../react';
84
+ * import { handleSvmPayment } from '@/app/sdk';
85
+ *
86
+ * function PaymentButton() {
87
+ * const { networkType } = useWallet();
88
+ * const { isProcessing, setIsProcessing, result, setResult, error, setError } = usePayment();
89
+ *
90
+ * const handlePay = async () => {
91
+ * if (!networkType) return;
92
+ *
93
+ * setIsProcessing(true);
94
+ * setError(null);
95
+ *
96
+ * try {
97
+ * const response = await handleSvmPayment('/api/endpoint', {
98
+ * wallet: window.solana,
99
+ * network: 'solana-devnet',
100
+ * });
101
+ *
102
+ * const data = await response.json();
103
+ * setResult(data);
104
+ *
105
+ * // Your custom logic here
106
+ * console.log('Payment success!');
107
+ * } catch (err: any) {
108
+ * setError(err.message);
109
+ * } finally {
110
+ * setIsProcessing(false);
111
+ * }
112
+ * };
113
+ *
114
+ * return (
115
+ * <div>
116
+ * <button onClick={handlePay} disabled={isProcessing}>
117
+ * {isProcessing ? 'Processing...' : 'Pay'}
118
+ * </button>
119
+ * {error && <p>Error: {error}</p>}
120
+ * {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
121
+ * </div>
122
+ * );
123
+ * }
124
+ * ```
125
+ */
126
+ declare function usePayment(): UsePaymentReturn;
127
+
128
+ /**
129
+ * usePaymentInfo Hook
130
+ *
131
+ * React hook for fetching payment information from endpoint
132
+ */
133
+
134
+ interface UsePaymentInfoReturn {
135
+ paymentInfo: PaymentRequirements[] | null;
136
+ supportedNetworks: NetworkType[];
137
+ isLoading: boolean;
138
+ error: string | null;
139
+ refetch: () => Promise<void>;
140
+ }
141
+ /**
142
+ * Hook for fetching payment information
143
+ *
144
+ * @param endpoint - API endpoint to fetch payment info from
145
+ * @param merchantId - @see our website to apply
146
+ *
147
+ * @example
148
+ * ```tsx
149
+ * function PaymentInfo() {
150
+ * const { paymentInfo, supportedNetworks, isLoading } = usePaymentInfo('/api/protected');
151
+ *
152
+ * if (isLoading) return <p>Loading...</p>;
153
+ *
154
+ * return (
155
+ * <div>
156
+ * <p>Supported networks:</p>
157
+ * {supportedNetworks.map(net => <span key={net}>{net}</span>)}
158
+ * </div>
159
+ * );
160
+ * }
161
+ * ```
162
+ */
163
+ declare function usePaymentInfo(merchantId: string, endpoint?: string): UsePaymentInfoReturn;
164
+
165
+ /**
166
+ * WalletConnect Component
167
+ *
168
+ * Pre-built wallet connection UI component
169
+ */
170
+
171
+ interface WalletConnectProps {
172
+ supportedNetworks?: NetworkType[];
173
+ className?: string;
174
+ onConnect?: (address: string, networkType: NetworkType) => void;
175
+ onDisconnect?: () => void;
176
+ }
177
+ /**
178
+ * Pre-built wallet connection component
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * import { WalletConnect } from '../react';
183
+ *
184
+ * function App() {
185
+ * return (
186
+ * <WalletConnect
187
+ * supportedNetworks={[NetworkType.SOLANA, NetworkType.EVM]}
188
+ * onConnect={(address, network) => console.log('Connected:', address)}
189
+ * />
190
+ * );
191
+ * }
192
+ * ```
193
+ */
194
+ declare function WalletConnect({ supportedNetworks, className, onConnect, onDisconnect, }: WalletConnectProps): React.JSX.Element;
195
+
196
+ /**
197
+ * PaymentButton Component
198
+ *
199
+ * Pre-built payment button component
200
+ * Note: This is a simple wrapper. For complex payment flows,
201
+ * use the SDK directly with usePayment hook for full control.
202
+ */
203
+
204
+ interface PaymentButtonProps {
205
+ endpoint: string;
206
+ className?: string;
207
+ disabled?: boolean;
208
+ onSuccess?: (result: any) => void;
209
+ onError?: (error: string) => void;
210
+ onStart?: () => void;
211
+ onFinish?: () => void;
212
+ children?: React.ReactNode;
213
+ }
214
+ /**
215
+ * Simple pre-built payment button
216
+ *
217
+ * For complex payment flows, use the SDK directly:
218
+ *
219
+ * @example
220
+ * ```tsx
221
+ * import { useWallet, usePayment } from '../react';
222
+ * import { handleSvmPayment } from '@/app/sdk';
223
+ *
224
+ * function CustomPayment() {
225
+ * const { networkType } = useWallet();
226
+ * const { isProcessing, setIsProcessing, setResult, setError } = usePayment();
227
+ *
228
+ * const handlePay = async () => {
229
+ * setIsProcessing(true);
230
+ * try {
231
+ * // Your custom logic before payment
232
+ * const response = await handleSvmPayment(...);
233
+ * const data = await response.json();
234
+ *
235
+ * // Your custom logic after payment
236
+ * setResult(data);
237
+ * } catch (err) {
238
+ * setError(err.message);
239
+ * } finally {
240
+ * setIsProcessing(false);
241
+ * }
242
+ * };
243
+ * }
244
+ * ```
245
+ */
246
+ declare function PaymentButton({ endpoint, className, disabled, onSuccess, onError, onStart, onFinish, children, }: PaymentButtonProps): React.JSX.Element;
247
+
248
+ export { PaymentButton, type PaymentButtonProps, type UsePaymentInfoReturn, type UsePaymentReturn, type UseWalletReturn, WalletConnect, type WalletConnectProps, usePayment, usePaymentInfo, useWallet };
@@ -0,0 +1,248 @@
1
+ import { PaymentRequirements } from 'x402/types';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * Common types for x402 SDK
6
+ * Framework-agnostic types that work across different wallet implementations
7
+ */
8
+
9
+ /**
10
+ * Network type enum - for wallet detection
11
+ */
12
+ declare enum NetworkType {
13
+ EVM = "evm",
14
+ SOLANA = "solana",
15
+ SVM = "svm",// Alias for Solana
16
+ UNKNOWN = "unknown"
17
+ }
18
+
19
+ /**
20
+ * useWallet Hook (External Store)
21
+ *
22
+ * Uses useSyncExternalStore for optimal performance
23
+ * No Provider needed!
24
+ */
25
+
26
+ interface UseWalletReturn {
27
+ address: string | null;
28
+ networkType: NetworkType | null;
29
+ isConnecting: boolean;
30
+ error: string | null;
31
+ connect: (networkType: NetworkType) => Promise<void>;
32
+ disconnect: () => void;
33
+ clearError: () => void;
34
+ }
35
+ /**
36
+ * Hook for wallet connection
37
+ * No Provider needed - uses external store
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * function MyComponent() {
42
+ * const { address, connect, disconnect } = useWallet();
43
+ *
44
+ * return (
45
+ * <div>
46
+ * {address ? (
47
+ * <button onClick={disconnect}>Disconnect</button>
48
+ * ) : (
49
+ * <button onClick={() => connect(NetworkType.SOLANA)}>Connect</button>
50
+ * )}
51
+ * </div>
52
+ * );
53
+ * }
54
+ * ```
55
+ */
56
+ declare function useWallet(): UseWalletReturn;
57
+
58
+ /**
59
+ * usePayment Hook
60
+ *
61
+ * React hook for payment state management
62
+ * Provides state only - you control the payment flow
63
+ */
64
+ interface UsePaymentReturn {
65
+ isProcessing: boolean;
66
+ result: any;
67
+ error: string | null;
68
+ setIsProcessing: (value: boolean) => void;
69
+ setResult: (value: any) => void;
70
+ setError: (value: string | null) => void;
71
+ clearResult: () => void;
72
+ clearError: () => void;
73
+ reset: () => void;
74
+ }
75
+ /**
76
+ * Hook for managing payment state
77
+ *
78
+ * This hook only manages state - you control the payment logic.
79
+ * Use SDK's handleSvmPayment/handleEvmPayment directly for full control.
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * import { usePayment, useWallet } from '../react';
84
+ * import { handleSvmPayment } from '@/app/sdk';
85
+ *
86
+ * function PaymentButton() {
87
+ * const { networkType } = useWallet();
88
+ * const { isProcessing, setIsProcessing, result, setResult, error, setError } = usePayment();
89
+ *
90
+ * const handlePay = async () => {
91
+ * if (!networkType) return;
92
+ *
93
+ * setIsProcessing(true);
94
+ * setError(null);
95
+ *
96
+ * try {
97
+ * const response = await handleSvmPayment('/api/endpoint', {
98
+ * wallet: window.solana,
99
+ * network: 'solana-devnet',
100
+ * });
101
+ *
102
+ * const data = await response.json();
103
+ * setResult(data);
104
+ *
105
+ * // Your custom logic here
106
+ * console.log('Payment success!');
107
+ * } catch (err: any) {
108
+ * setError(err.message);
109
+ * } finally {
110
+ * setIsProcessing(false);
111
+ * }
112
+ * };
113
+ *
114
+ * return (
115
+ * <div>
116
+ * <button onClick={handlePay} disabled={isProcessing}>
117
+ * {isProcessing ? 'Processing...' : 'Pay'}
118
+ * </button>
119
+ * {error && <p>Error: {error}</p>}
120
+ * {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
121
+ * </div>
122
+ * );
123
+ * }
124
+ * ```
125
+ */
126
+ declare function usePayment(): UsePaymentReturn;
127
+
128
+ /**
129
+ * usePaymentInfo Hook
130
+ *
131
+ * React hook for fetching payment information from endpoint
132
+ */
133
+
134
+ interface UsePaymentInfoReturn {
135
+ paymentInfo: PaymentRequirements[] | null;
136
+ supportedNetworks: NetworkType[];
137
+ isLoading: boolean;
138
+ error: string | null;
139
+ refetch: () => Promise<void>;
140
+ }
141
+ /**
142
+ * Hook for fetching payment information
143
+ *
144
+ * @param endpoint - API endpoint to fetch payment info from
145
+ * @param merchantId - @see our website to apply
146
+ *
147
+ * @example
148
+ * ```tsx
149
+ * function PaymentInfo() {
150
+ * const { paymentInfo, supportedNetworks, isLoading } = usePaymentInfo('/api/protected');
151
+ *
152
+ * if (isLoading) return <p>Loading...</p>;
153
+ *
154
+ * return (
155
+ * <div>
156
+ * <p>Supported networks:</p>
157
+ * {supportedNetworks.map(net => <span key={net}>{net}</span>)}
158
+ * </div>
159
+ * );
160
+ * }
161
+ * ```
162
+ */
163
+ declare function usePaymentInfo(merchantId: string, endpoint?: string): UsePaymentInfoReturn;
164
+
165
+ /**
166
+ * WalletConnect Component
167
+ *
168
+ * Pre-built wallet connection UI component
169
+ */
170
+
171
+ interface WalletConnectProps {
172
+ supportedNetworks?: NetworkType[];
173
+ className?: string;
174
+ onConnect?: (address: string, networkType: NetworkType) => void;
175
+ onDisconnect?: () => void;
176
+ }
177
+ /**
178
+ * Pre-built wallet connection component
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * import { WalletConnect } from '../react';
183
+ *
184
+ * function App() {
185
+ * return (
186
+ * <WalletConnect
187
+ * supportedNetworks={[NetworkType.SOLANA, NetworkType.EVM]}
188
+ * onConnect={(address, network) => console.log('Connected:', address)}
189
+ * />
190
+ * );
191
+ * }
192
+ * ```
193
+ */
194
+ declare function WalletConnect({ supportedNetworks, className, onConnect, onDisconnect, }: WalletConnectProps): React.JSX.Element;
195
+
196
+ /**
197
+ * PaymentButton Component
198
+ *
199
+ * Pre-built payment button component
200
+ * Note: This is a simple wrapper. For complex payment flows,
201
+ * use the SDK directly with usePayment hook for full control.
202
+ */
203
+
204
+ interface PaymentButtonProps {
205
+ endpoint: string;
206
+ className?: string;
207
+ disabled?: boolean;
208
+ onSuccess?: (result: any) => void;
209
+ onError?: (error: string) => void;
210
+ onStart?: () => void;
211
+ onFinish?: () => void;
212
+ children?: React.ReactNode;
213
+ }
214
+ /**
215
+ * Simple pre-built payment button
216
+ *
217
+ * For complex payment flows, use the SDK directly:
218
+ *
219
+ * @example
220
+ * ```tsx
221
+ * import { useWallet, usePayment } from '../react';
222
+ * import { handleSvmPayment } from '@/app/sdk';
223
+ *
224
+ * function CustomPayment() {
225
+ * const { networkType } = useWallet();
226
+ * const { isProcessing, setIsProcessing, setResult, setError } = usePayment();
227
+ *
228
+ * const handlePay = async () => {
229
+ * setIsProcessing(true);
230
+ * try {
231
+ * // Your custom logic before payment
232
+ * const response = await handleSvmPayment(...);
233
+ * const data = await response.json();
234
+ *
235
+ * // Your custom logic after payment
236
+ * setResult(data);
237
+ * } catch (err) {
238
+ * setError(err.message);
239
+ * } finally {
240
+ * setIsProcessing(false);
241
+ * }
242
+ * };
243
+ * }
244
+ * ```
245
+ */
246
+ declare function PaymentButton({ endpoint, className, disabled, onSuccess, onError, onStart, onFinish, children, }: PaymentButtonProps): React.JSX.Element;
247
+
248
+ export { PaymentButton, type PaymentButtonProps, type UsePaymentInfoReturn, type UsePaymentReturn, type UseWalletReturn, WalletConnect, type WalletConnectProps, usePayment, usePaymentInfo, useWallet };