@voyage_ai/v402-web-ts 0.1.2 → 0.1.4
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.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +139 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +122 -80
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +50 -1
- package/dist/react/index.d.ts +50 -1
- package/dist/react/index.js +1559 -136
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +1541 -112
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/styles.css +1 -168
- package/package.json +33 -10
- package/dist/react/components/WalletConnect.tsx +0 -152
- package/dist/react/hooks/usePayment.ts +0 -109
- package/dist/react/hooks/usePaymentInfo.ts +0 -128
- package/dist/react/hooks/useWallet.ts +0 -174
- package/dist/react/hooks/useWalletStore.ts +0 -61
- package/dist/react/index.ts +0 -38
- package/dist/react/store/walletStore.ts +0 -181
- package/dist/react/styles/inline-styles.ts +0 -238
|
@@ -1,174 +0,0 @@
|
|
|
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
|
-
onChainChanged,
|
|
17
|
-
onWalletDisconnect,
|
|
18
|
-
} from '../../utils';
|
|
19
|
-
|
|
20
|
-
export interface UseWalletReturn {
|
|
21
|
-
// State
|
|
22
|
-
address: string | null;
|
|
23
|
-
networkType: NetworkType | null;
|
|
24
|
-
isConnecting: boolean;
|
|
25
|
-
error: string | null;
|
|
26
|
-
|
|
27
|
-
// Actions
|
|
28
|
-
connect: (networkType: NetworkType) => Promise<void>;
|
|
29
|
-
disconnect: () => void;
|
|
30
|
-
clearError: () => void;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Hook for managing wallet connection
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```tsx
|
|
38
|
-
* function MyComponent() {
|
|
39
|
-
* const { address, connect, disconnect, isConnecting } = useWallet();
|
|
40
|
-
*
|
|
41
|
-
* return (
|
|
42
|
-
* <div>
|
|
43
|
-
* {address ? (
|
|
44
|
-
* <button onClick={disconnect}>Disconnect {address}</button>
|
|
45
|
-
* ) : (
|
|
46
|
-
* <button onClick={() => connect(NetworkType.SOLANA)}>
|
|
47
|
-
* Connect Wallet
|
|
48
|
-
* </button>
|
|
49
|
-
* )}
|
|
50
|
-
* </div>
|
|
51
|
-
* );
|
|
52
|
-
* }
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export function useWallet(): UseWalletReturn {
|
|
56
|
-
const [address, setAddress] = useState<string | null>(null);
|
|
57
|
-
const [networkType, setNetworkType] = useState<NetworkType | null>(null);
|
|
58
|
-
const [isConnecting, setIsConnecting] = useState(false);
|
|
59
|
-
const [error, setError] = useState<string | null>(null);
|
|
60
|
-
|
|
61
|
-
// Initialize wallet on mount
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const initWallet = async () => {
|
|
64
|
-
if (!isWalletManuallyDisconnected()) {
|
|
65
|
-
const connectedType = getConnectedNetworkType();
|
|
66
|
-
if (connectedType) {
|
|
67
|
-
const currentAddress = await getCurrentWallet(connectedType);
|
|
68
|
-
if (currentAddress) {
|
|
69
|
-
setAddress(currentAddress);
|
|
70
|
-
setNetworkType(connectedType);
|
|
71
|
-
console.log('🔄 Auto-reconnected wallet:', currentAddress);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
initWallet();
|
|
78
|
-
|
|
79
|
-
// Listen for account changes (EVM only)
|
|
80
|
-
const unsubscribeAccountChange = onAccountsChanged((accounts) => {
|
|
81
|
-
const connectedType = getConnectedNetworkType();
|
|
82
|
-
if (connectedType === NetworkType.EVM) {
|
|
83
|
-
if (accounts.length === 0) {
|
|
84
|
-
setAddress(null);
|
|
85
|
-
console.log('🔌 Wallet disconnected');
|
|
86
|
-
} else {
|
|
87
|
-
if (!isWalletManuallyDisconnected()) {
|
|
88
|
-
setAddress(accounts[0]);
|
|
89
|
-
console.log('🔄 Account changed:', accounts[0]);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// Listen for network/chain changes (EVM only)
|
|
96
|
-
const unsubscribeChainChange = onChainChanged(() => {
|
|
97
|
-
const connectedType = getConnectedNetworkType();
|
|
98
|
-
if (connectedType === NetworkType.EVM) {
|
|
99
|
-
console.log('⚠️ Network changed detected - disconnecting wallet');
|
|
100
|
-
disconnectWalletUtil();
|
|
101
|
-
setAddress(null);
|
|
102
|
-
setNetworkType(null);
|
|
103
|
-
setError('Network changed. Please reconnect your wallet.');
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Listen for wallet disconnect (Solana only)
|
|
108
|
-
const unsubscribeWalletDisconnect = onWalletDisconnect(() => {
|
|
109
|
-
const connectedType = getConnectedNetworkType();
|
|
110
|
-
if (connectedType === NetworkType.SOLANA || connectedType === NetworkType.SVM) {
|
|
111
|
-
console.log('⚠️ Solana wallet disconnected');
|
|
112
|
-
disconnectWalletUtil();
|
|
113
|
-
setAddress(null);
|
|
114
|
-
setNetworkType(null);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
return () => {
|
|
119
|
-
unsubscribeAccountChange();
|
|
120
|
-
unsubscribeChainChange();
|
|
121
|
-
unsubscribeWalletDisconnect();
|
|
122
|
-
};
|
|
123
|
-
}, []); // Only run on mount
|
|
124
|
-
|
|
125
|
-
// Connect wallet
|
|
126
|
-
const connect = useCallback(async (type: NetworkType) => {
|
|
127
|
-
setIsConnecting(true);
|
|
128
|
-
setError(null);
|
|
129
|
-
|
|
130
|
-
try {
|
|
131
|
-
const walletAddress = await connectWalletUtil(type);
|
|
132
|
-
|
|
133
|
-
console.log('✅ Wallet connected:', walletAddress, 'Network:', type);
|
|
134
|
-
|
|
135
|
-
// Update state - this should trigger re-render
|
|
136
|
-
setAddress(walletAddress);
|
|
137
|
-
setNetworkType(type);
|
|
138
|
-
|
|
139
|
-
// Force a small delay to ensure state updates
|
|
140
|
-
await new Promise(resolve => setTimeout(resolve, 0));
|
|
141
|
-
|
|
142
|
-
console.log('📝 State updated in hook');
|
|
143
|
-
} catch (err: any) {
|
|
144
|
-
setError(err.message || 'Failed to connect wallet');
|
|
145
|
-
throw err;
|
|
146
|
-
} finally {
|
|
147
|
-
setIsConnecting(false);
|
|
148
|
-
}
|
|
149
|
-
}, []);
|
|
150
|
-
|
|
151
|
-
// Disconnect wallet
|
|
152
|
-
const disconnect = useCallback(() => {
|
|
153
|
-
disconnectWalletUtil();
|
|
154
|
-
setAddress(null);
|
|
155
|
-
setNetworkType(null);
|
|
156
|
-
setError(null);
|
|
157
|
-
}, []);
|
|
158
|
-
|
|
159
|
-
// Clear error
|
|
160
|
-
const clearError = useCallback(() => {
|
|
161
|
-
setError(null);
|
|
162
|
-
}, []);
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
address,
|
|
166
|
-
networkType,
|
|
167
|
-
isConnecting,
|
|
168
|
-
error,
|
|
169
|
-
connect,
|
|
170
|
-
disconnect,
|
|
171
|
-
clearError,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
@@ -1,61 +0,0 @@
|
|
|
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
|
-
|
package/dist/react/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* x402 Payment SDK - React Package
|
|
3
|
-
*
|
|
4
|
-
* Pre-built React hooks and components for easy integration
|
|
5
|
-
*
|
|
6
|
-
* ## Quick Start
|
|
7
|
-
*
|
|
8
|
-
* ```tsx
|
|
9
|
-
* import { WalletConnect, PaymentButton, useWallet, usePayment } from '@x402/sdk/react';
|
|
10
|
-
*
|
|
11
|
-
* // No Provider needed! Just use the hooks directly
|
|
12
|
-
* function App() {
|
|
13
|
-
* const { address } = useWallet();
|
|
14
|
-
*
|
|
15
|
-
* return (
|
|
16
|
-
* <div>
|
|
17
|
-
* <WalletConnect />
|
|
18
|
-
* {address && <PaymentButton endpoint="/api/protected" />}
|
|
19
|
-
* </div>
|
|
20
|
-
* );
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
// Hooks (No Provider needed!)
|
|
26
|
-
export { useWallet } from './hooks/useWalletStore';
|
|
27
|
-
export type { UseWalletReturn } from './hooks/useWalletStore';
|
|
28
|
-
|
|
29
|
-
// Hooks
|
|
30
|
-
export { usePayment } from './hooks/usePayment';
|
|
31
|
-
export type { UsePaymentReturn } from './hooks/usePayment';
|
|
32
|
-
|
|
33
|
-
export { usePaymentInfo } from './hooks/usePaymentInfo';
|
|
34
|
-
export type { UsePaymentInfoReturn } from './hooks/usePaymentInfo';
|
|
35
|
-
|
|
36
|
-
// Components
|
|
37
|
-
export { WalletConnect } from './components/WalletConnect';
|
|
38
|
-
export type { WalletConnectProps } from './components/WalletConnect';
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wallet Store (External Store)
|
|
3
|
-
*
|
|
4
|
-
* Lightweight state management without Context Provider
|
|
5
|
-
* Uses singleton pattern + event emitter for reactivity
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {NetworkType} from '../../types';
|
|
9
|
-
import {
|
|
10
|
-
connectWallet as connectWalletUtil,
|
|
11
|
-
disconnectWallet as disconnectWalletUtil,
|
|
12
|
-
getConnectedNetworkType,
|
|
13
|
-
getCurrentWallet,
|
|
14
|
-
isWalletManuallyDisconnected,
|
|
15
|
-
onAccountsChanged,
|
|
16
|
-
onChainChanged,
|
|
17
|
-
onWalletDisconnect,
|
|
18
|
-
} from '../../utils';
|
|
19
|
-
|
|
20
|
-
type Listener = () => void;
|
|
21
|
-
|
|
22
|
-
interface WalletState {
|
|
23
|
-
address: string | null;
|
|
24
|
-
networkType: NetworkType | null;
|
|
25
|
-
isConnecting: boolean;
|
|
26
|
-
error: string | null;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class WalletStore {
|
|
30
|
-
private state: WalletState = {
|
|
31
|
-
address: null,
|
|
32
|
-
networkType: null,
|
|
33
|
-
isConnecting: false,
|
|
34
|
-
error: null,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
private listeners = new Set<Listener>();
|
|
38
|
-
private initialized = false;
|
|
39
|
-
|
|
40
|
-
// Initialize store (call once)
|
|
41
|
-
init() {
|
|
42
|
-
if (this.initialized) return;
|
|
43
|
-
this.initialized = true;
|
|
44
|
-
|
|
45
|
-
// Auto-reconnect on init
|
|
46
|
-
this.autoReconnect();
|
|
47
|
-
|
|
48
|
-
// Listen for account changes (EVM only)
|
|
49
|
-
onAccountsChanged((accounts) => {
|
|
50
|
-
const connectedType = getConnectedNetworkType();
|
|
51
|
-
if (connectedType === NetworkType.EVM) {
|
|
52
|
-
if (accounts.length === 0) {
|
|
53
|
-
this.setState({address: null});
|
|
54
|
-
console.log('🔌 Wallet disconnected');
|
|
55
|
-
} else {
|
|
56
|
-
if (!isWalletManuallyDisconnected()) {
|
|
57
|
-
this.setState({address: accounts[0]});
|
|
58
|
-
console.log('🔄 Account changed:', accounts[0]);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Listen for network/chain changes (EVM only)
|
|
65
|
-
onChainChanged(() => {
|
|
66
|
-
const connectedType = getConnectedNetworkType();
|
|
67
|
-
if (connectedType === NetworkType.EVM) {
|
|
68
|
-
console.log('⚠️ Network changed detected - disconnecting wallet');
|
|
69
|
-
disconnectWalletUtil();
|
|
70
|
-
this.setState({
|
|
71
|
-
address: null,
|
|
72
|
-
networkType: null,
|
|
73
|
-
error: 'Network changed. Please reconnect your wallet.',
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Listen for wallet disconnect (Solana only)
|
|
79
|
-
onWalletDisconnect(() => {
|
|
80
|
-
const connectedType = getConnectedNetworkType();
|
|
81
|
-
if (connectedType === NetworkType.SOLANA || connectedType === NetworkType.SVM) {
|
|
82
|
-
console.log('⚠️ Solana wallet disconnected');
|
|
83
|
-
disconnectWalletUtil();
|
|
84
|
-
this.setState({
|
|
85
|
-
address: null,
|
|
86
|
-
networkType: null,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private async autoReconnect() {
|
|
93
|
-
if (!isWalletManuallyDisconnected()) {
|
|
94
|
-
const connectedType = getConnectedNetworkType();
|
|
95
|
-
if (connectedType) {
|
|
96
|
-
const currentAddress = await getCurrentWallet(connectedType);
|
|
97
|
-
if (currentAddress) {
|
|
98
|
-
this.setState({
|
|
99
|
-
address: currentAddress,
|
|
100
|
-
networkType: connectedType,
|
|
101
|
-
});
|
|
102
|
-
console.log('🔄 Auto-reconnected wallet:', currentAddress);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Get current state
|
|
109
|
-
getState(): WalletState {
|
|
110
|
-
return this.state;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Update state and notify listeners
|
|
114
|
-
private setState(partial: Partial<WalletState>) {
|
|
115
|
-
this.state = {...this.state, ...partial};
|
|
116
|
-
this.notifyListeners();
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Subscribe to state changes
|
|
120
|
-
subscribe(listener: Listener): () => void {
|
|
121
|
-
this.listeners.add(listener);
|
|
122
|
-
return () => {
|
|
123
|
-
this.listeners.delete(listener);
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Notify all listeners
|
|
128
|
-
private notifyListeners() {
|
|
129
|
-
this.listeners.forEach(listener => listener());
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Connect wallet
|
|
133
|
-
async connect(type: NetworkType): Promise<void> {
|
|
134
|
-
this.setState({isConnecting: true, error: null});
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
const walletAddress = await connectWalletUtil(type);
|
|
138
|
-
|
|
139
|
-
console.log('✅ Wallet connected:', walletAddress, 'Network:', type);
|
|
140
|
-
|
|
141
|
-
this.setState({
|
|
142
|
-
address: walletAddress,
|
|
143
|
-
networkType: type,
|
|
144
|
-
isConnecting: false,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
console.log('📝 Store state updated');
|
|
148
|
-
} catch (err: any) {
|
|
149
|
-
this.setState({
|
|
150
|
-
error: err.message || 'Failed to connect wallet',
|
|
151
|
-
isConnecting: false,
|
|
152
|
-
});
|
|
153
|
-
throw err;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Disconnect wallet
|
|
158
|
-
disconnect(): void {
|
|
159
|
-
disconnectWalletUtil();
|
|
160
|
-
this.setState({
|
|
161
|
-
address: null,
|
|
162
|
-
networkType: null,
|
|
163
|
-
error: null,
|
|
164
|
-
});
|
|
165
|
-
console.log('🔌 Wallet disconnected from store');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Clear error
|
|
169
|
-
clearError(): void {
|
|
170
|
-
this.setState({error: null});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Singleton instance
|
|
175
|
-
export const walletStore = new WalletStore();
|
|
176
|
-
|
|
177
|
-
// Initialize on import (browser only)
|
|
178
|
-
if (typeof window !== 'undefined') {
|
|
179
|
-
walletStore.init();
|
|
180
|
-
}
|
|
181
|
-
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Inline styles for x402 React Components
|
|
3
|
-
*
|
|
4
|
-
* Modern, minimal, and flat design without gradients or fancy borders.
|
|
5
|
-
* All styles are defined as JavaScript objects to ensure they're always bundled
|
|
6
|
-
* with the components. This eliminates the need for users to import CSS files.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import {CSSProperties} from 'react';
|
|
10
|
-
|
|
11
|
-
// 检测是否支持暗色模式
|
|
12
|
-
export const isDarkMode = (): boolean => {
|
|
13
|
-
if (typeof window === 'undefined') return false;
|
|
14
|
-
return window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
// 现代简约配色 - 扁平化设计
|
|
18
|
-
const colors = {
|
|
19
|
-
// Light mode
|
|
20
|
-
light: {
|
|
21
|
-
background: '#fafafa',
|
|
22
|
-
cardBg: '#ffffff',
|
|
23
|
-
text: '#0a0a0a',
|
|
24
|
-
textSecondary: '#737373',
|
|
25
|
-
primary: '#000000',
|
|
26
|
-
primaryHover: '#262626',
|
|
27
|
-
danger: '#ef4444',
|
|
28
|
-
dangerHover: '#dc2626',
|
|
29
|
-
success: '#10b981',
|
|
30
|
-
successHover: '#059669',
|
|
31
|
-
disabled: '#e5e5e5',
|
|
32
|
-
disabledText: '#a3a3a3',
|
|
33
|
-
errorBg: '#fef2f2',
|
|
34
|
-
errorText: '#dc2626',
|
|
35
|
-
},
|
|
36
|
-
// Dark mode
|
|
37
|
-
dark: {
|
|
38
|
-
background: '#0a0a0a',
|
|
39
|
-
cardBg: '#171717',
|
|
40
|
-
text: '#fafafa',
|
|
41
|
-
textSecondary: '#a3a3a3',
|
|
42
|
-
primary: '#ffffff',
|
|
43
|
-
primaryHover: '#e5e5e5',
|
|
44
|
-
danger: '#f87171',
|
|
45
|
-
dangerHover: '#ef4444',
|
|
46
|
-
success: '#34d399',
|
|
47
|
-
successHover: '#10b981',
|
|
48
|
-
disabled: '#262626',
|
|
49
|
-
disabledText: '#525252',
|
|
50
|
-
errorBg: '#1c1917',
|
|
51
|
-
errorText: '#f87171',
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// 获取当前主题颜色
|
|
56
|
-
export const getColors = () => {
|
|
57
|
-
return isDarkMode() ? colors.dark : colors.light;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
// 容器样式
|
|
61
|
-
export const containerStyle: CSSProperties = {
|
|
62
|
-
width: '100%',
|
|
63
|
-
maxWidth: '420px',
|
|
64
|
-
margin: '0 auto',
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// 钱包区块样式 - 极简无边框
|
|
68
|
-
export const getSectionStyle = (): CSSProperties => {
|
|
69
|
-
const c = getColors();
|
|
70
|
-
return {
|
|
71
|
-
padding: '1.5rem',
|
|
72
|
-
background: c.cardBg,
|
|
73
|
-
borderRadius: '12px',
|
|
74
|
-
};
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// 标题样式 - 简洁
|
|
78
|
-
export const getTitleStyle = (): CSSProperties => {
|
|
79
|
-
const c = getColors();
|
|
80
|
-
return {
|
|
81
|
-
margin: '0 0 1.25rem 0',
|
|
82
|
-
fontSize: '1.125rem',
|
|
83
|
-
fontWeight: 600,
|
|
84
|
-
color: c.text,
|
|
85
|
-
letterSpacing: '-0.01em',
|
|
86
|
-
};
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
// 按钮容器样式
|
|
90
|
-
export const buttonsContainerStyle: CSSProperties = {
|
|
91
|
-
display: 'flex',
|
|
92
|
-
flexDirection: 'column',
|
|
93
|
-
gap: '0.75rem',
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// 钱包选项样式
|
|
97
|
-
export const walletOptionStyle: CSSProperties = {
|
|
98
|
-
display: 'flex',
|
|
99
|
-
flexDirection: 'column',
|
|
100
|
-
gap: '0.5rem',
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// 基础按钮样式 - 扁平化
|
|
104
|
-
const baseButtonStyle: CSSProperties = {
|
|
105
|
-
padding: '0.875rem 1.25rem',
|
|
106
|
-
fontSize: '0.9375rem',
|
|
107
|
-
fontWeight: 500,
|
|
108
|
-
border: 'none',
|
|
109
|
-
borderRadius: '8px',
|
|
110
|
-
cursor: 'pointer',
|
|
111
|
-
transition: 'background-color 0.15s ease, opacity 0.15s ease',
|
|
112
|
-
outline: 'none',
|
|
113
|
-
letterSpacing: '-0.01em',
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
// 连接按钮样式 - 纯黑/纯白
|
|
117
|
-
export const getConnectButtonStyle = (isDisabled: boolean, isHovered: boolean): CSSProperties => {
|
|
118
|
-
const c = getColors();
|
|
119
|
-
const darkMode = isDarkMode();
|
|
120
|
-
|
|
121
|
-
if (isDisabled) {
|
|
122
|
-
return {
|
|
123
|
-
...baseButtonStyle,
|
|
124
|
-
background: c.disabled,
|
|
125
|
-
color: c.disabledText,
|
|
126
|
-
cursor: 'not-allowed',
|
|
127
|
-
border: darkMode ? '1px solid #404040' : '1px solid #d4d4d4',
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
...baseButtonStyle,
|
|
133
|
-
background: isHovered ? c.primaryHover : c.primary,
|
|
134
|
-
color: darkMode ? '#000000' : '#ffffff',
|
|
135
|
-
cursor: 'pointer',
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// 断开连接按钮样式
|
|
140
|
-
export const getDisconnectButtonStyle = (isHovered: boolean): CSSProperties => {
|
|
141
|
-
const c = getColors();
|
|
142
|
-
return {
|
|
143
|
-
...baseButtonStyle,
|
|
144
|
-
background: isHovered ? c.dangerHover : c.danger,
|
|
145
|
-
color: '#ffffff',
|
|
146
|
-
};
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
// 支付按钮样式
|
|
150
|
-
export const getPayButtonStyle = (isDisabled: boolean, isHovered: boolean): CSSProperties => {
|
|
151
|
-
const c = getColors();
|
|
152
|
-
return {
|
|
153
|
-
...baseButtonStyle,
|
|
154
|
-
background: isDisabled ? c.disabled : (isHovered ? c.successHover : c.success),
|
|
155
|
-
color: '#ffffff',
|
|
156
|
-
width: '100%',
|
|
157
|
-
cursor: isDisabled ? 'not-allowed' : 'pointer',
|
|
158
|
-
opacity: isDisabled ? 0.5 : 1,
|
|
159
|
-
};
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// 安装链接样式 - 简洁
|
|
163
|
-
export const getInstallLinkStyle = (isHovered: boolean): CSSProperties => {
|
|
164
|
-
const c = getColors();
|
|
165
|
-
return {
|
|
166
|
-
display: 'inline-block',
|
|
167
|
-
padding: '0.5rem',
|
|
168
|
-
fontSize: '0.8125rem',
|
|
169
|
-
color: c.textSecondary,
|
|
170
|
-
textDecoration: isHovered ? 'underline' : 'none',
|
|
171
|
-
textAlign: 'center',
|
|
172
|
-
fontWeight: 500,
|
|
173
|
-
};
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
// 钱包地址容器样式
|
|
177
|
-
export const walletAddressStyle: CSSProperties = {
|
|
178
|
-
display: 'flex',
|
|
179
|
-
flexDirection: 'column',
|
|
180
|
-
gap: '0.5rem',
|
|
181
|
-
marginBottom: '1rem',
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
// 钱包标签样式
|
|
185
|
-
export const getLabelStyle = (): CSSProperties => {
|
|
186
|
-
const c = getColors();
|
|
187
|
-
return {
|
|
188
|
-
fontSize: '0.8125rem',
|
|
189
|
-
color: c.textSecondary,
|
|
190
|
-
fontWeight: 500,
|
|
191
|
-
textTransform: 'uppercase',
|
|
192
|
-
letterSpacing: '0.05em',
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// 地址样式
|
|
197
|
-
export const getAddressStyle = (): CSSProperties => {
|
|
198
|
-
const c = getColors();
|
|
199
|
-
return {
|
|
200
|
-
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
201
|
-
fontSize: '0.9375rem',
|
|
202
|
-
fontWeight: 500,
|
|
203
|
-
color: c.text,
|
|
204
|
-
letterSpacing: '-0.01em',
|
|
205
|
-
};
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
// 钱包操作区域样式
|
|
209
|
-
export const walletActionsStyle: CSSProperties = {
|
|
210
|
-
margin: '1rem 0',
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
// 提示文字样式
|
|
214
|
-
export const getHintStyle = (): CSSProperties => {
|
|
215
|
-
const c = getColors();
|
|
216
|
-
return {
|
|
217
|
-
marginTop: '1rem',
|
|
218
|
-
fontSize: '0.8125rem',
|
|
219
|
-
color: c.textSecondary,
|
|
220
|
-
textAlign: 'center',
|
|
221
|
-
lineHeight: '1.5',
|
|
222
|
-
};
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
// 错误信息样式 - 扁平化
|
|
226
|
-
export const getErrorStyle = (): CSSProperties => {
|
|
227
|
-
const c = getColors();
|
|
228
|
-
return {
|
|
229
|
-
marginTop: '1rem',
|
|
230
|
-
padding: '0.75rem 1rem',
|
|
231
|
-
background: c.errorBg,
|
|
232
|
-
color: c.errorText,
|
|
233
|
-
borderRadius: '8px',
|
|
234
|
-
fontSize: '0.8125rem',
|
|
235
|
-
fontWeight: 500,
|
|
236
|
-
};
|
|
237
|
-
};
|
|
238
|
-
|