forked from Nova-reward/Nova-Rewards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWalletConnect.js
More file actions
105 lines (95 loc) · 3.75 KB
/
Copy pathWalletConnect.js
File metadata and controls
105 lines (95 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
'use client';
import { useState } from 'react';
import { useWallet } from '../context/WalletContext';
import { truncateAddress } from '../lib/truncateAddress';
import { formatTokenAmount } from '../lib/formatting';
const WALLETS = [
{ id: 'freighter', label: 'Freighter', icon: '🔑', description: 'Browser extension' },
{ id: 'albedo', label: 'Albedo', icon: '🌐', description: 'Web-based wallet' },
{ id: 'xbull', label: 'xBull', icon: '🐂', description: 'Browser extension' },
];
/**
* Multi-wallet connect button supporting Freighter, Albedo, and xBull.
* Shows connected address + balance when connected.
*/
export default function WalletConnect() {
const { publicKey, balance, connect, disconnect, loading, error, hydrated } = useWallet();
const [showPicker, setShowPicker] = useState(false);
const [connectError, setConnectError] = useState('');
const handleConnect = async (walletId) => {
setConnectError('');
setShowPicker(false);
try {
await connect(walletId);
} catch (err) {
setConnectError(err.message || 'Failed to connect wallet.');
}
};
const handleDisconnect = () => {
disconnect();
setConnectError('');
};
if (!hydrated) return null;
if (publicKey) {
return (
<div className="card" style={{ display: 'flex', alignItems: 'center', gap: '1rem', flexWrap: 'wrap' }}>
<div style={{ flex: 1 }}>
<p style={{ color: 'var(--muted)', fontSize: '0.8rem' }}>Connected Wallet</p>
<p style={{ fontFamily: 'monospace', fontWeight: 600 }}>{truncateAddress(publicKey)}</p>
<p style={{ color: 'var(--accent)', fontWeight: 700 }}>{formatTokenAmount(balance)} NOVA</p>
</div>
<button className="btn btn-secondary" onClick={handleDisconnect}>Disconnect</button>
</div>
);
}
return (
<div style={{ position: 'relative' }}>
<button
className="btn btn-primary"
onClick={() => setShowPicker((v) => !v)}
disabled={loading}
>
{loading ? (
<span className="btn-loading"><span className="spinner"></span>Connecting…</span>
) : '🔗 Connect Wallet'}
</button>
{showPicker && (
<div style={{
position: 'absolute', top: 'calc(100% + 8px)', left: 0, zIndex: 100,
background: 'var(--surface)', border: '1px solid var(--border)',
borderRadius: '12px', padding: '0.75rem', minWidth: '220px',
boxShadow: '0 8px 24px rgba(0,0,0,0.15)',
}}>
<p style={{ color: 'var(--muted)', fontSize: '0.8rem', marginBottom: '0.5rem', padding: '0 0.25rem' }}>
Choose a wallet
</p>
{WALLETS.map((w) => (
<button
key={w.id}
onClick={() => handleConnect(w.id)}
style={{
display: 'flex', alignItems: 'center', gap: '0.75rem',
width: '100%', padding: '0.6rem 0.75rem', background: 'none',
border: 'none', borderRadius: '8px', cursor: 'pointer',
color: 'var(--text)', textAlign: 'left',
}}
onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'}
onMouseLeave={(e) => e.currentTarget.style.background = 'none'}
>
<span style={{ fontSize: '1.4rem' }}>{w.icon}</span>
<div>
<p style={{ fontWeight: 600, fontSize: '0.9rem' }}>{w.label}</p>
<p style={{ color: 'var(--muted)', fontSize: '0.75rem' }}>{w.description}</p>
</div>
</button>
))}
</div>
)}
{(connectError || error) && (
<p className="error" style={{ marginTop: '0.5rem', fontSize: '0.85rem' }}>
{connectError || error}
</p>
)}
</div>
);
}